Update GRPC

This commit is contained in:
cici37
2022-05-04 18:41:20 -07:00
parent e8f6184d86
commit 334d8fb7a2
108 changed files with 2308 additions and 1010 deletions

View File

@@ -0,0 +1,237 @@
package antlr
import "math"
const (
_initalCapacity = 16
_initalBucketCapacity = 8
_loadFactor = 0.75
)
var _ Set = (*Array2DHashSet)(nil)
type Set interface {
Add(value interface{}) (added interface{})
Len() int
Get(value interface{}) (found interface{})
Contains(value interface{}) bool
Values() []interface{}
Each(f func(interface{}) bool)
}
type Array2DHashSet struct {
buckets [][]interface{}
hashcodeFunction func(interface{}) int
equalsFunction func(interface{}, interface{}) bool
n int // How many elements in set
threshold int // when to expand
currentPrime int // jump by 4 primes each expand or whatever
initialBucketCapacity int
}
func (as *Array2DHashSet) Each(f func(interface{}) bool) {
if as.Len() < 1 {
return
}
for _, bucket := range as.buckets {
for _, o := range bucket {
if o == nil {
break
}
if !f(o) {
return
}
}
}
}
func (as *Array2DHashSet) Values() []interface{} {
if as.Len() < 1 {
return nil
}
values := make([]interface{}, 0, as.Len())
as.Each(func(i interface{}) bool {
values = append(values, i)
return true
})
return values
}
func (as *Array2DHashSet) Contains(value interface{}) bool {
return as.Get(value) != nil
}
func (as *Array2DHashSet) Add(value interface{}) interface{} {
if as.n > as.threshold {
as.expand()
}
return as.innerAdd(value)
}
func (as *Array2DHashSet) expand() {
old := as.buckets
as.currentPrime += 4
var (
newCapacity = len(as.buckets) << 1
newTable = as.createBuckets(newCapacity)
newBucketLengths = make([]int, len(newTable))
)
as.buckets = newTable
as.threshold = int(float64(newCapacity) * _loadFactor)
for _, bucket := range old {
if bucket == nil {
continue
}
for _, o := range bucket {
if o == nil {
break
}
b := as.getBuckets(o)
bucketLength := newBucketLengths[b]
var newBucket []interface{}
if bucketLength == 0 {
// new bucket
newBucket = as.createBucket(as.initialBucketCapacity)
newTable[b] = newBucket
} else {
newBucket = newTable[b]
if bucketLength == len(newBucket) {
// expand
newBucketCopy := make([]interface{}, len(newBucket)<<1)
copy(newBucketCopy[:bucketLength], newBucket)
newBucket = newBucketCopy
newTable[b] = newBucket
}
}
newBucket[bucketLength] = o
newBucketLengths[b]++
}
}
}
func (as *Array2DHashSet) Len() int {
return as.n
}
func (as *Array2DHashSet) Get(o interface{}) interface{} {
if o == nil {
return nil
}
b := as.getBuckets(o)
bucket := as.buckets[b]
if bucket == nil { // no bucket
return nil
}
for _, e := range bucket {
if e == nil {
return nil // empty slot; not there
}
if as.equalsFunction(e, o) {
return e
}
}
return nil
}
func (as *Array2DHashSet) innerAdd(o interface{}) interface{} {
b := as.getBuckets(o)
bucket := as.buckets[b]
// new bucket
if bucket == nil {
bucket = as.createBucket(as.initialBucketCapacity)
bucket[0] = o
as.buckets[b] = bucket
as.n++
return o
}
// look for it in bucket
for i := 0; i < len(bucket); i++ {
existing := bucket[i]
if existing == nil { // empty slot; not there, add.
bucket[i] = o
as.n++
return o
}
if as.equalsFunction(existing, o) { // found existing, quit
return existing
}
}
// full bucket, expand and add to end
oldLength := len(bucket)
bucketCopy := make([]interface{}, oldLength<<1)
copy(bucketCopy[:oldLength], bucket)
bucket = bucketCopy
as.buckets[b] = bucket
bucket[oldLength] = o
as.n++
return o
}
func (as *Array2DHashSet) getBuckets(value interface{}) int {
hash := as.hashcodeFunction(value)
return hash & (len(as.buckets) - 1)
}
func (as *Array2DHashSet) createBuckets(cap int) [][]interface{} {
return make([][]interface{}, cap)
}
func (as *Array2DHashSet) createBucket(cap int) []interface{} {
return make([]interface{}, cap)
}
func NewArray2DHashSetWithCap(
hashcodeFunction func(interface{}) int,
equalsFunction func(interface{}, interface{}) bool,
initCap int,
initBucketCap int,
) *Array2DHashSet {
if hashcodeFunction == nil {
hashcodeFunction = standardHashFunction
}
if equalsFunction == nil {
equalsFunction = standardEqualsFunction
}
ret := &Array2DHashSet{
hashcodeFunction: hashcodeFunction,
equalsFunction: equalsFunction,
n: 0,
threshold: int(math.Floor(_initalCapacity * _loadFactor)),
currentPrime: 1,
initialBucketCapacity: initBucketCap,
}
ret.buckets = ret.createBuckets(initCap)
return ret
}
func NewArray2DHashSet(
hashcodeFunction func(interface{}) int,
equalsFunction func(interface{}, interface{}) bool,
) *Array2DHashSet {
return NewArray2DHashSetWithCap(hashcodeFunction, equalsFunction, _initalCapacity, _initalBucketCapacity)
}