func (f Index) Count() (count int, err error) {
	it := f.db.NewIterator()
	defer it.Release()
	for ok := it.Seek(f.prefix); ok; ok = it.Next() {
		key := it.Key()
		if key[0] != f.prefix[0] {
			break
		}
		count++
	}
	return count, it.Error()
}
Count returns the number of items in index.
package shed
import (
	"bytes"
	"errors"
	"fmt"
	"github.com/syndtr/goleveldb/leveldb"
	"github.com/syndtr/goleveldb/leveldb/iterator"
)
type Item struct {
	Address         []byte
	Data            []byte
	AccessTimestamp int64
	StoreTimestamp  int64
	BinID           uint64
	PinCounter      uint64  
	Tag             uint32
	BatchID         []byte  
	Index           []byte  
	Timestamp       []byte  
	Sig             []byte  
	BucketDepth     uint8   
	Depth           uint8   
	Radius          uint8   
	Immutable       bool    
}
func (i Item) Merge(i2 Item) Item {
	if i.Address == nil {
		i.Address = i2.Address
	}
	if i.Data == nil {
		i.Data = i2.Data
	}
	if i.AccessTimestamp == 0 {
		i.AccessTimestamp = i2.AccessTimestamp
	}
	if i.StoreTimestamp == 0 {
		i.StoreTimestamp = i2.StoreTimestamp
	}
	if i.BinID == 0 {
		i.BinID = i2.BinID
	}
	if i.PinCounter == 0 {
		i.PinCounter = i2.PinCounter
	}
	if i.Tag == 0 {
		i.Tag = i2.Tag
	}
	if len(i.BatchID) == 0 {
		i.BatchID = i2.BatchID
	}
	if len(i.Index) == 0 {
		i.Index = i2.Index
	}
	if len(i.Timestamp) == 0 {
		i.Timestamp = i2.Timestamp
	}
	if len(i.Sig) == 0 {
		i.Sig = i2.Sig
	}
	if i.BucketDepth == 0 {
		i.BucketDepth = i2.BucketDepth
	}
	if i.Depth == 0 {
		i.Depth = i2.Depth
	}
	if i.Radius == 0 {
		i.Radius = i2.Radius
	}
	if !i.Immutable {
		i.Immutable = i2.Immutable
	}
	return i
}
type Index struct {
	db              *DB
	prefix          []byte
	encodeKeyFunc   func(fields Item) (key []byte, err error)
	decodeKeyFunc   func(key []byte) (e Item, err error)
	encodeValueFunc func(fields Item) (value []byte, err error)
	decodeValueFunc func(keyFields Item, value []byte) (e Item, err error)
}
type IndexFuncs struct {
	EncodeKey   func(fields Item) (key []byte, err error)
	DecodeKey   func(key []byte) (e Item, err error)
	EncodeValue func(fields Item) (value []byte, err error)
	DecodeValue func(keyFields Item, value []byte) (e Item, err error)
}
func (db *DB) NewIndex(name string, funcs IndexFuncs) (f Index, err error) {
	id, err := db.schemaIndexPrefix(name)
	if err != nil {
		return f, fmt.Errorf("get schema index prefix: %w", err)
	}
	prefix := []byte{id}
	return Index{
		db:     db,
		prefix: prefix,
		encodeKeyFunc: func(e Item) (key []byte, err error) {
			key, err = funcs.EncodeKey(e)
			if err != nil {
				return nil, err
			}
			return append(append(make([]byte, 0, len(key)+1), prefix...), key...), nil
		},
		decodeKeyFunc: func(key []byte) (e Item, err error) {
			return funcs.DecodeKey(key[1:])
		},
		encodeValueFunc: funcs.EncodeValue,
		decodeValueFunc: funcs.DecodeValue,
	}, nil
}
func (f Index) ItemKey(item Item) (key []byte, err error) {
	return f.encodeKeyFunc(item)
}
func (f Index) Get(keyFields Item) (out Item, err error) {
	key, err := f.encodeKeyFunc(keyFields)
	if err != nil {
		return out, fmt.Errorf("encode key: %w", err)
	}
	value, err := f.db.Get(key)
	if err != nil {
		return out, fmt.Errorf("get value: %w", err)
	}
	out, err = f.decodeValueFunc(keyFields, value)
	if err != nil {
		return out, fmt.Errorf("decode value: %w", err)
	}
	return out.Merge(keyFields), nil
}
func (f Index) Fill(items []Item) (err error) {
	snapshot, err := f.db.ldb.GetSnapshot()
	if err != nil {
		return fmt.Errorf("get snapshot: %w", err)
	}
	defer snapshot.Release()
	for i, item := range items {
		key, err := f.encodeKeyFunc(item)
		if err != nil {
			return fmt.Errorf("encode key: %w", err)
		}
		value, err := snapshot.Get(key, nil)
		if err != nil {
			return fmt.Errorf("get value: %w", err)
		}
		v, err := f.decodeValueFunc(item, value)
		if err != nil {
			return fmt.Errorf("decode value: %w", err)
		}
		items[i] = v.Merge(item)
	}
	return nil
}
func (f Index) Has(keyFields Item) (bool, error) {
	key, err := f.encodeKeyFunc(keyFields)
	if err != nil {
		return false, fmt.Errorf("encode key: %w", err)
	}
	return f.db.Has(key)
}
func (f Index) HasMulti(items ...Item) ([]bool, error) {
	have := make([]bool, len(items))
	snapshot, err := f.db.ldb.GetSnapshot()
	if err != nil {
		return nil, fmt.Errorf("get snapshot: %w", err)
	}
	defer snapshot.Release()
	for i, keyFields := range items {
		key, err := f.encodeKeyFunc(keyFields)
		if err != nil {
			return nil, fmt.Errorf("encode key for address %x: %w", keyFields.Address, err)
		}
		have[i], err = snapshot.Has(key, nil)
		if err != nil {
			return nil, fmt.Errorf("has key for address %x: %w", keyFields.Address, err)
		}
	}
	return have, nil
}
func (f Index) Put(i Item) (err error) {
	key, err := f.encodeKeyFunc(i)
	if err != nil {
		return fmt.Errorf("encode key: %w", err)
	}
	value, err := f.encodeValueFunc(i)
	if err != nil {
		return fmt.Errorf("encode value: %w", err)
	}
	return f.db.Put(key, value)
}
func (f Index) PutInBatch(batch *leveldb.Batch, i Item) (err error) {
	key, err := f.encodeKeyFunc(i)
	if err != nil {
		return fmt.Errorf("encode key: %w", err)
	}
	value, err := f.encodeValueFunc(i)
	if err != nil {
		return fmt.Errorf("encode value: %w", err)
	}
	batch.Put(key, value)
	return nil
}
func (f Index) Delete(keyFields Item) (err error) {
	key, err := f.encodeKeyFunc(keyFields)
	if err != nil {
		return fmt.Errorf("encode key: %w", err)
	}
	return f.db.Delete(key)
}
func (f Index) DeleteInBatch(batch *leveldb.Batch, keyFields Item) (err error) {
	key, err := f.encodeKeyFunc(keyFields)
	if err != nil {
		return fmt.Errorf("encode key: %w", err)
	}
	batch.Delete(key)
	return nil
}
type IndexIterFunc func(item Item) (stop bool, err error)
type IterateOptions struct {
	StartFrom *Item
	SkipStartFromItem bool
	Prefix []byte
	Reverse bool
}
func (f Index) Iterate(fn IndexIterFunc, options *IterateOptions) (err error) {
	if options == nil {
		options = new(IterateOptions)
	}
	prefix := append(f.prefix, options.Prefix...)
	startKey := prefix
	if options.StartFrom != nil {
		startKey, err = f.encodeKeyFunc(*options.StartFrom)
		if err != nil {
			return fmt.Errorf("encode key: %w", err)
		}
	}
	it := f.db.NewIterator()
	defer it.Release()
	var ok bool
	ok = it.Seek(startKey)
	if !options.Reverse {
		if !ok {
			return it.Error()
		}
	} else {
		if options.StartFrom != nil {
			if !ok {
				return it.Error()
			}
		} else {
			ok = it.Last()
			if !ok {
				return it.Error()
			}
			if lastKeyHasPrefix := bytes.HasPrefix(it.Key(), prefix); !lastKeyHasPrefix {
				incrementedPrefix := bytesIncrement(prefix)
				if incrementedPrefix == nil {
					return fmt.Errorf("index iterator invalid prefix: %v -> %v", prefix, string(prefix))
				}
				ok = it.Seek(incrementedPrefix)
				if !ok {
					return it.Error()
				}
				ok = it.Prev()
				if !ok {
					return it.Error()
				}
			}
		}
	}
	itSeekerFn := it.Next
	if options.Reverse {
		itSeekerFn = it.Prev
	}
	if options.SkipStartFromItem && bytes.Equal(startKey, it.Key()) {
		ok = itSeekerFn()
	}
	for ; ok; ok = itSeekerFn() {
		item, err := f.itemFromIterator(it, prefix)
		if err != nil {
			if errors.Is(err, leveldb.ErrNotFound) {
				break
			}
			return fmt.Errorf("get item from iterator: %w", err)
		}
		stop, err := fn(item)
		if err != nil {
			return fmt.Errorf("index iterator function: %w", err)
		}
		if stop {
			break
		}
	}
	return it.Error()
}
func bytesIncrement(bytes []byte) []byte {
	b := append(bytes[:0:0], bytes...)
	for i := len(bytes) - 1; i >= 0; {
		if b[i] == 0xFF {
			i--
			continue
		}
		b[i]++
		return b[:i+1]
	}
	return nil
}
func (f Index) First(prefix []byte) (i Item, err error) {
	it := f.db.NewIterator()
	defer it.Release()
	totalPrefix := append(f.prefix, prefix...)
	it.Seek(totalPrefix)
	return f.itemFromIterator(it, totalPrefix)
}
func (f Index) itemFromIterator(it iterator.Iterator, totalPrefix []byte) (i Item, err error) {
	key := it.Key()
	if !bytes.HasPrefix(key, totalPrefix) {
		return i, leveldb.ErrNotFound
	}
	keyItem, err := f.decodeKeyFunc(append([]byte(nil), key...))
	if err != nil {
		return i, fmt.Errorf("decode key: %w", err)
	}
	valueItem, err := f.decodeValueFunc(keyItem, append([]byte(nil), it.Value()...))
	if err != nil {
		return i, fmt.Errorf("decode value: %w", err)
	}
	return keyItem.Merge(valueItem), it.Error()
}
func (f Index) Last(prefix []byte) (i Item, err error) {
	it := f.db.NewIterator()
	defer it.Release()
	nextPrefix := incByteSlice(prefix)
	l := len(prefix)
	if l > 0 && nextPrefix != nil {
		it.Seek(append(f.prefix, nextPrefix...))
		it.Prev()
	} else {
		it.Last()
	}
	totalPrefix := append(f.prefix, prefix...)
	return f.itemFromIterator(it, totalPrefix)
}
func incByteSlice(b []byte) (next []byte) {
	l := len(b)
	next = make([]byte, l)
	copy(next, b)
	for i := l - 1; i >= 0; i-- {
		if b[i] == 255 {
			next[i] = 0
		} else {
			next[i] = b[i] + 1
			return next
		}
	}
	return nil
}