diff --git a/c_level_db.go b/c_level_db.go index 6c87c294..33a78009 100644 --- a/c_level_db.go +++ b/c_level_db.go @@ -106,6 +106,24 @@ func (db *CLevelDB) Print() { } } +func (db *CLevelDB) Stats() map[string]string { + // TODO: Find the available properties for the C LevelDB implementation + keys := []string{} + + stats := make(map[string]string) + for _, key := range keys { + str, err := db.db.GetProperty(key) + if err == nil { + stats[key] = str + } + } + return stats +} + +func (db *CLevelDB) Iterator() Iterator { + return db.db.NewIterator(nil, nil) +} + func (db *CLevelDB) NewBatch() Batch { batch := levigo.NewWriteBatch() return &cLevelDBBatch{db, batch} diff --git a/db.go b/db.go index 8ab1c43b..b8849909 100644 --- a/db.go +++ b/db.go @@ -13,6 +13,8 @@ type DB interface { // For debugging Print() + Iterator() Iterator + Stats() map[string]string } type Batch interface { @@ -21,6 +23,13 @@ type Batch interface { Write() } +type Iterator interface { + Next() bool + + Key() []byte + Value() []byte +} + //----------------------------------------------------------------------------- const ( diff --git a/go_level_db.go b/go_level_db.go index a16c5d9e..1b4a937c 100644 --- a/go_level_db.go +++ b/go_level_db.go @@ -82,6 +82,9 @@ func (db *GoLevelDB) Close() { } func (db *GoLevelDB) Print() { + str, _ := db.db.GetProperty("leveldb.stats") + fmt.Printf("%v\n", str) + iter := db.db.NewIterator(nil, nil) for iter.Next() { key := iter.Key() @@ -90,6 +93,32 @@ func (db *GoLevelDB) Print() { } } +func (db *GoLevelDB) Stats() map[string]string { + keys := []string{ + "leveldb.num-files-at-level{n}", + "leveldb.stats", + "leveldb.sstables", + "leveldb.blockpool", + "leveldb.cachedblock", + "leveldb.openedtables", + "leveldb.alivesnaps", + "leveldb.aliveiters", + } + + stats := make(map[string]string) + for _, key := range keys { + str, err := db.db.GetProperty(key) + if err == nil { + stats[key] = str + } + } + return stats +} + +func (db *GoLevelDB) Iterator() Iterator { + return db.db.NewIterator(nil, nil) +} + func (db *GoLevelDB) NewBatch() Batch { batch := new(leveldb.Batch) return &goLevelDBBatch{db, batch} diff --git a/mem_db.go b/mem_db.go index eb1e54b5..28662429 100644 --- a/mem_db.go +++ b/mem_db.go @@ -65,6 +65,53 @@ func (db *MemDB) Print() { } } +func (db *MemDB) Stats() map[string]string { + stats := make(map[string]string) + stats["database.type"] = "memDB" + return stats +} + +type memDBIterator struct { + last int + keys []string + db *MemDB +} + +func newMemDBIterator() *memDBIterator { + return &memDBIterator{} +} + +func (it *memDBIterator) Next() bool { + if it.last >= len(it.keys) { + return false + } + it.last++ + return true +} + +func (it *memDBIterator) Key() []byte { + return []byte(it.keys[it.last]) +} + +func (it *memDBIterator) Value() []byte { + return it.db.Get(it.Key()) +} + +func (db *MemDB) Iterator() Iterator { + it := newMemDBIterator() + it.db = db + it.last = -1 + + db.mtx.Lock() + defer db.mtx.Unlock() + + // unfortunately we need a copy of all of the keys + for key, _ := range db.db { + it.keys = append(it.keys, key) + } + return it +} + func (db *MemDB) NewBatch() Batch { return &memDBBatch{db, nil} }