0
0
bleve/index/store/cznicb/iterator.go

114 lines
2.1 KiB
Go
Raw Normal View History

// Copyright (c) 2015 Couchbase, Inc.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the
// License. You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an "AS
// IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
// express or implied. See the License for the specific language
// governing permissions and limitations under the License.
// +build go1.4
package cznicb
import (
"errors"
"github.com/cznic/b"
)
var iteratorDoneErr = errors.New("iteratorDoneErr") // A sentinel value.
type Iterator struct { // Assuming that iterators are used single-threaded.
s *Store
e *b.Enumerator
currK interface{}
currV interface{}
currErr error
}
func (i *Iterator) SeekFirst() {
i.currK = nil
i.currV = nil
i.currErr = nil
var err error
i.s.m.RLock()
i.e, err = i.s.t.SeekFirst()
i.s.m.RUnlock() // cannot defer, must unlock before Next
if err != nil {
i.currK = nil
i.currV = nil
i.currErr = iteratorDoneErr
}
i.Next()
}
func (i *Iterator) Seek(k []byte) {
i.currK = nil
i.currV = nil
i.currErr = nil
i.s.m.RLock()
i.e, _ = i.s.t.Seek(k)
i.s.m.RUnlock() // cannot defer, must unlock before Next
i.Next()
}
func (i *Iterator) Next() {
if i.currErr != nil {
i.currK = nil
i.currV = nil
i.currErr = iteratorDoneErr
return
}
i.s.m.RLock()
defer i.s.m.RUnlock()
i.currK, i.currV, i.currErr = i.e.Next()
}
func (i *Iterator) Current() ([]byte, []byte, bool) {
if i.currErr == iteratorDoneErr ||
i.currK == nil ||
i.currV == nil {
return nil, nil, false
}
return i.currK.([]byte), i.currV.([]byte), true
}
func (i *Iterator) Key() []byte {
k, _, ok := i.Current()
if !ok {
return nil
}
return k
}
func (i *Iterator) Value() []byte {
_, v, ok := i.Current()
if !ok {
return nil
}
return v
}
func (i *Iterator) Valid() bool {
_, _, ok := i.Current()
return ok
}
func (i *Iterator) Close() error {
if i.e != nil {
i.e.Close()
}
i.e = nil
return nil
}