blob: 59205bfba4a924b931c42f6763431c85b7d05610 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors
//
// 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.
package storage
import (
"github.com/golang/protobuf/proto"
leveldb_iter "github.com/syndtr/goleveldb/leveldb/iterator"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"shuffler"
)
// LevelDBStoreIterator provides an iterator to parse the result set pointed to
// by an underlying leveldb iterator object.
type LevelDBStoreIterator struct {
iter leveldb_iter.Iterator
}
// NewLevelDBStoreIterator builds and initializes a new |LevelDBStoreIterator|
// from the input \it|.
func NewLevelDBStoreIterator(it leveldb_iter.Iterator) Iterator {
if it == nil {
panic("LevelDBStore Iterator is nil.")
}
return &LevelDBStoreIterator{
iter: it,
}
}
// Get returns the current entry the Iterator is pointing to or an error if the
// iterator is invalid or if the iterator value is invalid.
func (li *LevelDBStoreIterator) Get() (*shuffler.ObservationVal, error) {
if li == nil {
panic("LevelDBStore Iterator is nil.")
}
if li.iter == nil || !li.iter.Valid() {
return nil, grpc.Errorf(codes.Internal, "Invalid iterator")
}
obVal := &shuffler.ObservationVal{}
if err := proto.Unmarshal(li.iter.Value(), obVal); err != nil {
return nil, grpc.Errorf(codes.Internal, "Error in parsing observation value from datastore: [%v]", err)
}
return obVal, nil
}
// Next advances the iterator to the next entry and returns whether or not
// the iterator is still valid. The Get() method may only be invoked on a
// valid iterator. A newly obtained iterator starts before the first valid
// entry so Next() must be invoked before Get().
func (li *LevelDBStoreIterator) Next() bool {
if li == nil {
panic("LevelDBStore Iterator is nil.")
}
if li.iter == nil {
return false
}
return li.iter.Next()
}
// Release releases the iterator after use.
func (li *LevelDBStoreIterator) Release() error {
if li == nil {
panic("LevelDBStore Iterator is nil.")
}
li.iter.Release()
if err := li.iter.Error(); err != nil {
li.iter = nil
return grpc.Errorf(codes.Internal, "LevelDB iterator error: [%v]", err)
}
li.iter = nil
return nil
}