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

     1  // Copyright (c) 2012, 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 iterator
     8  
     9  import (
    10  	"github.com/insionng/yougam/libraries/syndtr/goleveldb/leveldb/errors"
    11  	"github.com/insionng/yougam/libraries/syndtr/goleveldb/leveldb/util"
    12  )
    13  
    14  // IteratorIndexer is the interface that wraps CommonIterator and basic Get
    15  // method. IteratorIndexer provides index for indexed iterator.
    16  type IteratorIndexer interface {
    17  	CommonIterator
    18  
    19  	// Get returns a new data iterator for the current position, or nil if
    20  	// done.
    21  	Get() Iterator
    22  }
    23  
    24  type indexedIterator struct {
    25  	util.BasicReleaser
    26  	index  IteratorIndexer
    27  	strict bool
    28  
    29  	data   Iterator
    30  	err    error
    31  	errf   func(err error)
    32  	closed bool
    33  }
    34  
    35  func (i *indexedIterator) setData() {
    36  	if i.data != nil {
    37  		i.data.Release()
    38  	}
    39  	i.data = i.index.Get()
    40  }
    41  
    42  func (i *indexedIterator) clearData() {
    43  	if i.data != nil {
    44  		i.data.Release()
    45  	}
    46  	i.data = nil
    47  }
    48  
    49  func (i *indexedIterator) indexErr() {
    50  	if err := i.index.Error(); err != nil {
    51  		if i.errf != nil {
    52  			i.errf(err)
    53  		}
    54  		i.err = err
    55  	}
    56  }
    57  
    58  func (i *indexedIterator) dataErr() bool {
    59  	if err := i.data.Error(); err != nil {
    60  		if i.errf != nil {
    61  			i.errf(err)
    62  		}
    63  		if i.strict || !errors.IsCorrupted(err) {
    64  			i.err = err
    65  			return true
    66  		}
    67  	}
    68  	return false
    69  }
    70  
    71  func (i *indexedIterator) Valid() bool {
    72  	return i.data != nil && i.data.Valid()
    73  }
    74  
    75  func (i *indexedIterator) First() bool {
    76  	if i.err != nil {
    77  		return false
    78  	} else if i.Released() {
    79  		i.err = ErrIterReleased
    80  		return false
    81  	}
    82  
    83  	if !i.index.First() {
    84  		i.indexErr()
    85  		i.clearData()
    86  		return false
    87  	}
    88  	i.setData()
    89  	return i.Next()
    90  }
    91  
    92  func (i *indexedIterator) Last() bool {
    93  	if i.err != nil {
    94  		return false
    95  	} else if i.Released() {
    96  		i.err = ErrIterReleased
    97  		return false
    98  	}
    99  
   100  	if !i.index.Last() {
   101  		i.indexErr()
   102  		i.clearData()
   103  		return false
   104  	}
   105  	i.setData()
   106  	if !i.data.Last() {
   107  		if i.dataErr() {
   108  			return false
   109  		}
   110  		i.clearData()
   111  		return i.Prev()
   112  	}
   113  	return true
   114  }
   115  
   116  func (i *indexedIterator) Seek(key []byte) bool {
   117  	if i.err != nil {
   118  		return false
   119  	} else if i.Released() {
   120  		i.err = ErrIterReleased
   121  		return false
   122  	}
   123  
   124  	if !i.index.Seek(key) {
   125  		i.indexErr()
   126  		i.clearData()
   127  		return false
   128  	}
   129  	i.setData()
   130  	if !i.data.Seek(key) {
   131  		if i.dataErr() {
   132  			return false
   133  		}
   134  		i.clearData()
   135  		return i.Next()
   136  	}
   137  	return true
   138  }
   139  
   140  func (i *indexedIterator) Next() bool {
   141  	if i.err != nil {
   142  		return false
   143  	} else if i.Released() {
   144  		i.err = ErrIterReleased
   145  		return false
   146  	}
   147  
   148  	switch {
   149  	case i.data != nil && !i.data.Next():
   150  		if i.dataErr() {
   151  			return false
   152  		}
   153  		i.clearData()
   154  		fallthrough
   155  	case i.data == nil:
   156  		if !i.index.Next() {
   157  			i.indexErr()
   158  			return false
   159  		}
   160  		i.setData()
   161  		return i.Next()
   162  	}
   163  	return true
   164  }
   165  
   166  func (i *indexedIterator) Prev() bool {
   167  	if i.err != nil {
   168  		return false
   169  	} else if i.Released() {
   170  		i.err = ErrIterReleased
   171  		return false
   172  	}
   173  
   174  	switch {
   175  	case i.data != nil && !i.data.Prev():
   176  		if i.dataErr() {
   177  			return false
   178  		}
   179  		i.clearData()
   180  		fallthrough
   181  	case i.data == nil:
   182  		if !i.index.Prev() {
   183  			i.indexErr()
   184  			return false
   185  		}
   186  		i.setData()
   187  		if !i.data.Last() {
   188  			if i.dataErr() {
   189  				return false
   190  			}
   191  			i.clearData()
   192  			return i.Prev()
   193  		}
   194  	}
   195  	return true
   196  }
   197  
   198  func (i *indexedIterator) Key() []byte {
   199  	if i.data == nil {
   200  		return nil
   201  	}
   202  	return i.data.Key()
   203  }
   204  
   205  func (i *indexedIterator) Value() []byte {
   206  	if i.data == nil {
   207  		return nil
   208  	}
   209  	return i.data.Value()
   210  }
   211  
   212  func (i *indexedIterator) Release() {
   213  	i.clearData()
   214  	i.index.Release()
   215  	i.BasicReleaser.Release()
   216  }
   217  
   218  func (i *indexedIterator) Error() error {
   219  	if i.err != nil {
   220  		return i.err
   221  	}
   222  	if err := i.index.Error(); err != nil {
   223  		return err
   224  	}
   225  	return nil
   226  }
   227  
   228  func (i *indexedIterator) SetErrorCallback(f func(err error)) {
   229  	i.errf = f
   230  }
   231  
   232  // NewIndexedIterator returns an 'indexed iterator'. An index is iterator
   233  // that returns another iterator, a 'data iterator'. A 'data iterator' is the
   234  // iterator that contains actual key/value pairs.
   235  //
   236  // If strict is true the any 'corruption errors' (i.e errors.IsCorrupted(err) == true)
   237  // won't be ignored and will halt 'indexed iterator', otherwise the iterator will
   238  // continue to the next 'data iterator'. Corruption on 'index iterator' will not be
   239  // ignored and will halt the iterator.
   240  func NewIndexedIterator(index IteratorIndexer, strict bool) Iterator {
   241  	return &indexedIterator{index: index, strict: strict}
   242  }