From 0fb73ed6226f161efaa79ab750e28768997adaa6 Mon Sep 17 00:00:00 2001 From: Ganesh Vernekar Date: Wed, 14 Feb 2018 19:13:04 +0530 Subject: [PATCH] Changed recursion into iteration for removedPostings.Next() --- index/postings.go | 43 +++++++++++++++++++++--------------------- index/postings_test.go | 22 +++++++++++++++++++++ 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/index/postings.go b/index/postings.go index f942edaad..53449f341 100644 --- a/index/postings.go +++ b/index/postings.go @@ -445,32 +445,31 @@ func (rp *removedPostings) Next() bool { rp.rok = rp.remove.Next() rp.initialized = true } + for { + if !rp.fok { + return false + } - if !rp.fok { - return false - } - - if !rp.rok { - rp.cur = rp.full.At() - rp.fok = rp.full.Next() - return true - } + if !rp.rok { + rp.cur = rp.full.At() + rp.fok = rp.full.Next() + return true + } - fcur, rcur := rp.full.At(), rp.remove.At() - if fcur < rcur { - rp.cur = fcur - rp.fok = rp.full.Next() + fcur, rcur := rp.full.At(), rp.remove.At() + if fcur < rcur { + rp.cur = fcur + rp.fok = rp.full.Next() - return true - } else if rcur < fcur { - // Forward the remove postings to the right position. - rp.rok = rp.remove.Seek(fcur) - } else { - // Skip the current posting. - rp.fok = rp.full.Next() + return true + } else if rcur < fcur { + // Forward the remove postings to the right position. + rp.rok = rp.remove.Seek(fcur) + } else { + // Skip the current posting. + rp.fok = rp.full.Next() + } } - - return rp.Next() } func (rp *removedPostings) Seek(id uint64) bool { diff --git a/index/postings_test.go b/index/postings_test.go index 68553e357..9f8f71220 100644 --- a/index/postings_test.go +++ b/index/postings_test.go @@ -354,6 +354,28 @@ func TestRemovedPostings(t *testing.T) { } +func TestRemovedNextStackoverflow(t *testing.T) { + var full []uint64 + var remove []uint64 + + var i uint64 + for i = 0; i < 1e7; i++ { + full = append(full, i) + remove = append(remove, i) + } + + flp := newListPostings(full) + rlp := newListPostings(remove) + rp := newRemovedPostings(flp, rlp) + gotElem := false + for rp.Next() { + gotElem = true + } + + testutil.Ok(t, rp.Err()) + testutil.Assert(t, !gotElem, "") +} + func TestRemovedPostingsSeek(t *testing.T) { var cases = []struct { a, b []uint64