github.com/piotrnar/gocoin@v0.0.0-20240512203912-faa0448c5e96/lib/others/qdb/index.go (about) 1 package qdb 2 3 import ( 4 "os" 5 "io/ioutil" 6 ) 7 8 9 type QdbIndex struct { 10 db *DB 11 IdxFilePath string 12 file *os.File 13 DatfileIndex int 14 VersionSequence uint32 15 MaxDatfileSequence uint32 16 17 Index map[KeyType] *oneIdx 18 19 DiskSpaceNeeded uint64 20 ExtraSpaceUsed uint64 21 } 22 23 func NewDBidx(db *DB, recs uint) (idx *QdbIndex) { 24 idx = new(QdbIndex) 25 idx.db = db 26 idx.IdxFilePath = db.Dir+"qdbidx." 27 if recs==0 { 28 idx.Index = make(map[KeyType] *oneIdx) 29 } else { 30 idx.Index = make(map[KeyType] *oneIdx, recs) 31 } 32 used := make(map[uint32]bool, 10) 33 idx.loaddat(used) 34 idx.loadlog(used) 35 idx.db.cleanupold(used) 36 return 37 } 38 39 40 func (idx *QdbIndex) load(walk QdbWalkFunction) { 41 dats := make(map[uint32] []byte) 42 idx.browse(func(k KeyType, v *oneIdx) bool { 43 if walk!=nil || (v.flags&NO_CACHE)==0 { 44 dat := dats[v.DataSeq] 45 if dat == nil { 46 dat, _ = ioutil.ReadFile(idx.db.seq2fn(v.DataSeq)) 47 if dat==nil { 48 println("Database corrupt - missing file:", idx.db.seq2fn(v.DataSeq)) 49 os.Exit(1) 50 } 51 dats[v.DataSeq] = dat 52 } 53 v.SetData(dat[v.datpos:v.datpos+v.datlen]) 54 if walk!=nil { 55 res := walk(k, v.Slice()) 56 v.aply_browsing_flags(res) 57 v.freerec() 58 } 59 } 60 return true 61 }) 62 } 63 64 65 func (idx *QdbIndex) size() int { 66 return len(idx.Index) 67 } 68 69 70 func (idx *QdbIndex) get(k KeyType) *oneIdx { 71 return idx.Index[k] 72 } 73 74 75 func (idx *QdbIndex) memput(k KeyType, rec *oneIdx) { 76 if prv, ok := idx.Index[k]; ok { 77 prv.FreeData() 78 dif := uint64(24+prv.datlen) 79 if !idx.db.VolatileMode { 80 idx.ExtraSpaceUsed += dif 81 idx.DiskSpaceNeeded -= dif 82 } 83 } 84 idx.Index[k] = rec 85 86 if !idx.db.VolatileMode { 87 idx.DiskSpaceNeeded += uint64(24+rec.datlen) 88 } 89 if rec.DataSeq>idx.MaxDatfileSequence { 90 idx.MaxDatfileSequence = rec.DataSeq 91 } 92 } 93 94 95 func (idx *QdbIndex) memdel(k KeyType) { 96 if cur, ok := idx.Index[k]; ok { 97 cur.FreeData() 98 dif := uint64(12+cur.datlen) 99 if !idx.db.VolatileMode { 100 idx.ExtraSpaceUsed += dif 101 idx.DiskSpaceNeeded -= dif 102 } 103 delete(idx.Index, k) 104 } 105 } 106 107 func (idx *QdbIndex) put(k KeyType, rec *oneIdx) { 108 idx.memput(k, rec) 109 if idx.db.VolatileMode { 110 return 111 } 112 idx.addtolog(nil, k, rec) 113 } 114 115 116 func (idx *QdbIndex) del(k KeyType) { 117 idx.memdel(k) 118 if idx.db.VolatileMode { 119 return 120 } 121 idx.deltolog(nil, k) 122 } 123 124 125 func (idx *QdbIndex) browse(walk func(key KeyType, idx *oneIdx) bool) { 126 for k, v := range idx.Index { 127 if !walk(k, v) { 128 break 129 } 130 } 131 } 132 133 func (idx *QdbIndex) close() { 134 if idx.file!= nil { 135 idx.file.Close() 136 idx.file = nil 137 } 138 idx.Index = nil 139 }