diff --git a/actor/Actor.go b/actor/Actor.go index 236dc542..fa10f944 100644 --- a/actor/Actor.go +++ b/actor/Actor.go @@ -43,7 +43,7 @@ type ( id int64 state int32 trace traceInfo //trace func - mailBox *mpsc.Queue + mailBox *mpsc.Queue[*CallIO] mailIn [8]int64 mailChan chan bool timerId *int64 @@ -148,8 +148,8 @@ func (a *Actor) Acotr() *Actor { } func (a *Actor) Init() { - a.mailChan = make(chan bool, 1) - a.mailBox = mpsc.New() + a.mailChan = make(chan bool) + a.mailBox = mpsc.New[*CallIO]() a.acotrChan = make(chan int, 1) a.timerMap = make(map[uintptr]func()) //trance @@ -214,7 +214,7 @@ func (a *Actor) Send(head rpc.RpcHead, packet rpc.Packet) { io.RpcHead = head io.RpcPacket = packet.RpcPacket io.Buff = packet.Buff - a.mailBox.Push(io) + a.mailBox.Push(&io) if atomic.LoadInt64(&a.mailIn[0]) == 0 && atomic.CompareAndSwapInt64(&a.mailIn[0], 0, 1) { a.mailChan <- true } @@ -224,7 +224,7 @@ func (a *Actor) Trace(funcName string) { a.trace.funcName = funcName } -func (a *Actor) call(io CallIO) { +func (a *Actor) call(io *CallIO) { rpcPacket := io.RpcPacket head := io.RpcHead funcName := rpcPacket.FuncName @@ -270,7 +270,7 @@ func (a *Actor) UpdateTimer(ctx context.Context, ptr uintptr) { func (a *Actor) consume() { atomic.StoreInt64(&a.mailIn[0], 0) for data := a.mailBox.Pop(); data != nil; data = a.mailBox.Pop() { - a.call(data.(CallIO)) + a.call(data) } } diff --git a/base/common.go b/base/common.go index 026a3091..f5e3249a 100644 --- a/base/common.go +++ b/base/common.go @@ -287,7 +287,7 @@ func ToString(value interface{}) string { } //---------遍历子目录------------// -func WalkDir(dirpath string, filesVec *vector.Vector) { +func WalkDir(dirpath string, filesVec *vector.Vector[os.FileInfo]) { files, err := ioutil.ReadDir(dirpath) //读取目录下文件 if err != nil { return diff --git a/base/containers/comparator.go b/base/containers/comparator.go deleted file mode 100644 index 2da8fb00..00000000 --- a/base/containers/comparator.go +++ /dev/null @@ -1,247 +0,0 @@ -package containers - -import "time" - -// Comparator will make type assertion (see IntComparator for example), -// which will panic if a or b are not of the asserted type. -// -// Should return a number: -// negative , if a < b -// zero , if a == b -// positive , if a > b -type Comparator func(a, b interface{}) int - -// StringComparator provides a fast comparison on strings -func StringComparator(a, b interface{}) int { - s1 := a.(string) - s2 := b.(string) - min := len(s2) - if len(s1) < len(s2) { - min = len(s1) - } - diff := 0 - for i := 0; i < min && diff == 0; i++ { - diff = int(s1[i]) - int(s2[i]) - } - if diff == 0 { - diff = len(s1) - len(s2) - } - if diff < 0 { - return -1 - } - if diff > 0 { - return 1 - } - return 0 -} - -// IntComparator provides a basic comparison on int -func IntComparator(a, b interface{}) int { - aAsserted := a.(int) - bAsserted := b.(int) - switch { - case aAsserted > bAsserted: - return 1 - case aAsserted < bAsserted: - return -1 - default: - return 0 - } -} - -// Int8Comparator provides a basic comparison on int8 -func Int8Comparator(a, b interface{}) int { - aAsserted := a.(int8) - bAsserted := b.(int8) - switch { - case aAsserted > bAsserted: - return 1 - case aAsserted < bAsserted: - return -1 - default: - return 0 - } -} - -// Int16Comparator provides a basic comparison on int16 -func Int16Comparator(a, b interface{}) int { - aAsserted := a.(int16) - bAsserted := b.(int16) - switch { - case aAsserted > bAsserted: - return 1 - case aAsserted < bAsserted: - return -1 - default: - return 0 - } -} - -// Int32Comparator provides a basic comparison on int32 -func Int32Comparator(a, b interface{}) int { - aAsserted := a.(int32) - bAsserted := b.(int32) - switch { - case aAsserted > bAsserted: - return 1 - case aAsserted < bAsserted: - return -1 - default: - return 0 - } -} - -// Int64Comparator provides a basic comparison on int64 -func Int64Comparator(a, b interface{}) int { - aAsserted := a.(int64) - bAsserted := b.(int64) - switch { - case aAsserted > bAsserted: - return 1 - case aAsserted < bAsserted: - return -1 - default: - return 0 - } -} - -// UIntComparator provides a basic comparison on uint -func UIntComparator(a, b interface{}) int { - aAsserted := a.(uint) - bAsserted := b.(uint) - switch { - case aAsserted > bAsserted: - return 1 - case aAsserted < bAsserted: - return -1 - default: - return 0 - } -} - -// UInt8Comparator provides a basic comparison on uint8 -func UInt8Comparator(a, b interface{}) int { - aAsserted := a.(uint8) - bAsserted := b.(uint8) - switch { - case aAsserted > bAsserted: - return 1 - case aAsserted < bAsserted: - return -1 - default: - return 0 - } -} - -// UInt16Comparator provides a basic comparison on uint16 -func UInt16Comparator(a, b interface{}) int { - aAsserted := a.(uint16) - bAsserted := b.(uint16) - switch { - case aAsserted > bAsserted: - return 1 - case aAsserted < bAsserted: - return -1 - default: - return 0 - } -} - -// UInt32Comparator provides a basic comparison on uint32 -func UInt32Comparator(a, b interface{}) int { - aAsserted := a.(uint32) - bAsserted := b.(uint32) - switch { - case aAsserted > bAsserted: - return 1 - case aAsserted < bAsserted: - return -1 - default: - return 0 - } -} - -// UInt64Comparator provides a basic comparison on uint64 -func UInt64Comparator(a, b interface{}) int { - aAsserted := a.(uint64) - bAsserted := b.(uint64) - switch { - case aAsserted > bAsserted: - return 1 - case aAsserted < bAsserted: - return -1 - default: - return 0 - } -} - -// Float32Comparator provides a basic comparison on float32 -func Float32Comparator(a, b interface{}) int { - aAsserted := a.(float32) - bAsserted := b.(float32) - switch { - case aAsserted > bAsserted: - return 1 - case aAsserted < bAsserted: - return -1 - default: - return 0 - } -} - -// Float64Comparator provides a basic comparison on float64 -func Float64Comparator(a, b interface{}) int { - aAsserted := a.(float64) - bAsserted := b.(float64) - switch { - case aAsserted > bAsserted: - return 1 - case aAsserted < bAsserted: - return -1 - default: - return 0 - } -} - -// ByteComparator provides a basic comparison on byte -func ByteComparator(a, b interface{}) int { - aAsserted := a.(byte) - bAsserted := b.(byte) - switch { - case aAsserted > bAsserted: - return 1 - case aAsserted < bAsserted: - return -1 - default: - return 0 - } -} - -// RuneComparator provides a basic comparison on rune -func RuneComparator(a, b interface{}) int { - aAsserted := a.(rune) - bAsserted := b.(rune) - switch { - case aAsserted > bAsserted: - return 1 - case aAsserted < bAsserted: - return -1 - default: - return 0 - } -} - -// TimeComparator provides a basic comparison on time.Time -func TimeComparator(a, b interface{}) int { - aAsserted := a.(time.Time) - bAsserted := b.(time.Time) - - switch { - case aAsserted.After(bAsserted): - return 1 - case aAsserted.Before(bAsserted): - return -1 - default: - return 0 - } -} diff --git a/base/containers/comparator_test.go b/base/containers/comparator_test.go deleted file mode 100644 index 70795342..00000000 --- a/base/containers/comparator_test.go +++ /dev/null @@ -1,109 +0,0 @@ -package containers_test - -import ( - "gonet/base/containers" - "testing" - "time" -) - -func TestIntComparator(t *testing.T) { - - // i1,i2,expected - tests := [][]interface{}{ - {1, 1, 0}, - {1, 2, -1}, - {2, 1, 1}, - {11, 22, -1}, - {0, 0, 0}, - {1, 0, 1}, - {0, 1, -1}, - } - - for _, test := range tests { - actual := containers.IntComparator(test[0], test[1]) - expected := test[2] - if actual != expected { - t.Errorf("Got %v expected %v", actual, expected) - } - } -} - -func TestStringComparator(t *testing.T) { - - // s1,s2,expected - tests := [][]interface{}{ - {"a", "a", 0}, - {"a", "b", -1}, - {"b", "a", 1}, - {"aa", "aab", -1}, - {"", "", 0}, - {"a", "", 1}, - {"", "a", -1}, - {"", "aaaaaaa", -1}, - } - - for _, test := range tests { - actual := containers.StringComparator(test[0], test[1]) - expected := test[2] - if actual != expected { - t.Errorf("Got %v expected %v", actual, expected) - } - } -} - -func TestTimeComparator(t *testing.T) { - - now := time.Now() - - // i1,i2,expected - tests := [][]interface{}{ - {now, now, 0}, - {now.Add(24 * 7 * 2 * time.Hour), now, 1}, - {now, now.Add(24 * 7 * 2 * time.Hour), -1}, - } - - for _, test := range tests { - actual := containers.TimeComparator(test[0], test[1]) - expected := test[2] - if actual != expected { - t.Errorf("Got %v expected %v", actual, expected) - } - } -} - -func TestCustomComparator(t *testing.T) { - - type Custom struct { - id int - name string - } - - byID := func(a, b interface{}) int { - c1 := a.(Custom) - c2 := b.(Custom) - switch { - case c1.id > c2.id: - return 1 - case c1.id < c2.id: - return -1 - default: - return 0 - } - } - - // o1,o2,expected - tests := [][]interface{}{ - {Custom{1, "a"}, Custom{1, "a"}, 0}, - {Custom{1, "a"}, Custom{2, "b"}, -1}, - {Custom{2, "b"}, Custom{1, "a"}, 1}, - {Custom{1, "a"}, Custom{1, "b"}, 0}, - } - - for _, test := range tests { - actual := byID(test[0], test[1]) - expected := test[2] - if actual != expected { - t.Errorf("Got %v expected %v", actual, expected) - } - } -} diff --git a/base/containers/containers.go b/base/containers/containers.go deleted file mode 100644 index cd492ac8..00000000 --- a/base/containers/containers.go +++ /dev/null @@ -1,20 +0,0 @@ -package containers - -// Container is base interface that all data structures implement. -type Container interface { - Empty() bool - Size() int - Clear() - Values() []interface{} -} - -// GetSortedValues returns sorted container's elements with respect to the passed comparator. -// Does not effect the ordering of elements within the container. -func GetSortedValues(container Container, comparator Comparator) []interface{} { - values := container.Values() - if len(values) < 2 { - return values - } - Sort(values, comparator) - return values -} diff --git a/base/containers/iterator.go b/base/containers/iterator.go deleted file mode 100644 index 2a95893f..00000000 --- a/base/containers/iterator.go +++ /dev/null @@ -1,105 +0,0 @@ -package containers - -// IteratorWithIndex is stateful iterator for ordered containers whose values can be fetched by an index. -type IteratorWithIndex interface { - // Next moves the iterator to the next element and returns true if there was a next element in the container. - // If Next() returns true, then next element's index and value can be retrieved by Index() and Value(). - // If Next() was called for the first time, then it will point the iterator to the first element if it exists. - // Modifies the state of the iterator. - Next() bool - - // Value returns the current element's value. - // Does not modify the state of the iterator. - Value() interface{} - - // Index returns the current element's index. - // Does not modify the state of the iterator. - Index() int - - // Begin resets the iterator to its initial state (one-before-first) - // Call Next() to fetch the first element if any. - Begin() - - // First moves the iterator to the first element and returns true if there was a first element in the container. - // If First() returns true, then first element's index and value can be retrieved by Index() and Value(). - // Modifies the state of the iterator. - First() bool -} - -// IteratorWithKey is a stateful iterator for ordered containers whose elements are key value pairs. -type IteratorWithKey interface { - // Next moves the iterator to the next element and returns true if there was a next element in the container. - // If Next() returns true, then next element's key and value can be retrieved by Key() and Value(). - // If Next() was called for the first time, then it will point the iterator to the first element if it exists. - // Modifies the state of the iterator. - Next() bool - - // Value returns the current element's value. - // Does not modify the state of the iterator. - Value() interface{} - - // Key returns the current element's key. - // Does not modify the state of the iterator. - Key() interface{} - - // Begin resets the iterator to its initial state (one-before-first) - // Call Next() to fetch the first element if any. - Begin() - - // First moves the iterator to the first element and returns true if there was a first element in the container. - // If First() returns true, then first element's key and value can be retrieved by Key() and Value(). - // Modifies the state of the iterator. - First() bool -} - -// ReverseIteratorWithIndex is stateful iterator for ordered containers whose values can be fetched by an index. -// -// Essentially it is the same as IteratorWithIndex, but provides additional: -// -// Prev() function to enable traversal in reverse -// -// Last() function to move the iterator to the last element. -// -// End() function to move the iterator past the last element (one-past-the-end). -type ReverseIteratorWithIndex interface { - // Prev moves the iterator to the previous element and returns true if there was a previous element in the container. - // If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value(). - // Modifies the state of the iterator. - Prev() bool - - // End moves the iterator past the last element (one-past-the-end). - // Call Prev() to fetch the last element if any. - End() - - // Last moves the iterator to the last element and returns true if there was a last element in the container. - // If Last() returns true, then last element's index and value can be retrieved by Index() and Value(). - // Modifies the state of the iterator. - Last() bool - - IteratorWithIndex -} - -// ReverseIteratorWithKey is a stateful iterator for ordered containers whose elements are key value pairs. -// -// Essentially it is the same as IteratorWithKey, but provides additional: -// -// Prev() function to enable traversal in reverse -// -// Last() function to move the iterator to the last element. -type ReverseIteratorWithKey interface { - // Prev moves the iterator to the previous element and returns true if there was a previous element in the container. - // If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value(). - // Modifies the state of the iterator. - Prev() bool - - // End moves the iterator past the last element (one-past-the-end). - // Call Prev() to fetch the last element if any. - End() - - // Last moves the iterator to the last element and returns true if there was a last element in the container. - // If Last() returns true, then last element's key and value can be retrieved by Key() and Value(). - // Modifies the state of the iterator. - Last() bool - - IteratorWithKey -} diff --git a/base/containers/sort.go b/base/containers/sort.go deleted file mode 100644 index 86293a98..00000000 --- a/base/containers/sort.go +++ /dev/null @@ -1,24 +0,0 @@ -package containers - -import "sort" -// Sort sorts values (in-place) with respect to the given comparator. -// -// Uses Go's sort (hybrid of quicksort for large and then insertion sort for smaller slices). -func Sort(values []interface{}, comparator Comparator) { - sort.Sort(sortable{values, comparator}) -} - -type sortable struct { - values []interface{} - comparator Comparator -} - -func (s sortable) Len() int { - return len(s.values) -} -func (s sortable) Swap(i, j int) { - s.values[i], s.values[j] = s.values[j], s.values[i] -} -func (s sortable) Less(i, j int) bool { - return s.comparator(s.values[i], s.values[j]) < 0 -} diff --git a/base/containers/sort_test.go b/base/containers/sort_test.go deleted file mode 100644 index ca1eb058..00000000 --- a/base/containers/sort_test.go +++ /dev/null @@ -1,101 +0,0 @@ -package containers_test - -import ( - "gonet/base/containers" - "math/rand" - "testing" -) - -func TestSortInts(t *testing.T) { - ints := []interface{}{} - ints = append(ints, 4) - ints = append(ints, 1) - ints = append(ints, 2) - ints = append(ints, 3) - - containers.Sort(ints, containers.IntComparator) - - for i := 1; i < len(ints); i++ { - if ints[i-1].(int) > ints[i].(int) { - t.Errorf("Not sorted!") - } - } - -} - -func TestSortStrings(t *testing.T) { - - strings := []interface{}{} - strings = append(strings, "d") - strings = append(strings, "a") - strings = append(strings, "b") - strings = append(strings, "c") - - containers.Sort(strings, containers.StringComparator) - - for i := 1; i < len(strings); i++ { - if strings[i-1].(string) > strings[i].(string) { - t.Errorf("Not sorted!") - } - } -} - -func TestSortStructs(t *testing.T) { - type User struct { - id int - name string - } - - byID := func(a, b interface{}) int { - c1 := a.(User) - c2 := b.(User) - switch { - case c1.id > c2.id: - return 1 - case c1.id < c2.id: - return -1 - default: - return 0 - } - } - - // o1,o2,expected - users := []interface{}{ - User{4, "d"}, - User{1, "a"}, - User{3, "c"}, - User{2, "b"}, - } - - containers.Sort(users, byID) - - for i := 1; i < len(users); i++ { - if users[i-1].(User).id > users[i].(User).id { - t.Errorf("Not sorted!") - } - } -} - -func TestSortRandom(t *testing.T) { - ints := []interface{}{} - for i := 0; i < 10000; i++ { - ints = append(ints, rand.Int()) - } - containers.Sort(ints, containers.IntComparator) - for i := 1; i < len(ints); i++ { - if ints[i-1].(int) > ints[i].(int) { - t.Errorf("Not sorted!") - } - } -} - -func BenchmarkGoSortRandom(b *testing.B) { - b.StopTimer() - ints := []interface{}{} - for i := 0; i < 100000; i++ { - ints = append(ints, rand.Int()) - } - b.StartTimer() - containers.Sort(ints, containers.IntComparator) - b.StopTimer() -} diff --git a/base/datafile.go b/base/datafile.go index 57d61fcc..6318a352 100644 --- a/base/datafile.go +++ b/base/datafile.go @@ -63,7 +63,7 @@ type ( fileName string //文件名 fstream *BitStream readstep int //控制读的总数量 - dataTypes vector.Vector + dataTypes vector.Vector[int] currentColumnIndex int } @@ -114,7 +114,7 @@ func (d *DataFile) ReadDataFile(fileName string) bool { //col name d.fstream.ReadString() nDataType := d.fstream.ReadInt(8) - d.dataTypes.PushBack(int(nDataType)) + d.dataTypes.PushBack(nDataType) } return true } @@ -135,7 +135,7 @@ func (d *DataFile) GetData(data *Data) bool { } data.fileName = d.fileName - switch d.dataTypes.Get(d.currentColumnIndex).(int) { + switch d.dataTypes.Get(d.currentColumnIndex) { case DType_String: data.str = d.fstream.ReadString() case DType_S8: @@ -197,7 +197,7 @@ func (d *DataFile) GetData(data *Data) bool { } } - data.dataType = d.dataTypes.Get(d.currentColumnIndex).(int) + data.dataType = d.dataTypes.Get(d.currentColumnIndex) d.currentColumnIndex = (d.currentColumnIndex + 1) % d.ColumNum d.readstep-- return true diff --git a/base/hashRing.go b/base/hashRing.go index 03183707..b5d4fb2a 100644 --- a/base/hashRing.go +++ b/base/hashRing.go @@ -20,7 +20,7 @@ type ( HashRing struct { ringMap map[uint32]string memberMap map[string]bool - sortedKeys *maps.Map + sortedKeys *maps.Map[uint32, uint32] sync.RWMutex } @@ -40,7 +40,7 @@ func NewHashRing() *HashRing { ring := new(HashRing) ring.ringMap = make(map[uint32]string) ring.memberMap = make(map[string]bool) - ring.sortedKeys = maps.NewWithUInt32Comparator() + ring.sortedKeys = &maps.Map[uint32, uint32]{} return ring } @@ -122,11 +122,11 @@ func (h *HashRing) Get(name string) (error, string) { if !bOk { itr := h.sortedKeys.Iterator() if itr.First() { - return nil, h.ringMap[itr.Key().(uint32)] + return nil, h.ringMap[itr.Key()] } return ErrEmptyRing, "" } - return nil, h.ringMap[node.Key.(uint32)] + return nil, h.ringMap[node.Key] } func (h *HashRing) Get64(val int64) (error, uint32) { @@ -140,18 +140,18 @@ func (h *HashRing) Get64(val int64) (error, uint32) { if !bOk { itr := h.sortedKeys.Iterator() if itr.First() { - return nil, itr.Value().(uint32) + return nil, itr.Value() } return ErrEmptyRing, 0 } - return nil, node.Value.(uint32) + return nil, node.Value } // use for stubring type ( // HashRing holds the information about the members of the consistent hash ring. StubHashRing struct { - sortedKeys *maps.Map + sortedKeys *maps.Map[uint32, uint32] } IStuHashRing interface { @@ -175,7 +175,7 @@ func (h *StubHashRing) add(elt string) { // Add inserts a string element in the consistent hash. func (h *StubHashRing) Init(endpoints []string) { - h.sortedKeys = maps.NewWithUInt32Comparator() + h.sortedKeys = &maps.Map[uint32, uint32]{} for _, v := range endpoints { h.add(v) } @@ -187,9 +187,9 @@ func (h *StubHashRing) Get(val int64) (error, uint32) { if !bOk { itr := h.sortedKeys.Iterator() if itr.First() { - return nil, itr.Value().(uint32) + return nil, itr.Value() } return ErrEmptyRing, 0 } - return nil, node.Value.(uint32) + return nil, node.Value } diff --git a/base/heap/heap.go b/base/heap/heap.go new file mode 100644 index 00000000..2c69ac99 --- /dev/null +++ b/base/heap/heap.go @@ -0,0 +1,118 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package heap provides heap operations for any type that implements +// heap.Interface. A heap is a tree with the property that each node is the +// minimum-valued node in its subtree. +// +// The minimum element in the tree is the root, at index 0. +// +// A heap is a common way to implement a priority queue. To build a priority +// queue, implement the Heap interface with the (negative) priority as the +// ordering for the Less method, so Push adds items while Pop removes the +// highest-priority item from the queue. The Examples include such an +// implementation; the file example_pq_test.go has the complete source. +package heap + +import "sort" + +// The Interface type describes the requirements +// for a type using the routines in this package. +// Any type that implements it may be used as a +// min-heap with the following invariants (established after +// Init has been called or if the data is empty or sorted): +// +// !h.Less(j, i) for 0 <= i < h.Len() and 2*i+1 <= j <= 2*i+2 and j < h.Len() +// +// Note that Push and Pop in this interface are for package heap's +// implementation to call. To add and remove things from the heap, +// use heap.Push and heap.Pop. +type Interface[T any] interface { + sort.Interface + Push(x T) // add x as element Len() + Pop() T // remove and return element Len() - 1. +} + +// Init establishes the heap invariants required by the other routines in this package. +// Init is idempotent with respect to the heap invariants +// and may be called whenever the heap invariants may have been invalidated. +// The complexity is O(n) where n = h.Len(). +func Init[T any](h Interface[T]) { + // heapify + n := h.Len() + for i := n/2 - 1; i >= 0; i-- { + down(h, i, n) + } +} + +// Push pushes the element x onto the heap. +// The complexity is O(log n) where n = h.Len(). +func Push[T any](h Interface[T], x T) { + h.Push(x) + up(h, h.Len()-1) +} + +// Pop removes and returns the minimum element (according to Less) from the heap. +// The complexity is O(log n) where n = h.Len(). +// Pop is equivalent to Remove(h, 0). +func Pop[T any](h Interface[T]) T { + n := h.Len() - 1 + h.Swap(0, n) + down(h, 0, n) + return h.Pop() +} + +// Remove removes and returns the element at index i from the heap. +// The complexity is O(log n) where n = h.Len(). +func Remove[T any](h Interface[T], i int) T { + n := h.Len() - 1 + if n != i { + h.Swap(i, n) + if !down(h, i, n) { + up(h, i) + } + } + return h.Pop() +} + +// Fix re-establishes the heap ordering after the element at index i has changed its value. +// Changing the value of the element at index i and then calling Fix is equivalent to, +// but less expensive than, calling Remove(h, i) followed by a Push of the new value. +// The complexity is O(log n) where n = h.Len(). +func Fix[T any](h Interface[T], i int) { + if !down(h, i, h.Len()) { + up(h, i) + } +} + +func up[T any](h Interface[T], j int) { + for { + i := (j - 1) / 2 // parent + if i == j || !h.Less(j, i) { + break + } + h.Swap(i, j) + j = i + } +} + +func down[T any](h Interface[T], i0, n int) bool { + i := i0 + for { + j1 := 2*i + 1 + if j1 >= n || j1 < 0 { // j1 < 0 after int overflow + break + } + j := j1 // left child + if j2 := j1 + 1; j2 < n && h.Less(j2, j1) { + j = j2 // = 2*i + 2 // right child + } + if !h.Less(j, i) { + break + } + h.Swap(i, j) + i = j + } + return i > i0 +} diff --git a/base/maps/iterator.go b/base/maps/iterator.go index 3bfa433d..2fdb644a 100644 --- a/base/maps/iterator.go +++ b/base/maps/iterator.go @@ -1,15 +1,9 @@ package maps -import "gonet/base/containers" - -func assertIteratorImplementation() { - var _ containers.ReverseIteratorWithKey = (*Iterator)(nil) -} - // Iterator holding the iterator's state -type Iterator struct { - maps *Map - node *Node +type Iterator[K OrderKey, V any] struct { + maps *Map[K, V] + node *Node[K, V] position position } @@ -20,15 +14,15 @@ const ( ) // Iterator returns a stateful iterator whose elements are key/value pairs. -func (it *Map) Iterator() Iterator { - return Iterator{maps: it, node: nil, position: begin} +func (it *Map[K, V]) Iterator() Iterator[K, V] { + return Iterator[K, V]{maps: it, node: nil, position: begin} } // Next moves the iterator to the next element and returns true if there was a next element in the container. // If Next() returns true, then next element's key and value can be retrieved by Key() and Value(). // If Next() was called for the first time, then it will point the iterator to the first element if it exists. // Modifies the state of the iterator. -func (it *Iterator) Next() bool { +func (it *Iterator[K, V]) Next() bool { if it.position == end { goto end } @@ -51,7 +45,7 @@ func (it *Iterator) Next() bool { node := it.node for it.node.Parent != nil { it.node = it.node.Parent - if it.maps.Comparator(node.Key, it.node.Key) <= 0 { + if Comparator(node.Key, it.node.Key) <= 0 { goto between } } @@ -70,7 +64,7 @@ between: // Prev moves the iterator to the previous element and returns true if there was a previous element in the container. // If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value(). // Modifies the state of the iterator. -func (it *Iterator) Prev() bool { +func (it *Iterator[K, V]) Prev() bool { if it.position == begin { goto begin } @@ -93,7 +87,7 @@ func (it *Iterator) Prev() bool { node := it.node for it.node.Parent != nil { it.node = it.node.Parent - if it.maps.Comparator(node.Key, it.node.Key) >= 0 { + if Comparator(node.Key, it.node.Key) >= 0 { goto between } } @@ -111,26 +105,26 @@ between: // Value returns the current element's value. // Does not modify the state of the iterator. -func (it *Iterator) Value() interface{} { +func (it *Iterator[K, V]) Value() V { return it.node.Value } // Key returns the current element's key. // Does not modify the state of the iterator. -func (it *Iterator) Key() interface{} { +func (it *Iterator[K, V]) Key() K { return it.node.Key } // Begin resets the iterator to its initial state (one-before-first) // Call Next() to fetch the first element if any. -func (it *Iterator) Begin() { +func (it *Iterator[K, V]) Begin() { it.node = nil it.position = begin } // End moves the iterator past the last element (one-past-the-end). // Call Prev() to fetch the last element if any. -func (it *Iterator) End() { +func (it *Iterator[K, V]) End() { it.node = nil it.position = end } @@ -138,7 +132,7 @@ func (it *Iterator) End() { // First moves the iterator to the first element and returns true if there was a first element in the container. // If First() returns true, then first element's key and value can be retrieved by Key() and Value(). // Modifies the state of the iterator -func (it *Iterator) First() bool { +func (it *Iterator[K, V]) First() bool { it.Begin() return it.Next() } @@ -146,7 +140,7 @@ func (it *Iterator) First() bool { // Last moves the iterator to the last element and returns true if there was a last element in the container. // If Last() returns true, then last element's key and value can be retrieved by Key() and Value(). // Modifies the state of the iterator. -func (it *Iterator) Last() bool { +func (it *Iterator[K, V]) Last() bool { it.End() return it.Prev() } diff --git a/base/maps/maps.go b/base/maps/maps.go index 5d21a1dc..1726ba03 100644 --- a/base/maps/maps.go +++ b/base/maps/maps.go @@ -2,79 +2,74 @@ package maps import ( "fmt" - "gonet/base/containers" ) -// Map interface that all Maps implement -type IMap interface { - containers.Container - // Empty() bool - // Size() int - // Clear() - // Values() []interface{} -} - -func assertMapImplementation() { - var _ IMap = (*Map)(nil) -} - type color bool const ( black, red color = true, false ) -// Map holds elements of the red-black tree -type Map struct { - Root *Node - size int - Comparator containers.Comparator +type OrderKey interface { + int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | + uint32 | uint64 | uintptr | float32 | float64 | string } -// Node is a single element within the Map -type Node struct { - Key interface{} - Value interface{} - color color - Left *Node - Right *Node - Parent *Node +// IntComparator provides a basic comparison on int +func Comparator[K OrderKey](a, b K) int { + switch { + case a > b: + return 1 + case a < b: + return -1 + default: + return 0 + } } -// NewWith instantiates a red-black tree with the custom comparator. -func NewWith(comparator containers.Comparator) *Map { - return &Map{Comparator: comparator} +// Map interface that all Maps implement +type IMap[K OrderKey, V any] interface { + Empty() bool + Size() int + Clear() + Values() []V } -// NewWithIntComparator instantiates a red-black tree with the IntComparator, i.e. keys are of type int. -func NewWithIntComparator() *Map { - return &Map{Comparator: containers.IntComparator} +func assertMapImplementation() { + var _ IMap[int, interface{}] = (*Map[int, interface{}])(nil) } -// NewWithIntComparator instantiates a red-black tree with the UInt32Comparator, i.e. keys are of type int. -func NewWithUInt32Comparator() *Map { - return &Map{Comparator: containers.UInt32Comparator} +// Map holds elements of the red-black tree +type Map[K OrderKey, V any] struct { + Root *Node[K, V] + size int + Nil V } -// NewWithStringComparator instantiates a red-black tree with the StringComparator, i.e. keys are of type string. -func NewWithStringComparator() *Map { - return &Map{Comparator: containers.StringComparator} +// Node is a single element within the Map +type Node[K OrderKey, V any] struct { + Key K + Value V + color color + Left *Node[K, V] + Right *Node[K, V] + Parent *Node[K, V] } // Put inserts node into the tree. // Key should adhere to the comparator's type assertion, otherwise method panics. -func (m *Map) Put(key interface{}, value interface{}) { - var insertedNode *Node +func (m *Map[K, V]) Put(key K, value V) { + var insertedNode *Node[K, V] if m.Root == nil { // Assert key is of comparator's type for initial tree - m.Comparator(key, key) - m.Root = &Node{Key: key, Value: value, color: red} + Comparator(key, key) + m.Root = &Node[K, V]{Key: key, Value: value, color: red} insertedNode = m.Root } else { node := m.Root loop := true for loop { - compare := m.Comparator(key, node.Key) + compare := Comparator(key, node.Key) switch { case compare == 0: node.Key = key @@ -82,7 +77,7 @@ func (m *Map) Put(key interface{}, value interface{}) { return case compare < 0: if node.Left == nil { - node.Left = &Node{Key: key, Value: value, color: red} + node.Left = &Node[K, V]{Key: key, Value: value, color: red} insertedNode = node.Left loop = false } else { @@ -90,7 +85,7 @@ func (m *Map) Put(key interface{}, value interface{}) { } case compare > 0: if node.Right == nil { - node.Right = &Node{Key: key, Value: value, color: red} + node.Right = &Node[K, V]{Key: key, Value: value, color: red} insertedNode = node.Right loop = false } else { @@ -107,18 +102,18 @@ func (m *Map) Put(key interface{}, value interface{}) { // Get searches the node in the tree by key and returns its value or nil if key is not found in tree. // Second return parameter is true if key was found, otherwise false. // Key should adhere to the comparator's type assertion, otherwise method panics. -func (m *Map) Get(key interface{}) (value interface{}, found bool) { +func (m *Map[K, V]) Get(key K) (value V, found bool) { node := m.lookup(key) if node != nil { return node.Value, true } - return nil, false + return m.Nil, false } // Remove remove the node from the tree by key. // Key should adhere to the comparator's type assertion, otherwise method panics. -func (m *Map) Remove(key interface{}) { - var child *Node +func (m *Map[K, V]) Remove(key K) { + var child *Node[K, V] node := m.lookup(key) if node == nil { return @@ -148,18 +143,18 @@ func (m *Map) Remove(key interface{}) { } // Empty returns true if tree does not contain any nodes -func (m *Map) Empty() bool { +func (m *Map[K, V]) Empty() bool { return m.size == 0 } // Size returns number of nodes in the tree. -func (m *Map) Size() int { +func (m *Map[K, V]) Size() int { return m.size } // Keys returns all keys in-order -func (m *Map) Keys() []interface{} { - keys := make([]interface{}, m.size) +func (m *Map[K, V]) Keys() []K { + keys := make([]K, m.size) it := m.Iterator() for i := 0; it.Next(); i++ { keys[i] = it.Key() @@ -168,8 +163,8 @@ func (m *Map) Keys() []interface{} { } // Values returns all values in-order based on the key. -func (m *Map) Values() []interface{} { - values := make([]interface{}, m.size) +func (m *Map[K, V]) Values() []V { + values := make([]V, m.size) it := m.Iterator() for i := 0; it.Next(); i++ { values[i] = it.Value() @@ -178,8 +173,8 @@ func (m *Map) Values() []interface{} { } // Left returns the left-most (min) node or nil if tree is empty. -func (m *Map) Left() *Node { - var parent *Node +func (m *Map[K, V]) Left() *Node[K, V] { + var parent *Node[K, V] current := m.Root for current != nil { parent = current @@ -189,8 +184,8 @@ func (m *Map) Left() *Node { } // Right returns the right-most (max) node or nil if tree is empty. -func (m *Map) Right() *Node { - var parent *Node +func (m *Map[K, V]) Right() *Node[K, V] { + var parent *Node[K, V] current := m.Root for current != nil { parent = current @@ -207,11 +202,11 @@ func (m *Map) Right() *Node { // all nodes in the tree are larger than the given node. // // Key should adhere to the comparator's type assertion, otherwise method panics. -func (m *Map) Floor(key interface{}) (floor *Node, found bool) { +func (m *Map[K, V]) Floor(key K) (floor *Node[K, V], found bool) { found = false node := m.Root for node != nil { - compare := m.Comparator(key, node.Key) + compare := Comparator(key, node.Key) switch { case compare == 0: return node, true @@ -236,11 +231,11 @@ func (m *Map) Floor(key interface{}) (floor *Node, found bool) { // all nodes in the tree are smaller than the given node. // // Key should adhere to the comparator's type assertion, otherwise method panics. -func (m *Map) Ceiling(key interface{}) (ceiling *Node, found bool) { +func (m *Map[K, V]) Ceiling(key K) (ceiling *Node[K, V], found bool) { found = false node := m.Root for node != nil { - compare := m.Comparator(key, node.Key) + compare := Comparator(key, node.Key) switch { case compare == 0: return node, true @@ -258,13 +253,13 @@ func (m *Map) Ceiling(key interface{}) (ceiling *Node, found bool) { } // Clear removes all nodes from the tree. -func (m *Map) Clear() { +func (m *Map[K, V]) Clear() { m.Root = nil m.size = 0 } // String returns a string representation of container -func (m *Map) String() string { +func (m *Map[K, V]) String() string { str := "RedBlackTree\n" if !m.Empty() { output(m.Root, "", true, &str) @@ -272,11 +267,11 @@ func (m *Map) String() string { return str } -func (node *Node) String() string { +func (node *Node[K, V]) String() string { return fmt.Sprintf("%v", node.Key) } -func output(node *Node, prefix string, isTail bool, str *string) { +func output[K OrderKey, V any](node *Node[K, V], prefix string, isTail bool, str *string) { if node.Right != nil { newPrefix := prefix if isTail { @@ -304,10 +299,10 @@ func output(node *Node, prefix string, isTail bool, str *string) { } } -func (m *Map) lookup(key interface{}) *Node { +func (m *Map[K, V]) lookup(key K) *Node[K, V] { node := m.Root for node != nil { - compare := m.Comparator(key, node.Key) + compare := Comparator(key, node.Key) switch { case compare == 0: return node @@ -320,21 +315,21 @@ func (m *Map) lookup(key interface{}) *Node { return nil } -func (node *Node) grandparent() *Node { +func (node *Node[K, V]) grandparent() *Node[K, V] { if node != nil && node.Parent != nil { return node.Parent.Parent } return nil } -func (node *Node) uncle() *Node { +func (node *Node[K, V]) uncle() *Node[K, V] { if node == nil || node.Parent == nil || node.Parent.Parent == nil { return nil } return node.Parent.sibling() } -func (node *Node) sibling() *Node { +func (node *Node[K, V]) sibling() *Node[K, V] { if node == nil || node.Parent == nil { return nil } @@ -344,7 +339,7 @@ func (node *Node) sibling() *Node { return node.Parent.Left } -func (m *Map) rotateLeft(node *Node) { +func (m *Map[K, V]) rotateLeft(node *Node[K, V]) { right := node.Right m.replaceNode(node, right) node.Right = right.Left @@ -355,7 +350,7 @@ func (m *Map) rotateLeft(node *Node) { node.Parent = right } -func (m *Map) rotateRight(node *Node) { +func (m *Map[K, V]) rotateRight(node *Node[K, V]) { left := node.Left m.replaceNode(node, left) node.Left = left.Right @@ -366,7 +361,7 @@ func (m *Map) rotateRight(node *Node) { node.Parent = left } -func (m *Map) replaceNode(old *Node, new *Node) { +func (m *Map[K, V]) replaceNode(old *Node[K, V], new *Node[K, V]) { if old.Parent == nil { m.Root = new } else { @@ -381,7 +376,7 @@ func (m *Map) replaceNode(old *Node, new *Node) { } } -func (m *Map) insertCase1(node *Node) { +func (m *Map[K, V]) insertCase1(node *Node[K, V]) { if node.Parent == nil { node.color = black } else { @@ -389,14 +384,14 @@ func (m *Map) insertCase1(node *Node) { } } -func (m *Map) insertCase2(node *Node) { +func (m *Map[K, V]) insertCase2(node *Node[K, V]) { if nodeColor(node.Parent) == black { return } m.insertCase3(node) } -func (m *Map) insertCase3(node *Node) { +func (m *Map[K, V]) insertCase3(node *Node[K, V]) { uncle := node.uncle() if nodeColor(uncle) == red { node.Parent.color = black @@ -408,7 +403,7 @@ func (m *Map) insertCase3(node *Node) { } } -func (m *Map) insertCase4(node *Node) { +func (m *Map[K, V]) insertCase4(node *Node[K, V]) { grandparent := node.grandparent() if node == node.Parent.Right && node.Parent == grandparent.Left { m.rotateLeft(node.Parent) @@ -420,7 +415,7 @@ func (m *Map) insertCase4(node *Node) { m.insertCase5(node) } -func (m *Map) insertCase5(node *Node) { +func (m *Map[K, V]) insertCase5(node *Node[K, V]) { node.Parent.color = black grandparent := node.grandparent() grandparent.color = red @@ -431,7 +426,7 @@ func (m *Map) insertCase5(node *Node) { } } -func (node *Node) maximumNode() *Node { +func (node *Node[K, V]) maximumNode() *Node[K, V] { if node == nil { return nil } @@ -441,14 +436,14 @@ func (node *Node) maximumNode() *Node { return node } -func (m *Map) deleteCase1(node *Node) { +func (m *Map[K, V]) deleteCase1(node *Node[K, V]) { if node.Parent == nil { return } m.deleteCase2(node) } -func (m *Map) deleteCase2(node *Node) { +func (m *Map[K, V]) deleteCase2(node *Node[K, V]) { sibling := node.sibling() if nodeColor(sibling) == red { node.Parent.color = red @@ -462,7 +457,7 @@ func (m *Map) deleteCase2(node *Node) { m.deleteCase3(node) } -func (m *Map) deleteCase3(node *Node) { +func (m *Map[K, V]) deleteCase3(node *Node[K, V]) { sibling := node.sibling() if nodeColor(node.Parent) == black && nodeColor(sibling) == black && @@ -475,7 +470,7 @@ func (m *Map) deleteCase3(node *Node) { } } -func (m *Map) deleteCase4(node *Node) { +func (m *Map[K, V]) deleteCase4(node *Node[K, V]) { sibling := node.sibling() if nodeColor(node.Parent) == red && nodeColor(sibling) == black && @@ -488,7 +483,7 @@ func (m *Map) deleteCase4(node *Node) { } } -func (m *Map) deleteCase5(node *Node) { +func (m *Map[K, V]) deleteCase5(node *Node[K, V]) { sibling := node.sibling() if node == node.Parent.Left && nodeColor(sibling) == black && @@ -508,7 +503,7 @@ func (m *Map) deleteCase5(node *Node) { m.deleteCase6(node) } -func (m *Map) deleteCase6(node *Node) { +func (m *Map[K, V]) deleteCase6(node *Node[K, V]) { sibling := node.sibling() sibling.color = nodeColor(node.Parent) node.Parent.color = black @@ -521,7 +516,7 @@ func (m *Map) deleteCase6(node *Node) { } } -func nodeColor(node *Node) color { +func nodeColor[K OrderKey, V any](node *Node[K, V]) color { if node == nil { return black } diff --git a/base/maps/maps_test.go b/base/maps/maps_test.go index 824a605c..62e9c34c 100644 --- a/base/maps/maps_test.go +++ b/base/maps/maps_test.go @@ -10,7 +10,7 @@ import ( ) func TestRedBlackTreePut(t *testing.T) { - tree := NewWithIntComparator() + tree := &Map[int, string]{} tree.Put(5, "e") tree.Put(6, "f") tree.Put(7, "g") @@ -23,10 +23,10 @@ func TestRedBlackTreePut(t *testing.T) { if actualValue := tree.Size(); actualValue != 7 { t.Errorf("Got %v expected %v", actualValue, 7) } - if actualValue, expectedValue := fmt.Sprintf("%d%d%d%d%d%d%d", tree.Keys()...), "1234567"; actualValue != expectedValue { + if actualValue, expectedValue := fmt.Sprintf("%v", tree.Keys()), "[1 2 3 4 5 6 7]"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } - if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s%s%s%s", tree.Values()...), "abcdefg"; actualValue != expectedValue { + if actualValue, expectedValue := fmt.Sprintf("%v", tree.Values()), "[a b c d e f g]"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } @@ -43,7 +43,7 @@ func TestRedBlackTreePut(t *testing.T) { for _, test := range tests1 { // retrievals - actualValue, actualFound := tree.Get(test[0]) + actualValue, actualFound := tree.Get(test[0].(int)) if actualValue != test[1] || actualFound != test[2] { t.Errorf("Got %v expected %v", actualValue, test[1]) } @@ -51,7 +51,7 @@ func TestRedBlackTreePut(t *testing.T) { } func TestRedBlackTreeRemove(t *testing.T) { - tree := NewWithIntComparator() + tree := &Map[int, string]{} tree.Put(5, "e") tree.Put(6, "f") tree.Put(7, "g") @@ -67,13 +67,13 @@ func TestRedBlackTreeRemove(t *testing.T) { tree.Remove(8) tree.Remove(5) - if actualValue, expectedValue := fmt.Sprintf("%d%d%d%d", tree.Keys()...), "1234"; actualValue != expectedValue { + if actualValue, expectedValue := fmt.Sprintf("%v", tree.Keys()), "[1 2 3 4]"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } - if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s", tree.Values()...), "abcd"; actualValue != expectedValue { + if actualValue, expectedValue := fmt.Sprintf("%v", tree.Values()), "[a b c d]"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } - if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s", tree.Values()...), "abcd"; actualValue != expectedValue { + if actualValue, expectedValue := fmt.Sprintf("%v", tree.Values()), "[a b c d]"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } if actualValue := tree.Size(); actualValue != 4 { @@ -92,7 +92,7 @@ func TestRedBlackTreeRemove(t *testing.T) { } for _, test := range tests2 { - actualValue, actualFound := tree.Get(test[0]) + actualValue, actualFound := tree.Get(test[0].(int)) if actualValue != test[1] || actualFound != test[2] { t.Errorf("Got %v expected %v", actualValue, test[1]) } @@ -105,10 +105,10 @@ func TestRedBlackTreeRemove(t *testing.T) { tree.Remove(2) tree.Remove(2) - if actualValue, expectedValue := fmt.Sprintf("%s", tree.Keys()), "[]"; actualValue != expectedValue { + if actualValue, expectedValue := fmt.Sprintf("%v", tree.Keys()), "[]"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } - if actualValue, expectedValue := fmt.Sprintf("%s", tree.Values()), "[]"; actualValue != expectedValue { + if actualValue, expectedValue := fmt.Sprintf("%v", tree.Values()), "[]"; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } if empty, size := tree.Empty(), tree.Size(); empty != true || size != -0 { @@ -118,7 +118,7 @@ func TestRedBlackTreeRemove(t *testing.T) { } func TestRedBlackTreeLeftAndRight(t *testing.T) { - tree := NewWithIntComparator() + tree := &Map[int, string]{} if actualValue := tree.Left(); actualValue != nil { t.Errorf("Got %v expected %v", actualValue, nil) @@ -152,7 +152,7 @@ func TestRedBlackTreeLeftAndRight(t *testing.T) { } func TestRedBlackTreeCeilingAndFloor(t *testing.T) { - tree := NewWithIntComparator() + tree := &Map[int, string]{} if node, found := tree.Floor(0); node != nil || found { t.Errorf("Got %v expected %v", node, "") @@ -185,7 +185,7 @@ func TestRedBlackTreeCeilingAndFloor(t *testing.T) { } func TestRedBlackTreeIteratorNextOnEmpty(t *testing.T) { - tree := NewWithIntComparator() + tree := &Map[int, string]{} it := tree.Iterator() for it.Next() { t.Errorf("Shouldn't iterate on empty tree") @@ -193,7 +193,7 @@ func TestRedBlackTreeIteratorNextOnEmpty(t *testing.T) { } func TestRedBlackTreeIteratorPrevOnEmpty(t *testing.T) { - tree := NewWithIntComparator() + tree := &Map[int, string]{} it := tree.Iterator() for it.Prev() { t.Errorf("Shouldn't iterate on empty tree") @@ -201,7 +201,7 @@ func TestRedBlackTreeIteratorPrevOnEmpty(t *testing.T) { } func TestRedBlackTreeIterator1Next(t *testing.T) { - tree := NewWithIntComparator() + tree := &Map[int, string]{} tree.Put(5, "e") tree.Put(6, "f") tree.Put(7, "g") @@ -239,7 +239,7 @@ func TestRedBlackTreeIterator1Next(t *testing.T) { } func TestRedBlackTreeIterator1Prev(t *testing.T) { - tree := NewWithIntComparator() + tree := &Map[int, string]{} tree.Put(5, "e") tree.Put(6, "f") tree.Put(7, "g") @@ -279,7 +279,7 @@ func TestRedBlackTreeIterator1Prev(t *testing.T) { } func TestRedBlackTreeIterator2Next(t *testing.T) { - tree := NewWithIntComparator() + tree := &Map[int, string]{} tree.Put(3, "c") tree.Put(1, "a") tree.Put(2, "b") @@ -305,7 +305,7 @@ func TestRedBlackTreeIterator2Next(t *testing.T) { } func TestRedBlackTreeIterator2Prev(t *testing.T) { - tree := NewWithIntComparator() + tree := &Map[int, string]{} tree.Put(3, "c") tree.Put(1, "a") tree.Put(2, "b") @@ -333,7 +333,7 @@ func TestRedBlackTreeIterator2Prev(t *testing.T) { } func TestRedBlackTreeIterator3Next(t *testing.T) { - tree := NewWithIntComparator() + tree := &Map[int, string]{} tree.Put(1, "a") it := tree.Iterator() count := 0 @@ -357,7 +357,7 @@ func TestRedBlackTreeIterator3Next(t *testing.T) { } func TestRedBlackTreeIterator3Prev(t *testing.T) { - tree := NewWithIntComparator() + tree := &Map[int, string]{} tree.Put(1, "a") it := tree.Iterator() for it.Next() { @@ -383,7 +383,7 @@ func TestRedBlackTreeIterator3Prev(t *testing.T) { } func TestRedBlackTreeIterator4Next(t *testing.T) { - tree := NewWithIntComparator() + tree := &Map[int, int]{} tree.Put(13, 5) tree.Put(8, 3) tree.Put(17, 7) @@ -426,7 +426,7 @@ func TestRedBlackTreeIterator4Next(t *testing.T) { } func TestRedBlackTreeIterator4Prev(t *testing.T) { - tree := NewWithIntComparator() + tree := &Map[int, int]{} tree.Put(13, 5) tree.Put(8, 3) tree.Put(17, 7) @@ -471,7 +471,7 @@ func TestRedBlackTreeIterator4Prev(t *testing.T) { } func TestRedBlackTreeIteratorBegin(t *testing.T) { - tree := NewWithIntComparator() + tree := &Map[int, string]{} tree.Put(3, "c") tree.Put(1, "a") tree.Put(2, "b") @@ -503,7 +503,7 @@ func TestRedBlackTreeIteratorBegin(t *testing.T) { } func TestRedBlackTreeIteratorEnd(t *testing.T) { - tree := NewWithIntComparator() + tree := &Map[int, string]{} it := tree.Iterator() if it.node != nil { @@ -530,7 +530,7 @@ func TestRedBlackTreeIteratorEnd(t *testing.T) { } func TestRedBlackTreeIteratorFirst(t *testing.T) { - tree := NewWithIntComparator() + tree := &Map[int, string]{} tree.Put(3, "c") tree.Put(1, "a") tree.Put(2, "b") @@ -544,7 +544,7 @@ func TestRedBlackTreeIteratorFirst(t *testing.T) { } func TestRedBlackTreeIteratorLast(t *testing.T) { - tree := NewWithIntComparator() + tree := &Map[int, string]{} tree.Put(3, "c") tree.Put(1, "a") tree.Put(2, "b") @@ -558,7 +558,7 @@ func TestRedBlackTreeIteratorLast(t *testing.T) { } func TestRedBlackTreeSerialization(t *testing.T) { - tree := NewWithStringComparator() + tree := &Map[string, string]{} tree.Put("c", "3") tree.Put("b", "2") tree.Put("a", "1") @@ -568,10 +568,10 @@ func TestRedBlackTreeSerialization(t *testing.T) { if actualValue, expectedValue := tree.Size(), 3; actualValue != expectedValue { t.Errorf("Got %v expected %v", actualValue, expectedValue) } - if actualValue := tree.Keys(); actualValue[0].(string) != "a" || actualValue[1].(string) != "b" || actualValue[2].(string) != "c" { + if actualValue := tree.Keys(); actualValue[0] != "a" || actualValue[1] != "b" || actualValue[2] != "c" { t.Errorf("Got %v expected %v", actualValue, "[a,b,c]") } - if actualValue := tree.Values(); actualValue[0].(string) != "1" || actualValue[1].(string) != "2" || actualValue[2].(string) != "3" { + if actualValue := tree.Values(); actualValue[0] != "1" || actualValue[1] != "2" || actualValue[2] != "3" { t.Errorf("Got %v expected %v", actualValue, "[1,2,3]") } if err != nil { @@ -588,7 +588,7 @@ func TestRedBlackTreeSerialization(t *testing.T) { assert() } -func benchmarkGet(b *testing.B, tree *Map, size int) { +func benchmarkGet(b *testing.B, tree *Map[int, struct{}], size int) { for i := 0; i < b.N; i++ { for n := 0; n < size; n++ { tree.Get(n) @@ -596,7 +596,7 @@ func benchmarkGet(b *testing.B, tree *Map, size int) { } } -func benchmarkPut(b *testing.B, tree *Map, size int) { +func benchmarkPut(b *testing.B, tree *Map[int, struct{}], size int) { for i := 0; i < b.N; i++ { for n := 0; n < size; n++ { tree.Put(n, struct{}{}) @@ -604,7 +604,7 @@ func benchmarkPut(b *testing.B, tree *Map, size int) { } } -func benchmarkRemove(b *testing.B, tree *Map, size int) { +func benchmarkRemove(b *testing.B, tree *Map[int, struct{}], size int) { for i := 0; i < b.N; i++ { for n := 0; n < size; n++ { tree.Remove(n) @@ -615,7 +615,7 @@ func benchmarkRemove(b *testing.B, tree *Map, size int) { func BenchmarkRedBlackTreeGet100(b *testing.B) { b.StopTimer() size := 100 - tree := NewWithIntComparator() + tree := &Map[int, struct{}]{} for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } @@ -626,7 +626,7 @@ func BenchmarkRedBlackTreeGet100(b *testing.B) { func BenchmarkRedBlackTreeGet1000(b *testing.B) { b.StopTimer() size := 1000 - tree := NewWithIntComparator() + tree := &Map[int, struct{}]{} for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } @@ -637,7 +637,7 @@ func BenchmarkRedBlackTreeGet1000(b *testing.B) { func BenchmarkRedBlackTreeGet10000(b *testing.B) { b.StopTimer() size := 10000 - tree := NewWithIntComparator() + tree := &Map[int, struct{}]{} for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } @@ -648,7 +648,7 @@ func BenchmarkRedBlackTreeGet10000(b *testing.B) { func BenchmarkRedBlackTreeGet100000(b *testing.B) { b.StopTimer() size := 100000 - tree := NewWithIntComparator() + tree := &Map[int, struct{}]{} for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } @@ -659,7 +659,7 @@ func BenchmarkRedBlackTreeGet100000(b *testing.B) { func BenchmarkRedBlackTreePut100(b *testing.B) { b.StopTimer() size := 100 - tree := NewWithIntComparator() + tree := &Map[int, struct{}]{} b.StartTimer() benchmarkPut(b, tree, size) } @@ -667,7 +667,7 @@ func BenchmarkRedBlackTreePut100(b *testing.B) { func BenchmarkRedBlackTreePut1000(b *testing.B) { b.StopTimer() size := 1000 - tree := NewWithIntComparator() + tree := &Map[int, struct{}]{} for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } @@ -678,7 +678,7 @@ func BenchmarkRedBlackTreePut1000(b *testing.B) { func BenchmarkRedBlackTreePut10000(b *testing.B) { b.StopTimer() size := 10000 - tree := NewWithIntComparator() + tree := &Map[int, struct{}]{} for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } @@ -689,7 +689,7 @@ func BenchmarkRedBlackTreePut10000(b *testing.B) { func BenchmarkRedBlackTreePut100000(b *testing.B) { b.StopTimer() size := 100000 - tree := NewWithIntComparator() + tree := &Map[int, struct{}]{} for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } @@ -700,7 +700,7 @@ func BenchmarkRedBlackTreePut100000(b *testing.B) { func BenchmarkRedBlackTreeRemove100(b *testing.B) { b.StopTimer() size := 100 - tree := NewWithIntComparator() + tree := &Map[int, struct{}]{} for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } @@ -711,7 +711,7 @@ func BenchmarkRedBlackTreeRemove100(b *testing.B) { func BenchmarkRedBlackTreeRemove1000(b *testing.B) { b.StopTimer() size := 1000 - tree := NewWithIntComparator() + tree := &Map[int, struct{}]{} for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } @@ -722,7 +722,7 @@ func BenchmarkRedBlackTreeRemove1000(b *testing.B) { func BenchmarkRedBlackTreeRemove10000(b *testing.B) { b.StopTimer() size := 10000 - tree := NewWithIntComparator() + tree := &Map[int, struct{}]{} for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } @@ -733,7 +733,7 @@ func BenchmarkRedBlackTreeRemove10000(b *testing.B) { func BenchmarkRedBlackTreeRemove100000(b *testing.B) { b.StopTimer() size := 100000 - tree := NewWithIntComparator() + tree := &Map[int, struct{}]{} for n := 0; n < size; n++ { tree.Put(n, struct{}{}) } diff --git a/base/maps/serialization.go b/base/maps/serialization.go index fca36714..b73cd7f4 100644 --- a/base/maps/serialization.go +++ b/base/maps/serialization.go @@ -39,7 +39,7 @@ func ToString(value interface{}) string { } // ToJSON outputs the JSON representation of the tree. -func (tree *Map) ToJSON() ([]byte, error) { +func (tree *Map[K, V]) ToJSON() ([]byte, error) { elements := make(map[string]interface{}) it := tree.Iterator() for it.Next() { @@ -49,8 +49,8 @@ func (tree *Map) ToJSON() ([]byte, error) { } // FromJSON populates the tree from the input JSON representation. -func (tree *Map) FromJSON(data []byte) error { - elements := make(map[string]interface{}) +func (tree *Map[K, V]) FromJSON(data []byte) error { + elements := make(map[K]V) err := json.Unmarshal(data, &elements) if err == nil { tree.Clear() diff --git a/base/mpmc/deque.go b/base/mpmc/deque.go index 4587a51e..e2749d75 100644 --- a/base/mpmc/deque.go +++ b/base/mpmc/deque.go @@ -8,23 +8,24 @@ import ( type ( Cursor [8]uint64 // prevent false sharing of the sequence cursor by padding the CPU cache line with 64 *bytes* of data. - node struct { + node[T any] struct { sequence uint64 - val interface{} + val T } - Queue struct { + Queue[T any] struct { write *Cursor // the ring buffer has been written up to q sequence read *Cursor // q reader has processed up to q sequence bufferSize uint64 bufferMask uint64 - ringBuffer []interface{} + ringBuffer []*node[T] + Nil T } ) -func (n *node) Store(value uint64) { atomic.StoreUint64(&n.sequence, value) } -func (n *node) Load() uint64 { return atomic.LoadUint64(&n.sequence) } -func (n *node) CmpAndSwap(old, new uint64) bool { +func (n *node[T]) Store(value uint64) { atomic.StoreUint64(&n.sequence, value) } +func (n *node[T]) Load() uint64 { return atomic.LoadUint64(&n.sequence) } +func (n *node[T]) CmpAndSwap(old, new uint64) bool { return atomic.CompareAndSwapUint64(&n.sequence, old, new) } @@ -34,8 +35,8 @@ func NewCursor() *Cursor { return &c } -func New(size uint64) *Queue { - q := &Queue{} +func New[T any](size uint64) *Queue[T] { + q := &Queue[T]{} q.Init(size) return q } @@ -60,24 +61,24 @@ func roundUp1(v uint64) uint64 { return v } -func (q *Queue) Init(size uint64) { +func (q *Queue[T]) Init(size uint64) { q.bufferSize = roundUp1(size) q.bufferMask = q.bufferSize - 1 q.write = NewCursor() q.read = NewCursor() - q.ringBuffer = make([]interface{}, q.bufferSize) + q.ringBuffer = make([]*node[T], q.bufferSize) for i := uint64(0); i < q.bufferSize; i++ { - n := &node{} + n := &node[T]{} atomic.StoreUint64(&n.sequence, i) q.ringBuffer[i] = n } } -func (q *Queue) Push(data interface{}) { - var n *node +func (q *Queue[T]) Push(data T) { + var n *node[T] pos := q.write.Load() for true { - n = q.ringBuffer[pos&q.bufferMask].(*node) + n = q.ringBuffer[pos&q.bufferMask] seq := n.Load() dif := int64(seq) - int64(pos) if dif == 0 { @@ -95,11 +96,11 @@ func (q *Queue) Push(data interface{}) { n.Store(pos + 1) } -func (q *Queue) Pop() interface{} { - var n *node +func (q *Queue[T]) Pop() T { + var n *node[T] pos := q.read.Load() for true { - n = q.ringBuffer[pos&q.bufferMask].(*node) + n = q.ringBuffer[pos&q.bufferMask] seq := n.Load() dif := int64(seq) - (int64(pos + 1)) if dif == 0 { @@ -107,7 +108,7 @@ func (q *Queue) Pop() interface{} { break } } else if dif < 0 { - return nil + return q.Nil } else { pos = q.read.Load() } diff --git a/base/mpmc/deque_test.go b/base/mpmc/deque_test.go index a0f3d70c..cf035bbc 100644 --- a/base/mpmc/deque_test.go +++ b/base/mpmc/deque_test.go @@ -12,7 +12,7 @@ import ( const QueSize = 2000 func TestQueue_PushPop(t *testing.T) { - q := New(QueSize) + q := New[int](QueSize) q.Push(1) q.Push(2) @@ -27,7 +27,7 @@ func TestQueue_PushPopOneProducer(t *testing.T) { var wg sync.WaitGroup wg.Add(1) - q := New(QueSize) + q := New[*string](QueSize) go func() { i := 0 for { @@ -44,10 +44,10 @@ func TestQueue_PushPopOneProducer(t *testing.T) { } }() - var val interface{} = "foo" + var val string = "foo" for i := 0; i < expCount; i++ { - q.Push(val) + q.Push(&val) } wg.Wait() @@ -59,7 +59,7 @@ func TestMpmcQueueConsistency(t *testing.T) { cmax := max / c var wg sync.WaitGroup wg.Add(2) - q := New(QueSize) + q := New[*string](QueSize) go func() { i := 0 seen := make(map[string]string) @@ -71,14 +71,14 @@ func TestMpmcQueueConsistency(t *testing.T) { continue } i++ - s := r.(string) + s := *r _, present := seen[s] if present { log.Printf("item have already been seen %v", s) t.FailNow() } seen[s] = s - if i == cmax*c / 2{ + if i == cmax*c/2 { wg.Done() return } @@ -96,14 +96,14 @@ func TestMpmcQueueConsistency(t *testing.T) { continue } i++ - s := r.(string) + s := *r _, present := seen[s] if present { log.Printf("item have already been seen %v", s) t.FailNow() } seen[s] = s - if i == cmax*c / 2{ + if i == cmax*c/2 { wg.Done() return } @@ -117,7 +117,8 @@ func TestMpmcQueueConsistency(t *testing.T) { if rand.Intn(10) == 0 { //time.Sleep(time.Duration(rand.Intn(1000))) } - q.Push(fmt.Sprintf("%v %v", jj, i)) + val := fmt.Sprintf("%v %v", jj, i) + q.Push(&val) } }() } @@ -137,7 +138,7 @@ func TestMpmcQueueConsistency(t *testing.T) { func benchmarkPushPop(count, c int) { var wg sync.WaitGroup wg.Add(1) - q := New(QueSize) + q := New[*string](QueSize) go func() { i := 0 for { @@ -154,12 +155,12 @@ func benchmarkPushPop(count, c int) { } }() - var val interface{} = "foo" + var val string = "foo" for i := 0; i < c; i++ { go func(n int) { for n > 0 { - q.Push(val) + q.Push(&val) n-- } }(count / c) diff --git a/base/mpsc/deque.go b/base/mpsc/deque.go index ad16b519..3dc4f2c9 100644 --- a/base/mpsc/deque.go +++ b/base/mpsc/deque.go @@ -12,18 +12,19 @@ import ( "unsafe" ) -type node struct { - next *node - val interface{} +type node[T any] struct { + next *node[T] + val T } -type Queue struct { - head, tail *node +type Queue[T any] struct { + head, tail *node[T] + Nil T } -func New() *Queue { - q := &Queue{} - stub := &node{} +func New[T any]() *Queue[T] { + q := &Queue[T]{} + stub := &node[T]{} q.head = stub q.tail = stub return q @@ -32,11 +33,11 @@ func New() *Queue { // Push adds x to the back of the queue. // // Push can be safely called from multiple goroutines -func (q *Queue) Push(x interface{}) { - n := new(node) +func (q *Queue[T]) Push(x T) { + n := new(node[T]) n.val = x // current producer acquires head node - prev := (*node)(atomic.SwapPointer((*unsafe.Pointer)(unsafe.Pointer(&q.head)), unsafe.Pointer(n))) + prev := (*node[T])(atomic.SwapPointer((*unsafe.Pointer)(unsafe.Pointer(&q.head)), unsafe.Pointer(n))) // release node to consumer atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&prev.next)), unsafe.Pointer(n)) @@ -45,23 +46,22 @@ func (q *Queue) Push(x interface{}) { // Pop removes the item from the front of the queue or nil if the queue is empty // // Pop must be called from a single, consumer goroutine -func (q *Queue) Pop() interface{} { +func (q *Queue[T]) Pop() T { tail := q.tail - next := (*node)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&tail.next)))) // acquire + next := (*node[T])(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&tail.next)))) // acquire if next != nil { q.tail = next v := next.val - next.val = nil return v } - return nil + return q.Nil } // Empty returns true if the queue is empty // // Empty must be called from a single, consumer goroutine -func (q *Queue) Empty() bool { +func (q *Queue[T]) Empty() bool { tail := q.tail - next := (*node)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&tail.next)))) + next := (*node[T])(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&tail.next)))) return next == nil } diff --git a/base/mpsc/deque_test.go b/base/mpsc/deque_test.go index 9817c168..9f9dd551 100644 --- a/base/mpsc/deque_test.go +++ b/base/mpsc/deque_test.go @@ -11,7 +11,7 @@ import ( ) func TestQueue_PushPop(t *testing.T) { - q := New() + q := New[int]() q.Push(1) q.Push(2) @@ -21,10 +21,10 @@ func TestQueue_PushPop(t *testing.T) { } func TestQueue_Empty(t *testing.T) { - q := New() + q := New[int]() t.Log(q.Empty()) q.Push(1) - t.Log( q.Empty()) + t.Log(q.Empty()) } func TestQueue_PushPopOneProducer(t *testing.T) { @@ -32,7 +32,7 @@ func TestQueue_PushPopOneProducer(t *testing.T) { var wg sync.WaitGroup wg.Add(1) - q := New() + q := New[*string]() go func() { i := 0 for { @@ -49,10 +49,10 @@ func TestQueue_PushPopOneProducer(t *testing.T) { } }() - var val interface{} = "foo" + var val string = "foo" for i := 0; i < expCount; i++ { - q.Push(val) + q.Push(&val) } wg.Wait() @@ -64,7 +64,7 @@ func TestMpscQueueConsistency(t *testing.T) { cmax := max / c var wg sync.WaitGroup wg.Add(1) - q := New() + q := New[*string]() go func() { i := 0 seen := make(map[string]string) @@ -76,7 +76,7 @@ func TestMpscQueueConsistency(t *testing.T) { continue } i++ - s := r.(string) + s := *r _, present := seen[s] if present { log.Printf("item have already been seen %v", s) @@ -94,7 +94,8 @@ func TestMpscQueueConsistency(t *testing.T) { jj := j go func() { for i := 0; i < cmax; i++ { - q.Push(fmt.Sprintf("%v %v", jj, i)) + val := fmt.Sprintf("%v %v", jj, i) + q.Push(&val) } }() } @@ -114,7 +115,7 @@ func TestMpscQueueConsistency(t *testing.T) { func benchmarkPushPop(count, c int) { var wg sync.WaitGroup wg.Add(1) - q := New() + q := New[*string]() go func() { i := 0 for { @@ -131,12 +132,12 @@ func benchmarkPushPop(count, c int) { } }() - var val interface{} = "foo" + var val string = "foo" for i := 0; i < c; i++ { go func(n int) { for n > 0 { - q.Push(val) + q.Push(&val) n-- } }(count / c) @@ -187,7 +188,7 @@ func benchmarkChanPushPop(count, c int) { go func() { i := 0 for { - select{ + select { case <-q: i++ if i == count { @@ -248,18 +249,18 @@ func BenchmarkChanPushPop(b *testing.B) { } } -var g_MailChan = make(chan bool, 1) +var g_MailChan = make(chan bool, 1) var g_bMailIn [8]int64 func benchmarkPushPopActor(count, c int) { var wg sync.WaitGroup wg.Add(1) - q := New() + q := New[*string]() go func() { i := 0 for { select { - case <- g_MailChan: + case <-g_MailChan: atomic.StoreInt64(&g_bMailIn[0], 0) for data := q.Pop(); data != nil; data = q.Pop() { i++ @@ -272,12 +273,12 @@ func benchmarkPushPopActor(count, c int) { } }() - var val interface{} = "foo" + var val string = "foo" for i := 0; i < c; i++ { go func(n int) { for n > 0 { - q.Push(val) + q.Push(&val) if atomic.LoadInt64(&g_bMailIn[0]) == 0 && atomic.CompareAndSwapInt64(&g_bMailIn[0], 0, 1) { g_MailChan <- true } diff --git a/base/uuid.go b/base/uuid.go index 3ab789a8..5d74d492 100644 --- a/base/uuid.go +++ b/base/uuid.go @@ -47,7 +47,7 @@ type ( WorkIdQue struct { //workid que workMap map[uint32]int - idelVec *vector.Vector + idelVec *vector.Vector[int] id int } @@ -101,7 +101,7 @@ func ParseUUID(id int64) (ts int64, workerId int64, seq int64) { //----------WorkIdQue----------// func (w *WorkIdQue) Init(id int) { w.workMap = make(map[uint32]int) - w.idelVec = vector.NewVector() + w.idelVec = &vector.Vector[int]{} w.id = id } @@ -113,11 +113,10 @@ func (w *WorkIdQue) Add(val string) int { } if !w.idelVec.Empty() { - back := w.idelVec.Back() - nId = back.(int) + nId := w.idelVec.Back() w.idelVec.PopBack() w.workMap[nVal] = nId - return back.(int) + return nId } nId = w.id diff --git a/base/vector/iterator.go b/base/vector/iterator.go index 96053908..aa576270 100644 --- a/base/vector/iterator.go +++ b/base/vector/iterator.go @@ -1,27 +1,21 @@ package vector -import "gonet/base/containers" - -func assertIteratorImplementation() { - var _ containers.ReverseIteratorWithIndex = (*Iterator)(nil) -} - // Iterator holding the iterator's state -type Iterator struct { - vec *Vector +type Iterator[T any] struct { + vec *Vector[T] index int } // Iterator returns a stateful iterator whose values can be fetched by an index. -func (v *Vector) Iterator() Iterator { - return Iterator{vec: v, index: -1} +func (v *Vector[T]) Iterator() Iterator[T] { + return Iterator[T]{vec: v, index: -1} } // Next moves the iterator to the next element and returns true if there was a next element in the container. // If Next() returns true, then next element's index and value can be retrieved by Index() and Value(). // If Next() was called for the first time, then it will point the iterator to the first element if it exists. // Modifies the state of the iterator. -func (v *Iterator) Next() bool { +func (v *Iterator[T]) Next() bool { if v.index < v.vec.elementCount { v.index++ } @@ -31,7 +25,7 @@ func (v *Iterator) Next() bool { // Prev moves the iterator to the previous element and returns true if there was a previous element in the container. // If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value(). // Modifies the state of the iterator. -func (v *Iterator) Prev() bool { +func (v *Iterator[T]) Prev() bool { if v.index >= 0 { v.index-- } @@ -40,32 +34,32 @@ func (v *Iterator) Prev() bool { // Value returns the current element's value. // Does not modify the state of the iterator. -func (v *Iterator) Value() interface{} { +func (v *Iterator[T]) Value() T { return v.vec.Get(v.index) } // Index returns the current element's index. // Does not modify the state of the iterator. -func (v *Iterator) Index() int { +func (v *Iterator[T]) Index() int { return v.index } // Begin resets the iterator to its initial state (one-before-first) // Call Next() to fetch the first element if any. -func (v *Iterator) Begin() { +func (v *Iterator[T]) Begin() { v.index = -1 } // End moves the iterator past the last element (one-past-the-end). // Call Prev() to fetch the last element if any. -func (v *Iterator) End() { +func (v *Iterator[T]) End() { v.index = v.vec.elementCount } // First moves the iterator to the first element and returns true if there was a first element in the container. // If First() returns true, then first element's index and value can be retrieved by Index() and Value(). // Modifies the state of the iterator. -func (v *Iterator) First() bool { +func (v *Iterator[T]) First() bool { v.Begin() return v.Next() } @@ -73,7 +67,7 @@ func (v *Iterator) First() bool { // Last moves the iterator to the last element and returns true if there was a last element in the container. // If Last() returns true, then last element's index and value can be retrieved by Index() and Value(). // Modifies the state of the iterator. -func (v *Iterator) Last() bool { +func (v *Iterator[T]) Last() bool { v.End() return v.Prev() } diff --git a/base/vector/vector.go b/base/vector/vector.go index b2c80a3f..c1fe3730 100644 --- a/base/vector/vector.go +++ b/base/vector/vector.go @@ -1,7 +1,6 @@ package vector import ( - "gonet/base/containers" "log" ) @@ -16,33 +15,14 @@ const ( ) type ( - Vector struct { + Vector[T any] struct { elementCount int arraySize int - array []interface{} - } - - IVector interface { - containers.Container - insert(int) - increment() - decrement() - - Erase(int) - PushFront(interface{}) - PushBack(interface{}) - PopFront() - PopBack() - Front() interface{} - Back() interface{} - Len() int - Get(int) interface{} - Swap(i, j int) - Less(i, j int) bool + array []T } ) -func (v *Vector) insert(index int) { +func (v *Vector[T]) insert(index int) { assert(index <= v.elementCount, "Vector::insert - out of bounds index.") if v.elementCount == v.arraySize { @@ -56,7 +36,7 @@ func (v *Vector) insert(index int) { } } -func (v *Vector) increment() { +func (v *Vector[T]) increment() { if v.elementCount == v.arraySize { v.resize(v.elementCount + 1) } else { @@ -64,12 +44,12 @@ func (v *Vector) increment() { } } -func (v *Vector) decrement() { +func (v *Vector[T]) decrement() { assert(v.elementCount != 0, "Vector::decrement - cannot decrement zero-length vector.") v.elementCount-- } -func (v *Vector) resize(newCount int) bool { +func (v *Vector[T]) resize(newCount int) bool { if newCount > 0 { blocks := newCount / VectorBlockSize if newCount%VectorBlockSize != 0 { @@ -78,14 +58,14 @@ func (v *Vector) resize(newCount int) bool { v.elementCount = newCount v.arraySize = blocks * VectorBlockSize - newAarray := make([]interface{}, v.arraySize+1) + newAarray := make([]T, v.arraySize+1) copy(newAarray, v.array) v.array = newAarray } return true } -func (v *Vector) Erase(index int) { +func (v *Vector[T]) Erase(index int) { assert(index < v.elementCount, "Vector::erase - out of bounds index.") if index < v.elementCount-1 { copy(v.array[index:v.elementCount], v.array[index+1:v.elementCount]) @@ -94,74 +74,70 @@ func (v *Vector) Erase(index int) { v.elementCount-- } -func (v *Vector) PushFront(value interface{}) { +func (v *Vector[T]) PushFront(value T) { v.insert(0) v.array[0] = value } -func (v *Vector) PushBack(value interface{}) { +func (v *Vector[T]) PushBack(value T) { v.increment() v.array[v.elementCount-1] = value } -func (v *Vector) PopFront() { +func (v *Vector[T]) PopFront() { assert(v.elementCount != 0, "Vector::pop_front - cannot pop the front of a zero-length vector.") v.Erase(0) } -func (v *Vector) PopBack() { +func (v *Vector[T]) PopBack() { assert(v.elementCount != 0, "Vector::pop_back - cannot pop the back of a zero-length vector.") v.decrement() } // Check that the index is within bounds of the list -func (v *Vector) withinRange(index int) bool { +func (v *Vector[T]) withinRange(index int) bool { return index >= 0 && index < v.elementCount } -func (v *Vector) Front() interface{} { +func (v *Vector[T]) Front() T { assert(v.elementCount != 0, "Vector::first - Error, no first element of a zero sized array! (const)") return v.array[0] } -func (v *Vector) Back() interface{} { +func (v *Vector[T]) Back() T { assert(v.elementCount != 0, "Vector::last - Error, no last element of a zero sized array! (const)") return v.array[v.elementCount-1] } -func (v *Vector) Empty() bool { +func (v *Vector[T]) Empty() bool { return v.elementCount == 0 } -func (v *Vector) Size() int { +func (v *Vector[T]) Size() int { return v.arraySize } -func (v *Vector) Clear() { +func (v *Vector[T]) Clear() { v.elementCount = 0 } -func (v *Vector) Len() int { +func (v *Vector[T]) Len() int { return v.elementCount } -func (v *Vector) Get(index int) interface{} { +func (v *Vector[T]) Get(index int) T { assert(index < v.elementCount, "Vector::operator[] - out of bounds array access!") return v.array[index] } -func (v *Vector) Values() []interface{} { +func (v *Vector[T]) Values() []T { return v.array[0:v.elementCount] } -func (v *Vector) Swap(i, j int) { +func (v *Vector[T]) Swap(i, j int) { v.array[i], v.array[j] = v.array[j], v.array[i] } -func (v *Vector) Less(i, j int) bool { +func (v *Vector[T]) Less(i, j int) bool { return true } - -func NewVector() *Vector { - return &Vector{} -} diff --git a/common/betree/BehaviorTree.go b/common/betree/BehaviorTree.go index 02555d34..8eaf0152 100644 --- a/common/betree/BehaviorTree.go +++ b/common/betree/BehaviorTree.go @@ -12,7 +12,7 @@ import ( // * Action Node type ( BehaviorList struct { - vector.Vector + vector.Vector[IBaseNode] } IBehaviorList interface { @@ -34,7 +34,7 @@ type ( ) func (b *BehaviorList) Less(i, j int) bool { - return b.Get(i).(IBaseNode).GetName() < b.Get(j).(IBaseNode).GetName() + return b.Get(i).GetName() < b.Get(j).GetName() } func (b *BehaviorList) AddChild(name string, pNode IBaseNode) { diff --git a/common/cluster/Cluster.go b/common/cluster/Cluster.go index de691536..5456c7a5 100644 --- a/common/cluster/Cluster.go +++ b/common/cluster/Cluster.go @@ -45,7 +45,7 @@ type ( dieChan chan bool master *Master clusterInfoMap map[uint32]*common.ClusterInfo - packetFuncList *vector.Vector //call back + packetFuncList *vector.Vector[network.PacketFunc] //call back MailBox etv3.MailBox StubMailBox etv3.StubMailBox Stub common.Stub @@ -109,7 +109,7 @@ func (c *Cluster) InitCluster(info *common.ClusterInfo, Endpoints []string, nats c.hashRing[i] = base.NewHashRing() } c.clusterInfoMap = make(map[uint32]*common.ClusterInfo) - c.packetFuncList = vector.NewVector() + c.packetFuncList = &vector.Vector[network.PacketFunc]{} conn, err := setupNatsConn( natsUrl, @@ -205,7 +205,7 @@ func (c *Cluster) BindPacketFunc(callfunc network.PacketFunc) { func (c *Cluster) HandlePacket(packet rpc.Packet) { for _, v := range c.packetFuncList.Values() { - if v.(network.PacketFunc)(packet) { + if v(packet) { break } } diff --git a/common/cluster/rpc/Cluster.go b/common/cluster/rpc/Cluster.go index e6b7ffad..464b96f6 100644 --- a/common/cluster/rpc/Cluster.go +++ b/common/cluster/rpc/Cluster.go @@ -38,7 +38,7 @@ type ( master *Master hashRing *base.HashRing //hash一致性 clusterInfoMapg map[uint32]*common.ClusterInfo - packetFuncList *vector.Vector //call back + packetFuncList *vector.Vector[network.PacketFunc] //call back } ICluster interface { @@ -87,7 +87,7 @@ func (c *Cluster) InitCluster(info *common.ClusterInfo, Endpoints []string) { c.master = NewMaster(info, Endpoints) c.hashRing = base.NewHashRing() c.clusterInfoMapg = make(map[uint32]*common.ClusterInfo) - c.packetFuncList = vector.NewVector() + c.packetFuncList = &vector.Vector[network.PacketFunc]{} actor.MGR.RegisterActor(c) c.Actor.Start() } @@ -124,7 +124,7 @@ func (c *Cluster) AddCluster(info *common.ClusterInfo) { packet.SetClusterId(info.Id()) client.BindPacketFunc(actor.MGR.PacketFunc) for _, v := range c.packetFuncList.Values() { - client.BindPacketFunc(v.(network.PacketFunc)) + client.BindPacketFunc(v) } c.clusterLocker.Lock() c.clusterMap[info.Id()] = &ClusterNode{ClientSocket: client, ClusterInfo: info} diff --git a/go.mod b/go.mod index 080187d6..f9068fa2 100644 --- a/go.mod +++ b/go.mod @@ -1,37 +1,70 @@ module gonet -go 1.12 +go 1.18 require ( + github.com/go-sql-driver/mysql v1.4.1 + github.com/golang/protobuf v1.5.2 + github.com/gomodule/redigo v2.0.0+incompatible + github.com/json-iterator/go v1.1.7 + github.com/nats-io/nats.go v1.14.0 + github.com/stretchr/testify v1.7.0 + github.com/tealeg/xlsx v1.0.5 + github.com/xtaci/kcp-go v4.3.4+incompatible + go.etcd.io/etcd v3.3.17+incompatible + golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9 + google.golang.org/protobuf v1.28.0 + gopkg.in/yaml.v2 v2.4.0 +) + +require ( + github.com/coreos/bbolt v0.0.0-00010101000000-000000000000 // indirect github.com/coreos/etcd v3.3.17+incompatible // indirect github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-systemd v0.0.0-00010101000000-000000000000 // indirect github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect - github.com/go-sql-driver/mysql v1.4.1 - github.com/gogo/protobuf v1.3.1 // indirect - github.com/golang/protobuf v1.5.2 - github.com/gomodule/redigo v2.0.0+incompatible + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/google/btree v1.0.1 // indirect github.com/google/uuid v1.1.1 // indirect - github.com/hashicorp/raft v1.2.0 // indirect - github.com/hashicorp/raft-boltdb v0.0.0-20191021154308-4207f1bf0617 // indirect - github.com/json-iterator/go v1.1.7 + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect + github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect + github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect + github.com/jonboulle/clockwork v0.3.0 // indirect + github.com/klauspost/cpuid/v2 v2.0.6 // indirect github.com/klauspost/reedsolomon v1.9.13 // indirect + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v1.0.1 // indirect - github.com/nats-io/nats.go v1.10.0 - github.com/stretchr/testify v1.4.0 - github.com/tealeg/xlsx v1.0.5 + github.com/nats-io/nats-server/v2 v2.8.2 // indirect + github.com/nats-io/nkeys v0.3.0 // indirect + github.com/nats-io/nuid v1.0.1 // indirect + github.com/pkg/errors v0.8.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_golang v0.9.2 // indirect + github.com/soheilhy/cmux v0.1.5 // indirect github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b // indirect github.com/tjfoc/gmsm v1.4.1 // indirect - github.com/xtaci/kcp-go v4.3.4+incompatible - go.etcd.io/etcd v3.3.17+incompatible + github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 // indirect + github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect + go.uber.org/atomic v1.6.0 // indirect + go.uber.org/multierr v1.5.0 // indirect go.uber.org/zap v1.15.0 // indirect - golang.org/x/net v0.0.0-20201010224723-4f7140c49acb - google.golang.org/genproto v0.0.0-20200428115010-c45acf45369a // indirect - google.golang.org/protobuf v1.28.0 - gopkg.in/yaml.v2 v2.2.2 + golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect + golang.org/x/sys v0.0.0-20220111092808-5a964db01320 // indirect + golang.org/x/text v0.3.6 // indirect + golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect + google.golang.org/appengine v1.4.0 // indirect + google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884 // indirect + google.golang.org/grpc v1.33.1 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect + sigs.k8s.io/yaml v1.3.0 // indirect ) -replace google.golang.org/grpc => google.golang.org/grpc v1.26.0 - replace github.com/coreos/go-systemd => github.com/coreos/go-systemd/v22 v22.0.0 + +replace github.com/coreos/bbolt => go.etcd.io/bbolt v1.3.4 + +replace google.golang.org/grpc => google.golang.org/grpc v1.26.0 diff --git a/go.sum b/go.sum index 6908dc7a..5380b999 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,10 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 h1:EFSB7Zo9Eg91v7MJPVsifUysc/wPdN+NOnVe6bWbdBM= -github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= -github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= -github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/coreos/etcd v3.3.17+incompatible h1:f/Z3EoDSx1yjaIjLQGo1diYUlQYSBrrAQ5vP8NjwXwo= github.com/coreos/etcd v3.3.17+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= @@ -19,14 +16,23 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -34,84 +40,97 @@ github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaW github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0 h1:aRz0NBceriICVtjhCgKkDvl+RudKu1CT6h0ZvUTrNfE= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0= github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-hclog v0.9.1 h1:9PZfAcVEvez4yhLH2TBU64/h/z4xlFI80cWXRrxuKuM= -github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= -github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/raft v1.1.0/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM= -github.com/hashicorp/raft v1.2.0 h1:mHzHIrF0S91d3A7RPBvuqkgB4d/7oFJZyvf1Q4m7GA0= -github.com/hashicorp/raft v1.2.0/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= -github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk= -github.com/hashicorp/raft-boltdb v0.0.0-20191021154308-4207f1bf0617 h1:CJDRE/2tBNFOrcoexD2nvTRbQEox3FDxl4NxIezp1b8= -github.com/hashicorp/raft-boltdb v0.0.0-20191021154308-4207f1bf0617/go.mod h1:aUF6HQr8+t3FC/ZHAC+pZreUBhTaxumuu3L+d37uRxk= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg= +github.com/jonboulle/clockwork v0.3.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.14.4 h1:eijASRJcobkVtSt81Olfh7JX43osYLwy5krOJo6YEu4= github.com/klauspost/cpuid/v2 v2.0.6 h1:dQ5ueTiftKxp0gyjKSx5+8BtPWkyQbd95m8Gys/RarI= github.com/klauspost/cpuid/v2 v2.0.6/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/reedsolomon v1.9.13 h1:Xr0COKf7F0ACTXUNnz2ZFCWlUKlUTAUX3y7BODdUxqU= github.com/klauspost/reedsolomon v1.9.13/go.mod h1:eqPAcE7xar5CIzcdfwydOEdcmchAKAP/qs14y4GCBOk= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/nats-io/jwt v0.3.2 h1:+RB5hMpXUUA2dfxuhBTEkMOrYmM+gKIZYS1KjSostMI= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats.go v1.10.0 h1:L8qnKaofSfNFbXg0C5F71LdjPRnmQwSsA4ukmkt1TvY= -github.com/nats-io/nats.go v1.10.0/go.mod h1:AjGArbfyR50+afOUotNX2Xs5SYHf+CoOa5HH1eEl2HE= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.4 h1:aEsHIssIk6ETN5m2/MD8Y4B2X7FfXrBAUdkyRvbVYzA= -github.com/nats-io/nkeys v0.1.4/go.mod h1:XdZpAbhgyyODYqjTawOnIOI7VlbKSarI9Gfy1tqEu/s= +github.com/nats-io/jwt/v2 v2.2.1-0.20220330180145-442af02fd36a h1:lem6QCvxR0Y28gth9P+wV2K/zYUUAkJ+55U8cpS0p5I= +github.com/nats-io/nats-server/v2 v2.8.2 h1:5m1VytMEbZx0YINvKY+X2gXdLNwP43uLXnFRwz8j8KE= +github.com/nats-io/nats-server/v2 v2.8.2/go.mod h1:vIdpKz3OG+DCg4q/xVPdXHoztEyKDWRtykQ4N7hd7C4= +github.com/nats-io/nats.go v1.14.0 h1:/QLCss4vQ6wvDpbqXucsVRDi13tFIR6kTdau+nXzKJw= +github.com/nats-io/nats.go v1.14.0/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w= +github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8= +github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4= github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 h1:PnBWHBf+6L0jOqq0gIVUe6Yk0/QMZ640k6NvkxcBf+8= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a h1:9a8MnZMP0X2nLJdBg+pBmGgkJlSaKC2KaQmTCk1XDtE= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= +github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE= github.com/tealeg/xlsx v1.0.5/go.mod h1:btRS8dz54TDnvKNosuAqxrM1QgN1udgk9O34bDCnORM= github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 h1:89CEmDvlq/F7SJEOqkIdNDGJXrQIhuIx9D2DBXjavSU= @@ -120,78 +139,116 @@ github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b h1:fj5tQ8acgNUr6O8LE github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4= github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho= github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= +github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xtaci/kcp-go v4.3.4+incompatible h1:T56s9GLhx+KZUn5T8aO2Didfa4uTYvjeVIRLt6uYdhE= github.com/xtaci/kcp-go v4.3.4+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg= +go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v3.3.17+incompatible h1:g8iRku1SID8QAW8cDlV0L/PkZlw63LSiYEHYHoE6j/s= go.etcd.io/etcd v3.3.17+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM= -golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee h1:4yd7jl+vXjalO5ztz6Vc1VADv+S/80LGJmyl1ROJ2AI= golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd h1:XcWmESyNjXJMLahc3mqVQJcgSTDxFxhETVlfk9uGc38= +golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191027233614-53de4c7853b5 h1:IX2aat8xHKk1JAYuDPcTTEMfRaGQh2eHrTcrlp3KJi0= -golang.org/x/net v0.0.0-20191027233614-53de4c7853b5/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201010224723-4f7140c49acb h1:mUVeFHoDKis5nxCAzoAi7E8Ghb86EXh/RK6wtvJIqRY= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9 h1:0qxwC5n+ttVOINCBeRHO0nq9X7uy8SDsPoi5OaCdIEI= +golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed h1:uPxWBzB3+mlnjy9W58qY1j/cjyFjutgw/Vhan2zLy/A= -golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220111092808-5a964db01320 h1:0jf+tOCoZ3LyutmCOWpVni1chK4VfFLhRsDK7MhqGRY= +golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w= +golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200428115010-c45acf45369a h1:ykRcNp3dotYGpAEIYeWCGaefklVjVy/rnSvM3zNh6j8= -google.golang.org/genproto v0.0.0-20200428115010-c45acf45369a/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884 h1:fiNLklpBwWK1mth30Hlwk+fcdBmIALlgF5iy77O37Ig= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= @@ -199,12 +256,18 @@ google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscL google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/network/Isocket.go b/network/Isocket.go index 0d13b7f2..6c0cafe8 100644 --- a/network/Isocket.go +++ b/network/Isocket.go @@ -50,7 +50,7 @@ type ( sendTimes int receiveTimes int - packetFuncList *vector.Vector //call back + packetFuncList *vector.Vector[PacketFunc] //call back isHalf bool halfSize int @@ -104,7 +104,7 @@ func WithKcp() OpOption { func (this *Socket) Init(ip string, port int, params ...OpOption) bool { op := &Op{} op.applyOpts(params) - this.packetFuncList = vector.NewVector() + this.packetFuncList = &vector.Vector[PacketFunc]{} this.SetState(SSF_NULL) this.receiveBufferSize = 1024 this.connectType = SERVER_CONNECT @@ -219,7 +219,7 @@ func (this *Socket) CallMsg(head rpc.RpcHead, funcName string, params ...interfa func (this *Socket) HandlePacket(buff []byte) { packet := rpc.Packet{Id: this.clientId, Buff: buff} for _, v := range this.packetFuncList.Values() { - if v.(PacketFunc)(packet) { + if v(packet) { break } } diff --git a/orm/mongodb/example_test.go b/orm/mongodb/example_test.go index 1be3f0af..b4407bc9 100644 --- a/orm/mongodb/example_test.go +++ b/orm/mongodb/example_test.go @@ -1,5 +1,5 @@ package mongodb_test - +/* import ( "fmt" "gonet/orm/mongodb" @@ -46,4 +46,5 @@ func Example() { // 1 // 2 // 3 -} \ No newline at end of file +} +*/ \ No newline at end of file diff --git a/orm/mongodb/mongodb.go b/orm/mongodb/mongodb.go index 09c1c2c9..8f547e72 100644 --- a/orm/mongodb/mongodb.go +++ b/orm/mongodb/mongodb.go @@ -1,5 +1,5 @@ package mongodb - +/* import ( "container/heap" "gopkg.in/mgo.v2" @@ -181,4 +181,4 @@ func (c *DialContext) EnsureUniqueIndex(db string, collection string, key []stri Unique: true, Sparse: true, }) -} \ No newline at end of file +}*/ \ No newline at end of file