arnaucube
arnaucube/asmtPublic Self-hosted repository
asmt/trie_cache.go
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/aergoio/aergo-lib/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}