diff --git a/cmd/mtredisalize/leveldb.go b/cmd/mtredisalize/leveldb.go index 23c8109..f8ede70 100644 --- a/cmd/mtredisalize/leveldb.go +++ b/cmd/mtredisalize/leveldb.go @@ -14,11 +14,13 @@ import ( ) type LevelDBBackend struct { - cache *leveldb.Cache - db *leveldb.DB - interleaved bool - encoder common.KeyTranscoder - decoder common.KeyTranscoder + cache *leveldb.Cache + db *leveldb.DB + interleaved bool + coverage *common.Coverage3D + encoder common.KeyTranscoder + decoder common.KeyTranscoder + changeTracker *ChangeTracker mutex sync.RWMutex } @@ -71,9 +73,42 @@ func NewLeveDBBackend( encoder: encoder, decoder: decoder, changeTracker: changeTracker} + + if !interleaved { + if err = ldb.buildCoverage(); err != nil { + ldb.Shutdown() + ldb = nil + return + } + } return } +func (ldb *LevelDBBackend) buildCoverage() error { + log.Println("INFO: Start building coverage index (this may take some time)...") + + coverage := common.NewCoverage3D() + + ro := leveldb.NewReadOptions() + defer ro.Close() + ro.SetFillCache(false) + it := ldb.db.NewIterator(ro) + it.SeekToFirst() + for ; it.Valid(); it.Next() { + c, err := common.DecodeStringBytesToCoord(it.Key()) + if err != nil { + return err + } + coverage.Insert(c) + } + if err := it.GetError(); err != nil { + return err + } + ldb.coverage = coverage + log.Println("INFO: Finished building coverage index.") + return nil +} + func (ldb *LevelDBBackend) doRead(f func(db *leveldb.DB)) { ldb.mutex.RLock() f(ldb.db) @@ -156,6 +191,13 @@ func (ldbs *LevelDBSession) Store(hash, key, value []byte) (exists bool, err err }) // This technically too early because this done in transactions // which are commited (and possible fail) later. + if ldbs.backend.coverage != nil { + c, err := common.DecodeStringBytesToCoord(origKey) + if err != nil { + return false, err + } + ldbs.backend.coverage.Insert(c) + } if ldbs.backend.changeTracker != nil { ldbs.backend.changeTracker.BlockChanged(origKey) }