From 6a87c88d1682ebdaa921b7c2ecca857823913336 Mon Sep 17 00:00:00 2001 From: qishenonly <1050026498@qq.com> Date: Thu, 6 Jul 2023 17:06:53 +0800 Subject: [PATCH] fix some bug with hashmap --- engine/index/hashmap.go | 347 ++++++++++++++++++++-------------------- go.mod | 1 - go.sum | 2 - 3 files changed, 174 insertions(+), 176 deletions(-) diff --git a/engine/index/hashmap.go b/engine/index/hashmap.go index a2c54732..c6011f46 100644 --- a/engine/index/hashmap.go +++ b/engine/index/hashmap.go @@ -1,175 +1,176 @@ package index -import ( - "bytes" - "sort" - "sync" - - "github.com/ByteStorage/FlyDB/engine/data" - "github.com/cornelk/hashmap" -) - -/* -hashmap index, encapsulates the hashmap library of cornelk -*/ - -// HashMap struct -type HashMap struct { - hashmap *hashmap.Map[string, *data.LogRecordPst] - // To ensure Thread safety - // multi thread writes need to be locked - lock *sync.RWMutex -} - -// NewHashMap create a hashmap index -func NewHashMap() *HashMap { - return &HashMap{ - hashmap: hashmap.New[string, *data.LogRecordPst](), - lock: new(sync.RWMutex), - } -} - -// Implement the methods of the index interface -// Put stores the data location information of key into the index -func (hm *HashMap) Put(key []byte, pst *data.LogRecordPst) bool { - hm.lock.Lock() - defer hm.lock.Unlock() - - hm.hashmap.Set(string(key), pst) - return true -} - -// Get gains the data location of the key in the index -func (hm *HashMap) Get(key []byte) *data.LogRecordPst { - value, ok := hm.hashmap.Get(string(key)) - if !ok { - return nil - } - return value -} - -// Delete deletes data location of one key in index -func (hm *HashMap) Delete(key []byte) bool { - hm.lock.Lock() - hm.lock.Unlock() - - return hm.hashmap.Del(string(key)) -} - -// Size returns the size of the data in index -func (hm *HashMap) Size() int { - return hm.hashmap.Len() -} - -// Iterator returns a index Iterator -func (hm *HashMap) Iterator(reverse bool) Iterator { - // if the HashMap is empty, returns a default iterator - if hm.hashmap == nil { - return NewDefaultHashMapIterator(reverse) - } - hm.lock.RLock() - defer hm.lock.RUnlock() - // if the HashMap is not empty, returns a iterator - return NewHashMapIterator(hm.hashmap, reverse) -} - -// HashMapIterator struct -type HashMapIterator struct { - currIndex int // The subscript position of the current traversal - reverse bool // Whether it is reverse traversal - values []*Item // Key + Location index information -} - -// create a default HashMap Iterator for the empty HashMap -func NewDefaultHashMapIterator(reverse bool) *HashMapIterator { - return &HashMapIterator{ - currIndex: 0, - reverse: reverse, - values: nil, - } -} - -// create a HashMapIterator -func NewHashMapIterator(hm *hashmap.Map[string, *data.LogRecordPst], reverse bool) *HashMapIterator { - // Use values slice to store all data in values - values := make([]*Item, hm.Len()) - - // count the number of elements in the values slice - var count int = 0 - // store all data into an slice values - // We use range() method in the hashmap implement to do this - // define an operator method - saveFunc := func(key string, value *data.LogRecordPst) bool { - count++ - item := &Item{ - key: []byte(key), - pst: value, - } - values = append(values, item) - return true - } - // call range() method - hm.Range(saveFunc) - - // filter out nil values - values = values[count:] - - // if reverse needed, reverse the slice - if reverse { - for i, j := 0, len(values)-1; i < j; i, j = i+1, j-1 { - values[i], values[j] = values[j], values[i] - } - } - - return &HashMapIterator{ - currIndex: 0, - reverse: reverse, - values: values, - } -} - -// Rewind goes back to the begining of the Iterator,ie. the index of the first data -func (hmIt *HashMapIterator) Rewind() { - hmIt.currIndex = 0 -} - -// Seek finds a >= or <= target key according to the incoming key, -// and starts traversing from this target key -func (hmIt *HashMapIterator) Seek(key []byte) { - if hmIt.reverse { - hmIt.currIndex = sort.Search(len(hmIt.values), func(i int) bool { - return bytes.Compare(hmIt.values[i].key, key) <= 0 - }) - } else { - hmIt.currIndex = sort.Search(len(hmIt.values), func(i int) bool { - return bytes.Compare(hmIt.values[i].key, key) >= 0 - }) - } -} - -// Next jumps to the next key -func (hmIt *HashMapIterator) Next() { - hmIt.currIndex += 1 -} - -// Valid refers to whether it is valid, that is, -// whether all keys have been traversed, -// used to exit the traverse ==> true->yes false-->no -func (hmIt *HashMapIterator) Valid() bool { - return hmIt.currIndex < len(hmIt.values) -} - -// Key returns the key data at the current traversal position -func (hmIt *HashMapIterator) Key() []byte { - return hmIt.values[hmIt.currIndex].key -} - -// Value returns the value data of the current traversal position -func (hmIt *HashMapIterator) Value() *data.LogRecordPst { - return hmIt.values[hmIt.currIndex].pst -} - -// Close closes the iterator and releases the corresponding resources -func (hmIt *HashMapIterator) Close() { - hmIt.values = nil -} +// +//import ( +// "bytes" +// "sort" +// "sync" +// +// "github.com/ByteStorage/FlyDB/engine/data" +// "github.com/cornelk/hashmap" +//) +// +///* +//hashmap index, encapsulates the hashmap library of cornelk +//*/ +// +//// HashMap struct +//type HashMap struct { +// hashmap *hashmap.Map[string, *data.LogRecordPst] +// // To ensure Thread safety +// // multi thread writes need to be locked +// lock *sync.RWMutex +//} +// +//// NewHashMap create a hashmap index +//func NewHashMap() *HashMap { +// return &HashMap{ +// hashmap: hashmap.New[string, *data.LogRecordPst](), +// lock: new(sync.RWMutex), +// } +//} +// +//// Implement the methods of the index interface +//// Put stores the data location information of key into the index +//func (hm *HashMap) Put(key []byte, pst *data.LogRecordPst) bool { +// hm.lock.Lock() +// defer hm.lock.Unlock() +// +// hm.hashmap.Set(string(key), pst) +// return true +//} +// +//// Get gains the data location of the key in the index +//func (hm *HashMap) Get(key []byte) *data.LogRecordPst { +// value, ok := hm.hashmap.Get(string(key)) +// if !ok { +// return nil +// } +// return value +//} +// +//// Delete deletes data location of one key in index +//func (hm *HashMap) Delete(key []byte) bool { +// hm.lock.Lock() +// hm.lock.Unlock() +// +// return hm.hashmap.Del(string(key)) +//} +// +//// Size returns the size of the data in index +//func (hm *HashMap) Size() int { +// return hm.hashmap.Len() +//} +// +//// Iterator returns a index Iterator +//func (hm *HashMap) Iterator(reverse bool) Iterator { +// // if the HashMap is empty, returns a default iterator +// if hm.hashmap == nil { +// return NewDefaultHashMapIterator(reverse) +// } +// hm.lock.RLock() +// defer hm.lock.RUnlock() +// // if the HashMap is not empty, returns a iterator +// return NewHashMapIterator(hm.hashmap, reverse) +//} +// +//// HashMapIterator struct +//type HashMapIterator struct { +// currIndex int // The subscript position of the current traversal +// reverse bool // Whether it is reverse traversal +// values []*Item // Key + Location index information +//} +// +//// create a default HashMap Iterator for the empty HashMap +//func NewDefaultHashMapIterator(reverse bool) *HashMapIterator { +// return &HashMapIterator{ +// currIndex: 0, +// reverse: reverse, +// values: nil, +// } +//} +// +//// create a HashMapIterator +//func NewHashMapIterator(hm *hashmap.Map[string, *data.LogRecordPst], reverse bool) *HashMapIterator { +// // Use values slice to store all data in values +// values := make([]*Item, hm.Len()) +// +// // count the number of elements in the values slice +// var count int = 0 +// // store all data into an slice values +// // We use range() method in the hashmap implement to do this +// // define an operator method +// saveFunc := func(key string, value *data.LogRecordPst) bool { +// count++ +// item := &Item{ +// key: []byte(key), +// pst: value, +// } +// values = append(values, item) +// return true +// } +// // call range() method +// hm.Range(saveFunc) +// +// // filter out nil values +// values = values[count:] +// +// // if reverse needed, reverse the slice +// if reverse { +// for i, j := 0, len(values)-1; i < j; i, j = i+1, j-1 { +// values[i], values[j] = values[j], values[i] +// } +// } +// +// return &HashMapIterator{ +// currIndex: 0, +// reverse: reverse, +// values: values, +// } +//} +// +//// Rewind goes back to the begining of the Iterator,ie. the index of the first data +//func (hmIt *HashMapIterator) Rewind() { +// hmIt.currIndex = 0 +//} +// +//// Seek finds a >= or <= target key according to the incoming key, +//// and starts traversing from this target key +//func (hmIt *HashMapIterator) Seek(key []byte) { +// if hmIt.reverse { +// hmIt.currIndex = sort.Search(len(hmIt.values), func(i int) bool { +// return bytes.Compare(hmIt.values[i].key, key) <= 0 +// }) +// } else { +// hmIt.currIndex = sort.Search(len(hmIt.values), func(i int) bool { +// return bytes.Compare(hmIt.values[i].key, key) >= 0 +// }) +// } +//} +// +//// Next jumps to the next key +//func (hmIt *HashMapIterator) Next() { +// hmIt.currIndex += 1 +//} +// +//// Valid refers to whether it is valid, that is, +//// whether all keys have been traversed, +//// used to exit the traverse ==> true->yes false-->no +//func (hmIt *HashMapIterator) Valid() bool { +// return hmIt.currIndex < len(hmIt.values) +//} +// +//// Key returns the key data at the current traversal position +//func (hmIt *HashMapIterator) Key() []byte { +// return hmIt.values[hmIt.currIndex].key +//} +// +//// Value returns the value data of the current traversal position +//func (hmIt *HashMapIterator) Value() *data.LogRecordPst { +// return hmIt.values[hmIt.currIndex].pst +//} +// +//// Close closes the iterator and releases the corresponding resources +//func (hmIt *HashMapIterator) Close() { +// hmIt.values = nil +//} diff --git a/go.mod b/go.mod index b1b9c70b..f17b7f28 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module github.com/ByteStorage/FlyDB go 1.18 require ( - github.com/cornelk/hashmap v1.0.8 github.com/desertbit/grumble v1.1.3 github.com/fatih/color v1.13.0 github.com/google/btree v1.1.2 diff --git a/go.sum b/go.sum index 897ea4a3..4466a395 100644 --- a/go.sum +++ b/go.sum @@ -23,8 +23,6 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWs github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 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/cornelk/hashmap v1.0.8 h1:nv0AWgw02n+iDcawr5It4CjQIAcdMMKRrs10HOJYlrc= -github.com/cornelk/hashmap v1.0.8/go.mod h1:RfZb7JO3RviW/rT6emczVuC/oxpdz4UsSB2LJSclR1k= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=