OSDN Git Service

fix paging fix_paging
authormars <mars@bytom.io>
Tue, 2 Jul 2019 07:17:31 +0000 (15:17 +0800)
committermars <mars@bytom.io>
Tue, 2 Jul 2019 07:17:31 +0000 (15:17 +0800)
database/leveldb/db.go
database/leveldb/db_test.go
database/leveldb/go_level_db.go
database/leveldb/mem_db.go
wallet/indexer.go
wallet/unconfirmed.go

index 39f0772..80eb08d 100644 (file)
@@ -12,7 +12,7 @@ type DB interface {
        NewBatch() Batch
        Iterator() Iterator
        IteratorPrefix([]byte) Iterator
-       IteratorPrefixWithStart(Prefix, start []byte) Iterator
+       IteratorPrefixWithStart(Prefix, start []byte, isReverse bool) Iterator
 
        // For debugging
        Print()
index ccd37ed..5f1da04 100644 (file)
@@ -22,7 +22,7 @@ func TestDBIteratorSingleKey(t *testing.T) {
                        defer os.RemoveAll(dir)
 
                        db.Set([]byte("1"), []byte("value_1"))
-                       itr := db.IteratorPrefixWithStart(nil, nil)
+                       itr := db.IteratorPrefixWithStart(nil, nil, false)
                        require.Equal(t, []byte(""), itr.Key())
                        require.Equal(t, true, itr.Next())
                        require.Equal(t, []byte("1"), itr.Key())
@@ -39,12 +39,12 @@ func TestDBIteratorTwoKeys(t *testing.T) {
                        db.SetSync([]byte("1"), []byte("value_1"))
                        db.SetSync([]byte("2"), []byte("value_1"))
 
-                       itr := db.IteratorPrefixWithStart(nil, []byte("1"))
+                       itr := db.IteratorPrefixWithStart(nil, []byte("1"), false)
 
                        require.Equal(t, []byte("1"), itr.Key())
 
                        require.Equal(t, true, itr.Next())
-                       itr = db.IteratorPrefixWithStart(nil, []byte("2"))
+                       itr = db.IteratorPrefixWithStart(nil, []byte("2"), false)
 
                        require.Equal(t, false, itr.Next())
                })
@@ -69,7 +69,7 @@ func TestDBIterator(t *testing.T) {
        db.SetSync([]byte("aaa22"), []byte("value_2"))
        db.SetSync([]byte("bbb22"), []byte("value_3"))
 
-       itr := db.IteratorPrefixWithStart([]byte("aaa"), []byte("aaa1"))
+       itr := db.IteratorPrefixWithStart([]byte("aaa"), []byte("aaa1"), false)
        defer itr.Release()
 
        require.Equal(t, true, itr.Next())
@@ -77,7 +77,7 @@ func TestDBIterator(t *testing.T) {
 
        require.Equal(t, false, itr.Next())
 
-       itr = db.IteratorPrefixWithStart([]byte("aaa"), nil)
+       itr = db.IteratorPrefixWithStart([]byte("aaa"), nil, false)
 
        require.Equal(t, true, itr.Next())
        require.Equal(t, []byte("aaa1"), itr.Key())
@@ -87,6 +87,47 @@ func TestDBIterator(t *testing.T) {
 
        require.Equal(t, false, itr.Next())
 
-       itr = db.IteratorPrefixWithStart([]byte("bbb"), []byte("aaa1"))
+       itr = db.IteratorPrefixWithStart([]byte("bbb"), []byte("aaa1"), false)
+       require.Equal(t, false, itr.Next())
+}
+
+func TestDBIteratorReverse(t *testing.T) {
+       dirname, err := ioutil.TempDir("", "db_common_test")
+       require.Nil(t, err)
+
+       db, err := NewGoLevelDB("testdb", dirname)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       defer func() {
+               db.Close()
+               os.RemoveAll(dirname)
+       }()
+
+       db.SetSync([]byte("aaa1"), []byte("value_1"))
+       db.SetSync([]byte("aaa22"), []byte("value_2"))
+       db.SetSync([]byte("bbb22"), []byte("value_3"))
+
+       itr := db.IteratorPrefixWithStart([]byte("aaa"), []byte("aaa22"), true)
+       defer itr.Release()
+
+       require.Equal(t, true, itr.Next())
+       require.Equal(t, []byte("aaa1"), itr.Key())
+
+       require.Equal(t, false, itr.Next())
+
+       itr = db.IteratorPrefixWithStart([]byte("aaa"), nil, true)
+
+       require.Equal(t, []byte("aaa22"), itr.Key())
+
+       require.Equal(t, true, itr.Next())
+       require.Equal(t, []byte("aaa1"), itr.Key())
+
+       require.Equal(t, false, itr.Next())
+
+       require.Equal(t, false, itr.Next())
+
+       itr = db.IteratorPrefixWithStart([]byte("bbb"), []byte("aaa1"), true)
        require.Equal(t, false, itr.Next())
 }
index 7a2b892..a0eac36 100644 (file)
@@ -118,18 +118,31 @@ func (db *GoLevelDB) Stats() map[string]string {
 }
 
 type goLevelDBIterator struct {
-       source iterator.Iterator
-       start  []byte
+       source    iterator.Iterator
+       start     []byte
+       isReverse bool
 }
 
-func newGoLevelDBIterator(source iterator.Iterator, start []byte) *goLevelDBIterator {
-       if start != nil {
-               source.Seek(start)
+func newGoLevelDBIterator(source iterator.Iterator, start []byte, isReverse bool) *goLevelDBIterator {
+       if isReverse {
+               if start == nil {
+                       source.Last()
+               } else {
+                       valid := source.Seek(start)
+                       if !valid {
+                               source.Last()
+                       }
+               }
+       } else {
+               if start != nil {
+                       source.Seek(start)
+               }
        }
 
        return &goLevelDBIterator{
-               source: source,
-               start:  start,
+               source:    source,
+               start:     start,
+               isReverse: isReverse,
        }
 }
 
@@ -161,6 +174,9 @@ func (it *goLevelDBIterator) Error() error {
 
 func (it *goLevelDBIterator) Next() bool {
        it.assertNoError()
+       if it.isReverse {
+               return it.source.Prev()
+       }
        return it.source.Next()
 }
 
@@ -182,9 +198,9 @@ func (db *GoLevelDB) IteratorPrefix(prefix []byte) Iterator {
        return &goLevelDBIterator{source: db.db.NewIterator(util.BytesPrefix(prefix), nil)}
 }
 
-func (db *GoLevelDB) IteratorPrefixWithStart(Prefix, start []byte) Iterator {
+func (db *GoLevelDB) IteratorPrefixWithStart(Prefix, start []byte, isReverse bool) Iterator {
        itr := db.db.NewIterator(util.BytesPrefix(Prefix), nil)
-       return newGoLevelDBIterator(itr, start)
+       return newGoLevelDBIterator(itr, start, isReverse)
 }
 
 func (db *GoLevelDB) NewBatch() Batch {
index 63e2b76..f7b9a60 100644 (file)
@@ -9,9 +9,11 @@ import (
 )
 
 func init() {
-       registerDBCreator(MemDBBackendStr, func(name string, dir string) (DB, error) {
-               return NewMemDB(), nil
-       }, false)
+       /*
+               registerDBCreator(MemDBBackendStr, func(name string, dir string) (DB, error) {
+                       return NewMemDB(), nil
+               }, false)
+       */
 }
 
 type MemDB struct {
@@ -163,7 +165,7 @@ func (db *MemDB) IteratorPrefix(prefix []byte) Iterator {
        return it
 }
 
-func (db *MemDB) IteratorPrefixWithStart(Prefix, start []byte) Iterator {
+func (db *MemDB) IteratorPrefixWithStart(Prefix, start []byte, isReverse bool) Iterator {
        db.mtx.Lock()
        defer db.mtx.Unlock()
 
index 4601779..4bff9c9 100644 (file)
@@ -310,7 +310,7 @@ func (w *Wallet) GetTransactions(accountID string, StartTxID string, count uint,
                preFix = UnconfirmedTxPrefix
        }
 
-       itr := w.DB.IteratorPrefixWithStart([]byte(preFix), startKey)
+       itr := w.DB.IteratorPrefixWithStart([]byte(preFix), startKey, true)
        defer itr.Release()
 
        for txNum := count; itr.Next() && txNum > 0; txNum-- {
@@ -327,6 +327,8 @@ func (w *Wallet) GetTransactions(accountID string, StartTxID string, count uint,
 
        if unconfirmed {
                sort.Sort(SortByTimestamp(annotatedTxs))
+       } else {
+               sort.Sort(SortByHeight(annotatedTxs))
        }
 
        return annotatedTxs, nil
index 4eec6a2..843c289 100644 (file)
@@ -33,6 +33,13 @@ func (a SortByTimestamp) Len() int           { return len(a) }
 func (a SortByTimestamp) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
 func (a SortByTimestamp) Less(i, j int) bool { return a[i].Timestamp > a[j].Timestamp }
 
+// SortByHeight implements sort.Interface for AnnotatedTx slices
+type SortByHeight []*query.AnnotatedTx
+
+func (a SortByHeight) Len() int           { return len(a) }
+func (a SortByHeight) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+func (a SortByHeight) Less(i, j int) bool { return a[i].BlockHeight > a[j].BlockHeight }
+
 // AddUnconfirmedTx handle wallet status update when tx add into txpool
 func (w *Wallet) AddUnconfirmedTx(txD *protocol.TxDesc) {
        if err := w.saveUnconfirmedTx(txD.Tx); err != nil {