<commit_before>package sema

import (
	"fmt"
	"sync/atomic"
	"time"
)

var (
	errCap = fmt.Errorf("sema: capacity must be at least 1")
)

// Sema provides a simple semaphore implementation using a channel
type Sema struct {
	sm      chan struct{}
	holders *int64
}

// New creates a new semaphore with the given maximum capacity for concurrent access.
// Will panic if cap < 1
func New(cap int) (*Sema, error) {
	if cap < 1 {
		return nil, errCap
	}

	h := int64(0)
	return &Sema{
		sm:      make(chan struct{}, cap),
		holders: &h,
	}, nil
}

// Acquire the semaphore, will block if semaphore is full
// until any other holder release it.
// Will panic if semaphore is nil
func (s *Sema) Acquire() {
	s.checkNil()
	s.sm <- struct{}{}
	atomic.AddInt64(s.holders, 1)
}

// Release the semaphore
// Will panic if called on a non acquired semaphore
func (s *Sema) Release() {
	s.checkNil()
	if atomic.AddInt64(s.holders, -1) < 0 {
		panic("sema: calling release on a empty semaphore")
	}
	<-s.sm
}

// TryAcquire the semaphore without blocking return true on success and false on failure.
// Will panic if semaphore is nil
func (s *Sema) TryAcquire() bool {
	s.checkNil()
	select {
	case s.sm <- struct{}{}:
		atomic.AddInt64(s.holders, 1)
		return true
	default:
		return false
	}
}

// AcquireWithin the given timeout return true on success and false on failure
// Will panic if semaphore is nil
func (s *Sema) AcquireWithin(timeout time.Duration) bool {
	s.checkNil()
	select {
	case s.sm <- struct{}{}:
		atomic.AddInt64(s.holders, 1)
		return true
	case <-time.After(timeout):
		return false
	}
}

// Holders return the current holders count
// Will panic if semaphore is nil
func (s *Sema) Holders() int {
	s.checkNil()
	return int(atomic.LoadInt64(s.holders))
}

// Cap return semaphore capacity
// Will panic if semaphore is nil
func (s *Sema) Cap() int {
	s.checkNil()
	return cap(s.sm)
}

func (s *Sema) checkNil() {
	if s.sm == nil {
		panic("sema: calling on a nil semaphore")
	}
}<commit_msg>drop the unnecessary struct and counter<commit_after>package sema

import (
	"fmt"
	"time"
)

var (
	errCap = fmt.Errorf("sema: capacity must be at least 1")
)

// Sema provides a simple semaphore implementation using a channel
type Sema chan struct{}

// New creates a new semaphore with the given maximum capacity for concurrent access.
// Will panic if cap < 1
func New(cap int) (Sema, error) {
	if cap < 1 {
		return nil, errCap
	}
	return make(Sema, cap), nil
}

// Acquire the semaphore, will block if semaphore is full
// until any other holder release it.
// Will panic if semaphore is nil
func (s Sema) Acquire() {
	s.checkNil()
	s <- struct{}{}
}

// Release the semaphore
// Will panic if called on a non acquired semaphore
func (s Sema) Release() {
	s.checkNil()
	if len(s) < 1 {
		panic("sema: calling release on a empty semaphore")
	}
	<-s
}

// TryAcquire the semaphore without blocking return true on success and false on failure.
// Will panic if semaphore is nil
func (s Sema) TryAcquire() bool {
	s.checkNil()
	select {
	case s <- struct{}{}:
		return true
	default:
		return false
	}
}

// AcquireWithin the given timeout return true on success and false on failure
// Will panic if semaphore is nil
func (s Sema) AcquireWithin(timeout time.Duration) bool {
	s.checkNil()
	select {
	case s <- struct{}{}:
		return true
	case <-time.After(timeout):
		return false
	}
}

// Holders return the current holders count
// Will panic if semaphore is nil
func (s Sema) Holders() int {
	s.checkNil()
	return len(s)
}

// Cap return semaphore capacity
// Will panic if semaphore is nil
func (s Sema) Cap() int {
	s.checkNil()
	return cap(s)
}

func (s Sema) checkNil() {
	if s == nil {
		panic("sema: calling on a nil semaphore")
	}
}
{'fraction_non_alphanumeric': 0.11612386545648692, 'fraction_numerical': 0.007207688200747464, 'mean_word_length': 3.3875878220140514, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '149149', 'n_tokens_mistral': 1354, 'n_tokens_neox': 1295, 'n_words': 496}