@@ -29,13 +29,16 @@ package dtrie
2929import (
3030 "fmt"
3131 "sync"
32+
33+ // TODO change to "github.com/Workiva/go-datastructures/bitarray"
34+ "github.com/theodus/go-datastructures/bitarray"
3235)
3336
3437type node struct {
3538 entries []Entry
36- nodeMap uint32
37- dataMap uint32
38- level uint32 // level starts at 0
39+ nodeMap bitarray. Bitmap32
40+ dataMap bitarray. Bitmap32
41+ level uint8 // level starts at 0
3942}
4043
4144func (n * node ) KeyHash () uint32 { return 0 }
@@ -65,20 +68,20 @@ type Entry interface {
6568 Value () interface {}
6669}
6770
68- func emptyNode (level uint32 , capacity int ) * node {
71+ func emptyNode (level uint8 , capacity int ) * node {
6972 return & node {entries : make ([]Entry , capacity ), level : level }
7073}
7174
7275func insert (n * node , entry Entry ) * node {
73- index := mask (entry .KeyHash (), n .level )
76+ index := uint ( mask (entry .KeyHash (), n .level ) )
7477 newNode := n
7578 if newNode .level == 6 { // handle hash collisions on 6th level
7679 if newNode .entries [index ] == nil {
7780 newNode .entries [index ] = entry
78- newNode .dataMap = setBit ( newNode .dataMap , index )
81+ newNode .dataMap = newNode .dataMap . SetBit ( index )
7982 return newNode
8083 }
81- if hasBit ( newNode .dataMap , index ) {
84+ if newNode .dataMap . HasBit ( index ) {
8285 if newNode .entries [index ].Key () == entry .Key () {
8386 newNode .entries [index ] = entry
8487 return newNode
@@ -87,48 +90,48 @@ func insert(n *node, entry Entry) *node {
8790 cNode .entries [0 ] = newNode .entries [index ]
8891 cNode .entries [1 ] = entry
8992 newNode .entries [index ] = cNode
90- newNode .dataMap = clearBit ( newNode .dataMap , index )
93+ newNode .dataMap = newNode .dataMap . ClearBit ( index )
9194 return newNode
9295 }
9396 cNode := newNode .entries [index ].(* collisionNode )
9497 cNode .entries = append (cNode .entries , entry )
9598 return newNode
9699 }
97- if ! hasBit ( newNode .dataMap , index ) && ! hasBit ( newNode .nodeMap , index ) { // insert directly
100+ if ! newNode .dataMap . HasBit ( index ) && ! newNode .nodeMap . HasBit ( index ) { // insert directly
98101 newNode .entries [index ] = entry
99- newNode .dataMap = setBit ( newNode .dataMap , index )
102+ newNode .dataMap = newNode .dataMap . SetBit ( index )
100103 return newNode
101104 }
102- if hasBit ( newNode .nodeMap , index ) { // insert into sub-node
105+ if newNode .nodeMap . HasBit ( index ) { // insert into sub-node
103106 newNode .entries [index ] = insert (newNode .entries [index ].(* node ), entry )
104107 return newNode
105108 }
106109 if newNode .entries [index ].Key () == entry .Key () {
107110 newNode .entries [index ] = entry
108111 return newNode
109112 }
110- // create new node with the new and exisiting entries
113+ // create new node with the new and existing entries
111114 var subNode * node
112- if newNode .level == 5 { // only 2 bits left at level 6 (4 possible indicies )
115+ if newNode .level == 5 { // only 2 bits left at level 6 (4 possible indices )
113116 subNode = emptyNode (newNode .level + 1 , 4 )
114117 } else {
115118 subNode = emptyNode (newNode .level + 1 , 32 )
116119 }
117120 subNode = insert (subNode , newNode .entries [index ])
118121 subNode = insert (subNode , entry )
119- newNode .dataMap = clearBit ( newNode .dataMap , index )
120- newNode .nodeMap = setBit ( newNode .nodeMap , index )
122+ newNode .dataMap = newNode .dataMap . ClearBit ( index )
123+ newNode .nodeMap = newNode .nodeMap . SetBit ( index )
121124 newNode .entries [index ] = subNode
122125 return newNode
123126}
124127
125128// returns nil if not found
126129func get (n * node , keyHash uint32 , key interface {}) Entry {
127- index := mask (keyHash , n .level )
128- if hasBit ( n .dataMap , index ) {
130+ index := uint ( mask (keyHash , n .level ) )
131+ if n .dataMap . HasBit ( index ) {
129132 return n .entries [index ]
130133 }
131- if hasBit ( n .nodeMap , index ) {
134+ if n .nodeMap . HasBit ( index ) {
132135 return get (n .entries [index ].(* node ), keyHash , key )
133136 }
134137 if n .level == 6 { // get from collisionNode
@@ -146,28 +149,28 @@ func get(n *node, keyHash uint32, key interface{}) Entry {
146149}
147150
148151func remove (n * node , keyHash uint32 , key interface {}) * node {
149- index := mask (keyHash , n .level )
152+ index := uint ( mask (keyHash , n .level ) )
150153 newNode := n
151- if hasBit ( n .dataMap , index ) {
154+ if n .dataMap . HasBit ( index ) {
152155 newNode .entries [index ] = nil
153- newNode .dataMap = clearBit ( newNode .dataMap , index )
156+ newNode .dataMap = newNode .dataMap . ClearBit ( index )
154157 return newNode
155158 }
156- if hasBit ( n .nodeMap , index ) {
159+ if n .nodeMap . HasBit ( index ) {
157160 subNode := newNode .entries [index ].(* node )
158161 subNode = remove (subNode , keyHash , key )
159162 // compress if only 1 entry exists in sub-node
160- if popCount ( subNode .nodeMap ) == 0 && popCount ( subNode .dataMap ) == 1 {
163+ if subNode .nodeMap . PopCount ( ) == 0 && subNode .dataMap . PopCount ( ) == 1 {
161164 var e Entry
162- for i := uint32 (0 ); i < 32 ; i ++ {
163- if hasBit ( subNode .dataMap , i ) {
165+ for i := uint (0 ); i < 32 ; i ++ {
166+ if subNode .dataMap . HasBit ( i ) {
164167 e = subNode .entries [i ]
165168 break
166169 }
167170 }
168171 newNode .entries [index ] = e
169- newNode .nodeMap = clearBit ( newNode .nodeMap , index )
170- newNode .dataMap = setBit ( newNode .dataMap , index )
172+ newNode .nodeMap = newNode .nodeMap . ClearBit ( index )
173+ newNode .dataMap = newNode .dataMap . SetBit ( index )
171174 }
172175 newNode .entries [index ] = subNode
173176 return newNode
@@ -183,7 +186,7 @@ func remove(n *node, keyHash uint32, key interface{}) *node {
183186 // compress if only 1 entry exists in collisionNode
184187 if len (cNode .entries ) == 1 {
185188 newNode .entries [index ] = cNode .entries [0 ]
186- newNode .dataMap = setBit ( newNode .dataMap , index )
189+ newNode .dataMap = newNode .dataMap . SetBit ( index )
187190 }
188191 return newNode
189192 }
@@ -206,11 +209,11 @@ func pushEntries(n *node, stop <-chan struct{}, out chan Entry) {
206209 case <- stop :
207210 return
208211 default :
209- index := uint32 (i )
212+ index := uint (i )
210213 switch {
211- case hasBit ( n .dataMap , index ):
214+ case n .dataMap . HasBit ( index ):
212215 out <- e
213- case hasBit ( n .nodeMap , index ):
216+ case n .nodeMap . HasBit ( index ):
214217 wg .Add (1 )
215218 go func () {
216219 defer wg .Done ()
0 commit comments