From 002f90f016fcc6edc62132f497958635102c0b46 Mon Sep 17 00:00:00 2001 From: lim-yoona <1994238842@qq.com> Date: Thu, 6 Jul 2023 15:51:28 +0800 Subject: [PATCH] update AddHashMapIndex --- engine/index/hashmap.go | 34 ++++++++++++++++++++++++---------- engine/index/hashmap_test.go | 4 +++- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/engine/index/hashmap.go b/engine/index/hashmap.go index cf98f6cb..a2c54732 100644 --- a/engine/index/hashmap.go +++ b/engine/index/hashmap.go @@ -63,12 +63,14 @@ func (hm *HashMap) Size() int { // 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 nil + return NewDefaultHashMapIterator(reverse) } hm.lock.RLock() defer hm.lock.RUnlock() - return NewHashMapIterator(hm, reverse) + // if the HashMap is not empty, returns a iterator + return NewHashMapIterator(hm.hashmap, reverse) } // HashMapIterator struct @@ -78,19 +80,27 @@ type HashMapIterator struct { values []*Item // Key + Location index information } -// create a HashMapIterator -func NewHashMapIterator(hm *HashMap, reverse bool) *HashMapIterator { - // if the HashMap is empty, returns a nil HashMapIterator - // to avoid making a nil slice values - if hm.Size() == 0 { - return nil +// create a default HashMap Iterator for the empty HashMap +func NewDefaultHashMapIterator(reverse bool) *HashMapIterator { + return &HashMapIterator{ + currIndex: 0, + reverse: reverse, + values: nil, } - values := make([]*Item, hm.Size()) +} + +// 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, @@ -99,7 +109,11 @@ func NewHashMapIterator(hm *HashMap, reverse bool) *HashMapIterator { return true } // call range() method - hm.hashmap.Range(saveFunc) + 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 { diff --git a/engine/index/hashmap_test.go b/engine/index/hashmap_test.go index 288ca6de..d457a48b 100644 --- a/engine/index/hashmap_test.go +++ b/engine/index/hashmap_test.go @@ -52,13 +52,15 @@ func TestHashMap_Delete(t *testing.T) { } func TestHashMap_Iterator(t *testing.T) { - hm1 := NewBTree() + hm1 := NewHashMap() // 1. HashMap is empty + iter1 := hm1.Iterator(false) assert.Equal(t, false, iter1.Valid()) // 2. HashMap is not empty hm1.Put([]byte("abc"), &data.LogRecordPst{Fid: 1, Offset: 12}) + iter2 := hm1.Iterator(false) assert.True(t, iter2.Valid()) assert.NotNil(t, iter2.Key())