From bb8104b6249b4429a0bcde533a2db6e17ca550f0 Mon Sep 17 00:00:00 2001 From: "Paul W. Homer" Date: Fri, 17 Mar 2017 13:27:20 -0400 Subject: [PATCH 1/7] Exposed the LevelDB iterator in the DB struct. --- db.go | 8 ++++++++ go_level_db.go | 9 +++++++++ mem_db.go | 10 ++++++++++ 3 files changed, 27 insertions(+) diff --git a/db.go b/db.go index 8ab1c43be..9cd4e1c21 100644 --- a/db.go +++ b/db.go @@ -12,6 +12,8 @@ type DB interface { NewBatch() Batch // For debugging + Iterator() Iterator + Next(Iterator) (key []byte, value []byte) Print() } @@ -21,6 +23,12 @@ 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 a16c5d9e0..35c380ad8 100644 --- a/go_level_db.go +++ b/go_level_db.go @@ -90,6 +90,15 @@ func (db *GoLevelDB) Print() { } } +func (db *GoLevelDB) Iterator() Iterator { + return db.db.NewIterator(nil, nil) +} + +func (db *GoLevelDB) Next(iter Iterator) ([]byte, []byte) { + iter.Next() + return iter.Key(), iter.Value() +} + func (db *GoLevelDB) NewBatch() Batch { batch := new(leveldb.Batch) return &goLevelDBBatch{db, batch} diff --git a/mem_db.go b/mem_db.go index eb1e54b56..dcd86e6d5 100644 --- a/mem_db.go +++ b/mem_db.go @@ -65,6 +65,16 @@ func (db *MemDB) Print() { } } +// TODO: needs to be wired to range db.db +func (db *MemDB) Iterator() Iterator { + return nil +} + +// TODO: needs to be wired to range db.db +func (db *MemDB) Next(iter Iterator) (key []byte, value []byte) { + return nil, nil +} + func (db *MemDB) NewBatch() Batch { return &memDBBatch{db, nil} } From d6205eb4ca60631dd4abee93cef47d837be66af4 Mon Sep 17 00:00:00 2001 From: "Paul W. Homer" Date: Fri, 17 Mar 2017 14:34:11 -0400 Subject: [PATCH 2/7] Changed the iterations --- go_level_db.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/go_level_db.go b/go_level_db.go index 35c380ad8..3020d4a03 100644 --- a/go_level_db.go +++ b/go_level_db.go @@ -95,8 +95,10 @@ func (db *GoLevelDB) Iterator() Iterator { } func (db *GoLevelDB) Next(iter Iterator) ([]byte, []byte) { - iter.Next() - return iter.Key(), iter.Value() + if iter.Next() { + return iter.Key(), iter.Value() + } + return nil, nil } func (db *GoLevelDB) NewBatch() Batch { From 6064c80250f32dfc55a7bfd6113f4ed87c3fcd97 Mon Sep 17 00:00:00 2001 From: "Paul W. Homer" Date: Thu, 23 Mar 2017 11:37:46 -0400 Subject: [PATCH 3/7] Modified all db types to conform to the interface changes. --- c_level_db.go | 17 +++++++++++++++++ db.go | 5 +++-- go_level_db.go | 32 +++++++++++++++++++++++++------- mem_db.go | 49 +++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 88 insertions(+), 15 deletions(-) diff --git a/c_level_db.go b/c_level_db.go index 6c87c2949..41ed4dc16 100644 --- a/c_level_db.go +++ b/c_level_db.go @@ -106,6 +106,23 @@ func (db *CLevelDB) Print() { } } +func (db *CLevelDB) Stats() map[string]string { + 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 9cd4e1c21..b88499092 100644 --- a/db.go +++ b/db.go @@ -12,9 +12,9 @@ type DB interface { NewBatch() Batch // For debugging - Iterator() Iterator - Next(Iterator) (key []byte, value []byte) Print() + Iterator() Iterator + Stats() map[string]string } type Batch interface { @@ -25,6 +25,7 @@ type Batch interface { type Iterator interface { Next() bool + Key() []byte Value() []byte } diff --git a/go_level_db.go b/go_level_db.go index 3020d4a03..ac936d01b 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,15 +93,30 @@ func (db *GoLevelDB) Print() { } } -func (db *GoLevelDB) Iterator() Iterator { - return db.db.NewIterator(nil, nil) -} +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.alibeiters", + } -func (db *GoLevelDB) Next(iter Iterator) ([]byte, []byte) { - if iter.Next() { - return iter.Key(), iter.Value() + stats := make(map[string]string) + for _, key := range keys { + str, err := db.db.GetProperty(key) + if err == nil { + stats[key] = str + } } - return nil, nil + return stats +} + +func (db *GoLevelDB) Iterator() Iterator { + return db.db.NewIterator(nil, nil) } func (db *GoLevelDB) NewBatch() Batch { diff --git a/mem_db.go b/mem_db.go index dcd86e6d5..ef410e88c 100644 --- a/mem_db.go +++ b/mem_db.go @@ -65,14 +65,51 @@ func (db *MemDB) Print() { } } -// TODO: needs to be wired to range db.db -func (db *MemDB) Iterator() Iterator { - return nil +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 (it *memDBIterator) Create(db *MemDB) *memDBIterator { + if it == nil { + it = &memDBIterator{} + } + it.db = db + it.last = -1 + + // unfortunately we need a copy of all of the keys + for key, _ := range db.db { + it.keys = append(it.keys, key) + } + return it } -// TODO: needs to be wired to range db.db -func (db *MemDB) Next(iter Iterator) (key []byte, value []byte) { - return nil, nil +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.db[it.keys[it.last]] +} + +func (db *MemDB) Iterator() Iterator { + var it *memDBIterator + return it.Create(db) } func (db *MemDB) NewBatch() Batch { From 097e0abca9e34e00477047acb29c861f140f141e Mon Sep 17 00:00:00 2001 From: "Paul W. Homer" Date: Thu, 23 Mar 2017 14:46:40 -0400 Subject: [PATCH 4/7] Added in locking --- mem_db.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mem_db.go b/mem_db.go index ef410e88c..5307d1a7a 100644 --- a/mem_db.go +++ b/mem_db.go @@ -78,6 +78,9 @@ type memDBIterator struct { } func (it *memDBIterator) Create(db *MemDB) *memDBIterator { + db.mtx.Lock() + defer db.mtx.Unlock() + if it == nil { it = &memDBIterator{} } @@ -104,6 +107,9 @@ func (it *memDBIterator) Key() []byte { } func (it *memDBIterator) Value() []byte { + it.db.mtx.Lock() + defer it.db.mtx.Unlock() + return it.db.db[it.keys[it.last]] } From 34e2d6638dc452325c833cc141d23a986682dab7 Mon Sep 17 00:00:00 2001 From: "Paul W. Homer" Date: Wed, 29 Mar 2017 09:09:01 -0400 Subject: [PATCH 5/7] Fixed a typo in LevelDB property names. --- go_level_db.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go_level_db.go b/go_level_db.go index ac936d01b..1b4a937cf 100644 --- a/go_level_db.go +++ b/go_level_db.go @@ -102,7 +102,7 @@ func (db *GoLevelDB) Stats() map[string]string { "leveldb.cachedblock", "leveldb.openedtables", "leveldb.alivesnaps", - "leveldb.alibeiters", + "leveldb.aliveiters", } stats := make(map[string]string) From 4fdcf51467a1af895483b4d29dde54432c286c39 Mon Sep 17 00:00:00 2001 From: "Paul W. Homer" Date: Thu, 30 Mar 2017 11:51:11 -0400 Subject: [PATCH 6/7] Refactored the iterator to follow Go constructor conventions. --- mem_db.go | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/mem_db.go b/mem_db.go index 5307d1a7a..c80060526 100644 --- a/mem_db.go +++ b/mem_db.go @@ -77,21 +77,8 @@ type memDBIterator struct { db *MemDB } -func (it *memDBIterator) Create(db *MemDB) *memDBIterator { - db.mtx.Lock() - defer db.mtx.Unlock() - - if it == nil { - it = &memDBIterator{} - } - it.db = db - it.last = -1 - - // unfortunately we need a copy of all of the keys - for key, _ := range db.db { - it.keys = append(it.keys, key) - } - return it +func newMemDBIterator() *memDBIterator { + return &memDBIterator{} } func (it *memDBIterator) Next() bool { @@ -114,8 +101,18 @@ func (it *memDBIterator) Value() []byte { } func (db *MemDB) Iterator() Iterator { - var it *memDBIterator - return it.Create(db) + 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 { From 2feff1ea168b481189cdc91a6a63ab9196416c8e Mon Sep 17 00:00:00 2001 From: "Paul W. Homer" Date: Sat, 1 Apr 2017 15:44:41 -0400 Subject: [PATCH 7/7] Commented the empty table in c_level_db, and cleaned up the mem_db Value call. --- c_level_db.go | 1 + mem_db.go | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/c_level_db.go b/c_level_db.go index 41ed4dc16..33a780094 100644 --- a/c_level_db.go +++ b/c_level_db.go @@ -107,6 +107,7 @@ 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) diff --git a/mem_db.go b/mem_db.go index c80060526..286624294 100644 --- a/mem_db.go +++ b/mem_db.go @@ -94,10 +94,7 @@ func (it *memDBIterator) Key() []byte { } func (it *memDBIterator) Value() []byte { - it.db.mtx.Lock() - defer it.db.mtx.Unlock() - - return it.db.db[it.keys[it.last]] + return it.db.Get(it.Key()) } func (db *MemDB) Iterator() Iterator {