Source File
sketch.go
Belonging Package
github.com/dgraph-io/ristretto/v2
/** SPDX-FileCopyrightText: © Hypermode Inc. <hello@hypermode.com>* SPDX-License-Identifier: Apache-2.0*/package ristrettoimport ()// cmSketch is a Count-Min sketch implementation with 4-bit counters, heavily// based on Damian Gryski's CM4 [1].//// [1]: https://github.com/dgryski/go-tinylfu/blob/master/cm4.gotype cmSketch struct {rows [cmDepth]cmRowseed [cmDepth]uint64mask uint64}const (// cmDepth is the number of counter copies to store (think of it as rows).cmDepth = 4)func newCmSketch( int64) *cmSketch {if == 0 {panic("cmSketch: bad numCounters")}// Get the next power of 2 for better cache performance.= next2Power():= &cmSketch{mask: uint64( - 1)}// Initialize rows of counters and seeds.// Cryptographic precision not needed:= rand.New(rand.NewSource(time.Now().UnixNano())) //nolint:gosecfor := 0; < cmDepth; ++ {.seed[] = .Uint64().rows[] = newCmRow()}return}// Increment increments the count(ers) for the specified key.func ( *cmSketch) ( uint64) {for := range .rows {.rows[].increment(( ^ .seed[]) & .mask)}}// Estimate returns the value of the specified key.func ( *cmSketch) ( uint64) int64 {:= byte(255)for := range .rows {:= .rows[].get(( ^ .seed[]) & .mask)if < {=}}return int64()}// Reset halves all counter values.func ( *cmSketch) () {for , := range .rows {.reset()}}// Clear zeroes all counters.func ( *cmSketch) () {for , := range .rows {.clear()}}// cmRow is a row of bytes, with each byte holding two counters.type cmRow []bytefunc newCmRow( int64) cmRow {return make(cmRow, /2)}func ( cmRow) ( uint64) byte {return ([/2] >> (( & 1) * 4)) & 0x0f}func ( cmRow) ( uint64) {// Index of the counter.:= / 2// Shift distance (even 0, odd 4).:= ( & 1) * 4// Counter value.:= ([] >> ) & 0x0f// Only increment if not max value (overflow wrap is bad for LFU).if < 15 {[] += 1 <<}}func ( cmRow) () {// Halve each counter.for := range {[] = ([] >> 1) & 0x77}}func ( cmRow) () {// Zero each counter.for := range {[] = 0}}func ( cmRow) () string {:= ""for := uint64(0); < uint64(len()*2); ++ {+= fmt.Sprintf("%02d ", ([(/2)]>>((&1)*4))&0x0f)}= [:len()-1]return}// next2Power rounds x up to the next power of 2, if it's not already one.func next2Power( int64) int64 {--|= >> 1|= >> 2|= >> 4|= >> 8|= >> 16|= >> 32++return}
![]() |
The pages are generated with Golds v0.8.4. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |