github.com/klaytn/klaytn@v1.12.1/storage/statedb/print_trie_test.go (about) 1 // Copyright 2018 The klaytn Authors 2 // This file is part of the klaytn library. 3 // 4 // The klaytn library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The klaytn library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the klaytn library. If not, see <http://www.gnu.org/licenses/>. 16 17 package statedb 18 19 import ( 20 "fmt" 21 "reflect" 22 "testing" 23 ) 24 25 //////////////////////////////////////////////////////////////////////////////// 26 // Additional member functions of Iterator (defined in iterator.go) 27 //////////////////////////////////////////////////////////////////////////////// 28 func (it *Iterator) NextAny() bool { 29 if it.nodeIt.Next(true) { 30 return true 31 } 32 it.Err = it.nodeIt.Error() 33 return false 34 } 35 36 //////////////////////////////////////////////////////////////////////////////// 37 // Additional member functions of nodeIterator (defined in iterator.go) 38 //////////////////////////////////////////////////////////////////////////////// 39 func (it *nodeIterator) GetType() string { 40 if len(it.stack) == 0 { 41 return "" 42 } 43 return reflect.TypeOf(it.stack[len(it.stack)-1].node).String() 44 } 45 46 func (it *nodeIterator) GetKeyNibbles() (key, key_nibbles string) { 47 k := it.path 48 k = k[:len(k)-(len(k)&1)] 49 50 for i, n := range it.path { 51 if i == len(it.path)-1 && n == 16 { 52 key_nibbles += "T" 53 } else { 54 key_nibbles += indices[n] 55 } 56 } 57 58 return string(hexToKeybytes(k)), key_nibbles 59 } 60 61 //////////////////////////////////////////////////////////////////////////////// 62 // NodeIntMap 63 // 64 // Stores a mapping between node* and int 65 // This is required to make an integer ID of a node object for id in vis.js. 66 //////////////////////////////////////////////////////////////////////////////// 67 type NodeIntMap struct { 68 hashMap map[*node]int 69 counter int 70 } 71 72 func NewHashIntMap() *NodeIntMap { 73 return &NodeIntMap{ 74 hashMap: map[*node]int{}, 75 counter: 1, 76 } 77 } 78 79 func (m *NodeIntMap) Get(h *node) int { 80 if _, ok := m.hashMap[h]; !ok { 81 m.hashMap[h] = m.counter 82 m.counter++ 83 } 84 85 return m.hashMap[h] 86 } 87 88 //////////////////////////////////////////////////////////////////////////////// 89 // VisNode 90 // 91 // Describes a node object in vis.js. 92 //////////////////////////////////////////////////////////////////////////////// 93 type VisNode struct { 94 id int 95 label string 96 level int 97 addr *node 98 str string 99 typename string 100 } 101 102 func (v *VisNode) String() string { 103 return fmt.Sprintf("{id:%d, label:'%s', level:%d, addr:'%p', typename:'%s', x:%d, y:%d}", 104 v.id, v.label, v.level, v.addr, v.typename, v.id, v.id) 105 } 106 107 func SerializeNodes(nodes []VisNode) (ret string) { 108 for _, n := range nodes { 109 ret += fmt.Sprintf("%s, \n", n.String()) 110 } 111 112 return 113 } 114 115 //////////////////////////////////////////////////////////////////////////////// 116 // VisEdge 117 // 118 // Describes an edge object in vis.js. 119 //////////////////////////////////////////////////////////////////////////////// 120 type VisEdge struct { 121 from int 122 to int 123 label string 124 } 125 126 func (e *VisEdge) String() string { 127 return fmt.Sprintf("{from:%d, to:%d, label:'%s'}", e.from, e.to, e.label) 128 } 129 130 func SerializeEdges(edges []VisEdge) (ret string) { 131 for _, e := range edges { 132 ret += fmt.Sprintf("%s, \n", e.String()) 133 } 134 135 return 136 } 137 138 //////////////////////////////////////////////////////////////////////////////// 139 // TestPrintTrie 140 // 141 // You can execute only this test by `go test -run TestPrintTrie` 142 //////////////////////////////////////////////////////////////////////////////// 143 func TestPrintTrie(t *testing.T) { 144 trie := newEmptyTrie() 145 vals := []struct{ k, v string }{ 146 //{"klaytn", "wookiedoo"}, 147 //{"horse", "stallion"}, 148 //{"shaman", "horse"}, 149 //{"doge", "coin"}, 150 //{"dog", "puppy"}, 151 {"do", "verb"}, 152 {"dok", "puppyuyyy"}, 153 {"somethingveryoddindeedthis is", "myothernodedata"}, 154 {"barb", "ba"}, 155 {"bard", "bc"}, 156 {"bars", "bb"}, 157 {"bar", "b"}, 158 {"fab", "z"}, 159 {"food", "ab"}, 160 {"foos", "aa"}, 161 {"foo", "a"}, 162 {"aardvark", "c"}, 163 //{"bar", "b"}, 164 //{"barb", "bd"}, 165 //{"bars", "be"}, 166 //{"fab", "z"}, 167 //{"foo", "a"}, 168 //{"foos", "aa"}, 169 //{"food", "ab"}, 170 {"jars", "d"}, 171 } 172 all := make(map[string]string) 173 for _, val := range vals { 174 all[val.k] = val.v 175 trie.Update([]byte(val.k), []byte(val.v)) 176 } 177 trie.Commit(nil) 178 179 nodeIntMap := NewHashIntMap() 180 var visNodes []VisNode 181 var visEdges []VisEdge 182 183 it := NewIterator(trie.NodeIterator(nil)) 184 for it.NextAny() { 185 nodeIt, _ := it.nodeIt.(*nodeIterator) 186 187 key, key_nibbles := nodeIt.GetKeyNibbles() 188 189 edgeLabel := "" 190 191 myId := nodeIntMap.Get(&nodeIt.stack[len(nodeIt.stack)-1].node) 192 pId := 0 193 if len(nodeIt.stack) > 1 { 194 parent := &nodeIt.stack[len(nodeIt.stack)-2].node 195 pId = nodeIntMap.Get(parent) 196 switch (*parent).(type) { 197 case *fullNode: 198 edgeLabel = key_nibbles[len(key_nibbles)-1:] 199 default: 200 } 201 } 202 203 label := string("ROOT") 204 if len(key_nibbles) > 0 { 205 label = fmt.Sprintf("%s\\n%s", key, key_nibbles) 206 if key_nibbles[len(key_nibbles)-1:] == "T" { 207 label += fmt.Sprintf("\\nValue:%s", string(nodeIt.LeafBlob())) 208 } 209 } 210 211 visNodes = append(visNodes, VisNode{ 212 id: myId, 213 addr: &nodeIt.stack[len(nodeIt.stack)-1].node, 214 str: nodeIt.stack[len(nodeIt.stack)-1].node.fstring("0"), 215 label: label, 216 level: len(nodeIt.stack), 217 typename: nodeIt.GetType(), 218 }) 219 220 if pId > 0 { 221 visEdges = append(visEdges, VisEdge{ 222 from: pId, 223 to: myId, 224 label: edgeLabel, 225 }) 226 } 227 } 228 229 serNodes := SerializeNodes(visNodes) 230 serEdges := SerializeEdges(visEdges) 231 t.Logf("var nodes = new vis.DataSet([%s]);\n", serNodes) 232 t.Logf("var edges = new vis.DataSet([%s]);\n", serEdges) 233 }