mirror of https://github.com/prometheus/prometheus
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
43 lines
1.6 KiB
43 lines
1.6 KiB
package local |
|
|
|
import ( |
|
"sync" |
|
|
|
clientmodel "github.com/prometheus/client_golang/model" |
|
) |
|
|
|
// fingerprintLocker allows locking individual fingerprints. To limit the number |
|
// of mutexes needed for that, only a fixed number of mutexes are |
|
// allocated. Fingerprints to be locked are assigned to those pre-allocated |
|
// mutexes by their value. (Note that fingerprints are calculated by a hash |
|
// function, so that an approximately equal distribution over the mutexes is |
|
// expected, even without additional hashing of the fingerprint value.) |
|
// Collisions are not detected. If two fingerprints get assigned to the same |
|
// mutex, only one of them can be locked at the same time. As long as the number |
|
// of pre-allocated mutexes is much larger than the number of goroutines |
|
// requiring a fingerprint lock concurrently, the loss in efficiency is |
|
// small. However, a goroutine must never lock more than one fingerprint at the |
|
// same time. (In that case a collision would try to acquire the same mutex |
|
// twice). |
|
type fingerprintLocker struct { |
|
fpMtxs []sync.Mutex |
|
numFpMtxs uint |
|
} |
|
|
|
// newFingerprintLocker returns a new fingerprintLocker ready for use. |
|
func newFingerprintLocker(preallocatedMutexes int) *fingerprintLocker { |
|
return &fingerprintLocker{ |
|
make([]sync.Mutex, preallocatedMutexes), |
|
uint(preallocatedMutexes), |
|
} |
|
} |
|
|
|
// Lock locks the given fingerprint. |
|
func (l *fingerprintLocker) Lock(fp clientmodel.Fingerprint) { |
|
l.fpMtxs[uint(fp)%l.numFpMtxs].Lock() |
|
} |
|
|
|
// Unlock unlocks the given fingerprint. |
|
func (l *fingerprintLocker) Unlock(fp clientmodel.Fingerprint) { |
|
l.fpMtxs[uint(fp)%l.numFpMtxs].Unlock() |
|
}
|
|
|