From 76c33da3ee407a5e83125627c6ff916432aeda15 Mon Sep 17 00:00:00 2001 From: vkd Date: Thu, 8 Sep 2016 16:07:49 +0300 Subject: [PATCH 1/2] fix iterator across empty pages --- iterator.go | 39 ++++++++++++++++++++++----------------- iterator_test.go | 23 +++++++++++++++++++++++ 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/iterator.go b/iterator.go index 0a3df063..e8872fb3 100644 --- a/iterator.go +++ b/iterator.go @@ -46,25 +46,30 @@ func (it *ScanIterator) Next() bool { return true } - // Return if there is more data to fetch. - if it.ScanCmd.cursor == 0 { - return false - } + for { + // Return if there is more data to fetch. + if it.ScanCmd.cursor == 0 { + return false + } - // Fetch next page. - if it.ScanCmd._args[0] == "scan" { - it.ScanCmd._args[1] = it.ScanCmd.cursor - } else { - it.ScanCmd._args[2] = it.ScanCmd.cursor - } - it.ScanCmd.reset() - it.client.process(it.ScanCmd) - if it.ScanCmd.Err() != nil { - return false - } + // Fetch next page. + if it.ScanCmd._args[0] == "scan" { + it.ScanCmd._args[1] = it.ScanCmd.cursor + } else { + it.ScanCmd._args[2] = it.ScanCmd.cursor + } + it.ScanCmd.reset() + it.client.process(it.ScanCmd) + if it.ScanCmd.Err() != nil { + return false + } - it.pos = 1 - return len(it.ScanCmd.page) > 0 + it.pos = 1 + if len(it.ScanCmd.page) > 0 { + return true + } + } + return false } // Val returns the key/field at the current cursor position. diff --git a/iterator_test.go b/iterator_test.go index f752f68c..7b301768 100644 --- a/iterator_test.go +++ b/iterator_test.go @@ -21,6 +21,18 @@ var _ = Describe("ScanIterator", func() { return err } + var extraSeed = func(n int, m int) error { + pipe := client.Pipeline() + for i := 1; i <= m; i++ { + pipe.Set(fmt.Sprintf("A%02d", i), "x", 0).Err() + } + for i := 1; i <= n; i++ { + pipe.Set(fmt.Sprintf("K%02d", i), "x", 0).Err() + } + _, err := pipe.Exec() + return err + } + var hashKey = "K_HASHTEST" var hashSeed = func(n int) error { pipe := client.Pipeline() @@ -110,4 +122,15 @@ var _ = Describe("ScanIterator", func() { Expect(vals).To(HaveLen(13)) }) + It("should scan with match across empty pages", func() { + Expect(extraSeed(2, 10)).NotTo(HaveOccurred()) + + var vals []string + iter := client.Scan(0, "K*", 1).Iterator() + for iter.Next() { + vals = append(vals, iter.Val()) + } + Expect(iter.Err()).NotTo(HaveOccurred()) + Expect(vals).To(HaveLen(2)) + }) }) From cbf8ff22f55038e0681e43be48c01b37847b507c Mon Sep 17 00:00:00 2001 From: vkd Date: Thu, 8 Sep 2016 16:40:45 +0300 Subject: [PATCH 2/2] fix comments --- iterator.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iterator.go b/iterator.go index e8872fb3..d48ad7b8 100644 --- a/iterator.go +++ b/iterator.go @@ -47,7 +47,7 @@ func (it *ScanIterator) Next() bool { } for { - // Return if there is more data to fetch. + // Return if there is no more data to fetch. if it.ScanCmd.cursor == 0 { return false } @@ -65,6 +65,8 @@ func (it *ScanIterator) Next() bool { } it.pos = 1 + + // Redis can occasionally return empty page if len(it.ScanCmd.page) > 0 { return true }