asmt/smt/trie_cache.go
smt/trie_cache.goRaw
1/**
2 * @file
3 * @copyright defined in aergo/LICENSE.txt
4 */
5
6package trie
7
8import (
9 "sync"
10
11 "github.com/p4u/asmt/db"
12)
13
14// DbTx represents Set and Delete interface to store data
15type DbTx interface {
16 Set(key, value []byte)
17 Delete(key []byte)
18}
19
20type CacheDB struct {
21 // liveCache contains the first levels of the trie (nodes that have 2 non default children)
22 liveCache map[Hash][][]byte
23 // liveMux is a lock for liveCache
24 liveMux sync.RWMutex
25 // updatedNodes that have will be flushed to disk
26 updatedNodes map[Hash][][]byte
27 // updatedMux is a lock for updatedNodes
28 updatedMux sync.RWMutex
29 // nodesToRevert will be deleted from db
30 nodesToRevert [][]byte
31 // revertMux is a lock for updatedNodes
32 revertMux sync.RWMutex
33 // lock for CacheDB
34 lock sync.RWMutex
35 // store is the interface to disk db
36 Store db.DB
37}
38
39// commit adds updatedNodes to the given database transaction.
40func (c *CacheDB) commit(txn *DbTx) {
41 c.updatedMux.Lock()
42 defer c.updatedMux.Unlock()
43 for key, batch := range c.updatedNodes {
44 var node []byte
45 (*txn).Set(append(node, key[:]...), c.serializeBatch(batch))
46 }
47}
48
49// serializeBatch serialises the 2D [][]byte into a []byte for db
50func (c *CacheDB) serializeBatch(batch [][]byte) []byte {
51 serialized := make([]byte, 4) //, 30*33)
52 if batch[0][0] == 1 {
53 // the batch node is a shortcut
54 bitSet(serialized, 31)
55 }
56 for i := 1; i < 31; i++ {
57 if len(batch[i]) != 0 {
58 bitSet(serialized, i-1)
59 serialized = append(serialized, batch[i]...)
60 }
61 }
62 return serialized
63}