github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/syndtr/goleveldb/leveldb/testutil/iter.go (about)

     1  // Copyright (c) 2014, Suryandaru Triandana <syndtr@gmail.com>
     2  // All rights reserved.
     3  //
     4  // Use of this source code is governed by a BSD-style license that can be
     5  // found in the LICENSE file.
     6  
     7  package testutil
     8  
     9  import (
    10  	"fmt"
    11  	"math/rand"
    12  
    13  	. "github.com/insionng/yougam/libraries/onsi/gomega"
    14  
    15  	"github.com/insionng/yougam/libraries/syndtr/goleveldb/leveldb/iterator"
    16  )
    17  
    18  type IterAct int
    19  
    20  func (a IterAct) String() string {
    21  	switch a {
    22  	case IterNone:
    23  		return "none"
    24  	case IterFirst:
    25  		return "first"
    26  	case IterLast:
    27  		return "last"
    28  	case IterPrev:
    29  		return "prev"
    30  	case IterNext:
    31  		return "next"
    32  	case IterSeek:
    33  		return "seek"
    34  	case IterSOI:
    35  		return "soi"
    36  	case IterEOI:
    37  		return "eoi"
    38  	}
    39  	return "unknown"
    40  }
    41  
    42  const (
    43  	IterNone IterAct = iota
    44  	IterFirst
    45  	IterLast
    46  	IterPrev
    47  	IterNext
    48  	IterSeek
    49  	IterSOI
    50  	IterEOI
    51  )
    52  
    53  type IteratorTesting struct {
    54  	KeyValue
    55  	Iter         iterator.Iterator
    56  	Rand         *rand.Rand
    57  	PostFn       func(t *IteratorTesting)
    58  	Pos          int
    59  	Act, LastAct IterAct
    60  
    61  	once bool
    62  }
    63  
    64  func (t *IteratorTesting) init() {
    65  	if !t.once {
    66  		t.Pos = -1
    67  		t.once = true
    68  	}
    69  }
    70  
    71  func (t *IteratorTesting) post() {
    72  	if t.PostFn != nil {
    73  		t.PostFn(t)
    74  	}
    75  }
    76  
    77  func (t *IteratorTesting) setAct(act IterAct) {
    78  	t.LastAct, t.Act = t.Act, act
    79  }
    80  
    81  func (t *IteratorTesting) text() string {
    82  	return fmt.Sprintf("at pos %d and last action was <%v> -> <%v>", t.Pos, t.LastAct, t.Act)
    83  }
    84  
    85  func (t *IteratorTesting) Text() string {
    86  	return "IteratorTesting is " + t.text()
    87  }
    88  
    89  func (t *IteratorTesting) IsFirst() bool {
    90  	t.init()
    91  	return t.Len() > 0 && t.Pos == 0
    92  }
    93  
    94  func (t *IteratorTesting) IsLast() bool {
    95  	t.init()
    96  	return t.Len() > 0 && t.Pos == t.Len()-1
    97  }
    98  
    99  func (t *IteratorTesting) TestKV() {
   100  	t.init()
   101  	key, value := t.Index(t.Pos)
   102  	Expect(t.Iter.Key()).NotTo(BeNil())
   103  	Expect(t.Iter.Key()).Should(Equal(key), "Key is invalid, %s", t.text())
   104  	Expect(t.Iter.Value()).Should(Equal(value), "Value for key %q, %s", key, t.text())
   105  }
   106  
   107  func (t *IteratorTesting) First() {
   108  	t.init()
   109  	t.setAct(IterFirst)
   110  
   111  	ok := t.Iter.First()
   112  	Expect(t.Iter.Error()).ShouldNot(HaveOccurred())
   113  	if t.Len() > 0 {
   114  		t.Pos = 0
   115  		Expect(ok).Should(BeTrue(), t.Text())
   116  		t.TestKV()
   117  	} else {
   118  		t.Pos = -1
   119  		Expect(ok).ShouldNot(BeTrue(), t.Text())
   120  	}
   121  	t.post()
   122  }
   123  
   124  func (t *IteratorTesting) Last() {
   125  	t.init()
   126  	t.setAct(IterLast)
   127  
   128  	ok := t.Iter.Last()
   129  	Expect(t.Iter.Error()).ShouldNot(HaveOccurred())
   130  	if t.Len() > 0 {
   131  		t.Pos = t.Len() - 1
   132  		Expect(ok).Should(BeTrue(), t.Text())
   133  		t.TestKV()
   134  	} else {
   135  		t.Pos = 0
   136  		Expect(ok).ShouldNot(BeTrue(), t.Text())
   137  	}
   138  	t.post()
   139  }
   140  
   141  func (t *IteratorTesting) Next() {
   142  	t.init()
   143  	t.setAct(IterNext)
   144  
   145  	ok := t.Iter.Next()
   146  	Expect(t.Iter.Error()).ShouldNot(HaveOccurred())
   147  	if t.Pos < t.Len()-1 {
   148  		t.Pos++
   149  		Expect(ok).Should(BeTrue(), t.Text())
   150  		t.TestKV()
   151  	} else {
   152  		t.Pos = t.Len()
   153  		Expect(ok).ShouldNot(BeTrue(), t.Text())
   154  	}
   155  	t.post()
   156  }
   157  
   158  func (t *IteratorTesting) Prev() {
   159  	t.init()
   160  	t.setAct(IterPrev)
   161  
   162  	ok := t.Iter.Prev()
   163  	Expect(t.Iter.Error()).ShouldNot(HaveOccurred())
   164  	if t.Pos > 0 {
   165  		t.Pos--
   166  		Expect(ok).Should(BeTrue(), t.Text())
   167  		t.TestKV()
   168  	} else {
   169  		t.Pos = -1
   170  		Expect(ok).ShouldNot(BeTrue(), t.Text())
   171  	}
   172  	t.post()
   173  }
   174  
   175  func (t *IteratorTesting) Seek(i int) {
   176  	t.init()
   177  	t.setAct(IterSeek)
   178  
   179  	key, _ := t.Index(i)
   180  	oldKey, _ := t.IndexOrNil(t.Pos)
   181  
   182  	ok := t.Iter.Seek(key)
   183  	Expect(t.Iter.Error()).ShouldNot(HaveOccurred())
   184  	Expect(ok).Should(BeTrue(), fmt.Sprintf("Seek from key %q to %q, to pos %d, %s", oldKey, key, i, t.text()))
   185  
   186  	t.Pos = i
   187  	t.TestKV()
   188  	t.post()
   189  }
   190  
   191  func (t *IteratorTesting) SeekInexact(i int) {
   192  	t.init()
   193  	t.setAct(IterSeek)
   194  	var key0 []byte
   195  	key1, _ := t.Index(i)
   196  	if i > 0 {
   197  		key0, _ = t.Index(i - 1)
   198  	}
   199  	key := BytesSeparator(key0, key1)
   200  	oldKey, _ := t.IndexOrNil(t.Pos)
   201  
   202  	ok := t.Iter.Seek(key)
   203  	Expect(t.Iter.Error()).ShouldNot(HaveOccurred())
   204  	Expect(ok).Should(BeTrue(), fmt.Sprintf("Seek from key %q to %q (%q), to pos %d, %s", oldKey, key, key1, i, t.text()))
   205  
   206  	t.Pos = i
   207  	t.TestKV()
   208  	t.post()
   209  }
   210  
   211  func (t *IteratorTesting) SeekKey(key []byte) {
   212  	t.init()
   213  	t.setAct(IterSeek)
   214  	oldKey, _ := t.IndexOrNil(t.Pos)
   215  	i := t.Search(key)
   216  
   217  	ok := t.Iter.Seek(key)
   218  	Expect(t.Iter.Error()).ShouldNot(HaveOccurred())
   219  	if i < t.Len() {
   220  		key_, _ := t.Index(i)
   221  		Expect(ok).Should(BeTrue(), fmt.Sprintf("Seek from key %q to %q (%q), to pos %d, %s", oldKey, key, key_, i, t.text()))
   222  		t.Pos = i
   223  		t.TestKV()
   224  	} else {
   225  		Expect(ok).ShouldNot(BeTrue(), fmt.Sprintf("Seek from key %q to %q, %s", oldKey, key, t.text()))
   226  	}
   227  
   228  	t.Pos = i
   229  	t.post()
   230  }
   231  
   232  func (t *IteratorTesting) SOI() {
   233  	t.init()
   234  	t.setAct(IterSOI)
   235  	Expect(t.Pos).Should(BeNumerically("<=", 0), t.Text())
   236  	for i := 0; i < 3; i++ {
   237  		t.Prev()
   238  	}
   239  	t.post()
   240  }
   241  
   242  func (t *IteratorTesting) EOI() {
   243  	t.init()
   244  	t.setAct(IterEOI)
   245  	Expect(t.Pos).Should(BeNumerically(">=", t.Len()-1), t.Text())
   246  	for i := 0; i < 3; i++ {
   247  		t.Next()
   248  	}
   249  	t.post()
   250  }
   251  
   252  func (t *IteratorTesting) WalkPrev(fn func(t *IteratorTesting)) {
   253  	t.init()
   254  	for old := t.Pos; t.Pos > 0; old = t.Pos {
   255  		fn(t)
   256  		Expect(t.Pos).Should(BeNumerically("<", old), t.Text())
   257  	}
   258  }
   259  
   260  func (t *IteratorTesting) WalkNext(fn func(t *IteratorTesting)) {
   261  	t.init()
   262  	for old := t.Pos; t.Pos < t.Len()-1; old = t.Pos {
   263  		fn(t)
   264  		Expect(t.Pos).Should(BeNumerically(">", old), t.Text())
   265  	}
   266  }
   267  
   268  func (t *IteratorTesting) PrevAll() {
   269  	t.WalkPrev(func(t *IteratorTesting) {
   270  		t.Prev()
   271  	})
   272  }
   273  
   274  func (t *IteratorTesting) NextAll() {
   275  	t.WalkNext(func(t *IteratorTesting) {
   276  		t.Next()
   277  	})
   278  }
   279  
   280  func DoIteratorTesting(t *IteratorTesting) {
   281  	if t.Rand == nil {
   282  		t.Rand = NewRand()
   283  	}
   284  	t.SOI()
   285  	t.NextAll()
   286  	t.First()
   287  	t.SOI()
   288  	t.NextAll()
   289  	t.EOI()
   290  	t.PrevAll()
   291  	t.Last()
   292  	t.EOI()
   293  	t.PrevAll()
   294  	t.SOI()
   295  
   296  	t.NextAll()
   297  	t.PrevAll()
   298  	t.NextAll()
   299  	t.Last()
   300  	t.PrevAll()
   301  	t.First()
   302  	t.NextAll()
   303  	t.EOI()
   304  
   305  	ShuffledIndex(t.Rand, t.Len(), 1, func(i int) {
   306  		t.Seek(i)
   307  	})
   308  
   309  	ShuffledIndex(t.Rand, t.Len(), 1, func(i int) {
   310  		t.SeekInexact(i)
   311  	})
   312  
   313  	ShuffledIndex(t.Rand, t.Len(), 1, func(i int) {
   314  		t.Seek(i)
   315  		if i%2 != 0 {
   316  			t.PrevAll()
   317  			t.SOI()
   318  		} else {
   319  			t.NextAll()
   320  			t.EOI()
   321  		}
   322  	})
   323  
   324  	for _, key := range []string{"", "foo", "bar", "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"} {
   325  		t.SeekKey([]byte(key))
   326  	}
   327  }