From b6e3b23fa94aeaa9c4a8ccfb9a0c365ff6d33ba8 Mon Sep 17 00:00:00 2001 From: Armon Dadgar Date: Fri, 15 Nov 2013 13:34:15 -0800 Subject: [PATCH] LogStore must also expose FirstIndex(), add to LevelDB --- leveldb_store.go | 19 +++++++++++++++++++ leveldb_store_test.go | 36 +++++++++++++++++++++++++++++++++++- log.go | 3 +++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/leveldb_store.go b/leveldb_store.go index d4e1cd018..4f2100342 100644 --- a/leveldb_store.go +++ b/leveldb_store.go @@ -66,6 +66,25 @@ func NewLevelDBLogStore(base string) (*LevelDBLogStore, error) { return ldb, nil } +func (l *LevelDBLogStore) FirstIndex() (uint64, error) { + // Get an iterator + it := l.db.NewIterator(nil) + defer it.Release() + + // Seek to the first value + it.First() + + // Check if there is a key + key := it.Key() + if key == nil { + // Nothing written yet + return 0, it.Error() + } + + // Convert the key to the index + return bytesToUint64(key), it.Error() +} + func (l *LevelDBLogStore) LastIndex() (uint64, error) { // Get an iterator it := l.db.NewIterator(nil) diff --git a/leveldb_store_test.go b/leveldb_store_test.go index 8a504218e..c710c2ee7 100644 --- a/leveldb_store_test.go +++ b/leveldb_store_test.go @@ -134,8 +134,17 @@ func TestLevelDB_Logs(t *testing.T) { } defer l.Close() + // Should be no first index + idx, err := l.FirstIndex() + if err != nil { + t.Fatalf("err: %v ", err) + } + if idx != 0 { + t.Fatalf("bad idx: %d", idx) + } + // Should be no last index - idx, err := l.LastIndex() + idx, err = l.LastIndex() if err != nil { t.Fatalf("err: %v ", err) } @@ -151,6 +160,15 @@ func TestLevelDB_Logs(t *testing.T) { // Write out a log log := Log{ + Index: 1, + Term: 1, + Type: LogCommand, + Data: []byte("first"), + } + if err := l.StoreLog(&log); err != nil { + t.Fatalf("err: %v", err) + } + log = Log{ Index: 10, Term: 3, Type: LogCommand, @@ -165,6 +183,15 @@ func TestLevelDB_Logs(t *testing.T) { t.Fatalf("err: %v ", err) } + // Check the lowest index + idx, err = l.FirstIndex() + if err != nil { + t.Fatalf("err: %v ", err) + } + if idx != 1 { + t.Fatalf("bad idx: %d", idx) + } + // Check the highest index idx, err = l.LastIndex() if err != nil { @@ -180,6 +207,13 @@ func TestLevelDB_Logs(t *testing.T) { } // Index should be zero again + idx, err = l.FirstIndex() + if err != nil { + t.Fatalf("err: %v ", err) + } + if idx != 0 { + t.Fatalf("bad idx: %d", idx) + } idx, err = l.LastIndex() if err != nil { t.Fatalf("err: %v ", err) diff --git a/log.go b/log.go index 11c9b210c..780b5457a 100644 --- a/log.go +++ b/log.go @@ -36,6 +36,9 @@ type Log struct { // LogStore is used to provide an interface for storing // and retrieving logs in a durable fashion type LogStore interface { + // Returns the first index written. 0 for no entries. + FirstIndex() (uint64, error) + // Returns the last index written. 0 for no entries. LastIndex() (uint64, error)