cache.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. package trie
  2. import (
  3. "github.com/ethereum/go-ethereum/compression/rle"
  4. "github.com/ethereum/go-ethereum/ethdb"
  5. "github.com/ethereum/go-ethereum/logger/glog"
  6. "github.com/syndtr/goleveldb/leveldb"
  7. )
  8. type Backend interface {
  9. Get([]byte) ([]byte, error)
  10. Put([]byte, []byte) error
  11. }
  12. type Cache struct {
  13. batch *leveldb.Batch
  14. store map[string][]byte
  15. backend Backend
  16. }
  17. func NewCache(backend Backend) *Cache {
  18. return &Cache{new(leveldb.Batch), make(map[string][]byte), backend}
  19. }
  20. func (self *Cache) Get(key []byte) []byte {
  21. data := self.store[string(key)]
  22. if data == nil {
  23. data, _ = self.backend.Get(key)
  24. }
  25. return data
  26. }
  27. func (self *Cache) Put(key []byte, data []byte) {
  28. // write the data to the ldb batch
  29. self.batch.Put(key, rle.Compress(data))
  30. self.store[string(key)] = data
  31. }
  32. // Flush flushes the trie to the backing layer. If this is a leveldb instance
  33. // we'll use a batched write, otherwise we'll use regular put.
  34. func (self *Cache) Flush() {
  35. if db, ok := self.backend.(*ethdb.LDBDatabase); ok {
  36. if err := db.LDB().Write(self.batch, nil); err != nil {
  37. glog.Fatal("db write err:", err)
  38. }
  39. } else {
  40. for k, v := range self.store {
  41. self.backend.Put([]byte(k), v)
  42. }
  43. }
  44. }
  45. func (self *Cache) Copy() *Cache {
  46. cache := NewCache(self.backend)
  47. for k, v := range self.store {
  48. cache.store[k] = v
  49. }
  50. return cache
  51. }
  52. func (self *Cache) Reset() {
  53. //self.store = make(map[string][]byte)
  54. }