...

Source file src/github.com/syndtr/goleveldb/leveldb/iterator/indexed_iter.go

Documentation: github.com/syndtr/goleveldb/leveldb/iterator

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

View as plain text