Node deletion while iterating
bmfs opened this issue · 1 comments
bmfs commented
Noticed that while using a NodeKeyIteration, If nodes were deleted the iterator misses some results.
Is this expected?
An example:
package main
import (
"fmt"
"devt.de/krotik/eliasdb/graph"
"devt.de/krotik/eliasdb/graph/data"
"devt.de/krotik/eliasdb/graph/graphstorage"
)
func main() {
TestNodeDeletion()
}
func TestNodeDeletion() {
gs := graphstorage.NewMemoryGraphStorage("memdb")
gm := graph.NewGraphManager(gs)
nodeA1 := data.NewGraphNode()
nodeA1.SetAttr(data.NodeKey, "nodeA1")
nodeA1.SetAttr(data.NodeKind, "typeA")
nodeA2 := data.NewGraphNode()
nodeA2.SetAttr(data.NodeKey, "nodeA2")
nodeA2.SetAttr(data.NodeKind, "typeA")
nodeA3 := data.NewGraphNode()
nodeA3.SetAttr(data.NodeKey, "nodeA3")
nodeA3.SetAttr(data.NodeKind, "typeA")
nodeA4 := data.NewGraphNode()
nodeA4.SetAttr(data.NodeKey, "nodeA4")
nodeA4.SetAttr(data.NodeKind, "typeA")
gm.StoreNode("main", nodeA1)
gm.StoreNode("main", nodeA2)
gm.StoreNode("main", nodeA3)
gm.StoreNode("main", nodeA4)
fmt.Printf("Node Count: %d\n", gm.NodeCount("typeA"))
it, _ := gm.NodeKeyIterator("main", "typeA")
if it != nil {
for it.HasNext() {
key := it.Next()
fmt.Printf("-- Node key = %s lastError = %v\n", key, it.LastError)
if it.LastError != nil {
break
}
gm.RemoveNode("main", key, "typeA")
}
}
fmt.Printf("Node Count: %d\n", gm.NodeCount("typeA"))
}
krotik commented
The iterator uses the underlying H-Tree structure - this structure is changed when nodes get deleted. So, unfortunately, the behavior which you observed is expected. A better way to do this would be with a transaction (graph.NewGraphTrans) - this would also be significantly faster.