internal/gitaly/storage/keyvalue/prefixed.go (134 lines of code) (raw):

package keyvalue type prefixedTransactioner struct { transactioner Transactioner prefix []byte } // NewPrefixedTransactioner wraps the transactioner and applies the given prefix to every // key in operations performed through it. func NewPrefixedTransactioner(transactioner Transactioner, prefix []byte) Transactioner { return prefixedTransactioner{transactioner: transactioner, prefix: prefix} } func (p prefixedTransactioner) NewTransaction(readWrite bool) Transaction { txn := p.transactioner.NewTransaction(readWrite) return prefixedTransaction{ ReadWriter: NewPrefixedReadWriter(txn, p.prefix), transaction: txn, prefix: p.prefix, } } func (p prefixedTransactioner) NewWriteBatch() WriteBatch { return prefixedWriteBatch{ writeBatch: p.transactioner.NewWriteBatch(), prefix: p.prefix, } } func (p prefixedTransactioner) Update(handle func(ReadWriter) error) error { return p.transactioner.Update(func(txn ReadWriter) error { return handle(NewPrefixedReadWriter(txn, p.prefix)) }) } func (p prefixedTransactioner) View(handle func(ReadWriter) error) error { return p.transactioner.View(func(txn ReadWriter) error { return handle(NewPrefixedReadWriter(txn, p.prefix)) }) } type prefixedTransaction struct { ReadWriter transaction Transaction prefix []byte } func (p prefixedTransaction) Commit() error { return p.transaction.Commit() } func (p prefixedTransaction) Discard() { p.transaction.Discard() } type prefixedWriteBatch struct { writeBatch WriteBatch prefix []byte } func (p prefixedWriteBatch) Set(key, value []byte) error { return p.writeBatch.Set(addPrefix(p.prefix, key), value) } func (p prefixedWriteBatch) Delete(key []byte) error { return p.writeBatch.Delete(addPrefix(p.prefix, key)) } func (p prefixedWriteBatch) Flush() error { return p.writeBatch.Flush() } func (p prefixedWriteBatch) Cancel() { p.writeBatch.Cancel() } type prefixedReadWriter struct { readWriter ReadWriter prefix []byte } // NewPrefixedReadWriter returns ReadWriter that wraps the given read writer // and prefixes every key with the given prefix. func NewPrefixedReadWriter(readWriter ReadWriter, prefix []byte) ReadWriter { return prefixedReadWriter{ readWriter: readWriter, prefix: prefix, } } func (p prefixedReadWriter) NewIterator(opts IteratorOptions) Iterator { opts.Prefix = addPrefix(p.prefix, opts.Prefix) return prefixedIterator{ iterator: p.readWriter.NewIterator(opts), prefix: p.prefix, } } func (p prefixedReadWriter) Get(key []byte) (Item, error) { item, err := p.readWriter.Get(addPrefix(p.prefix, key)) if err != nil { return nil, err } return newPrefixedItem(item, p.prefix), nil } func (p prefixedReadWriter) Set(key, value []byte) error { return p.readWriter.Set(addPrefix(p.prefix, key), value) } func (p prefixedReadWriter) Delete(key []byte) error { return p.readWriter.Delete(addPrefix(p.prefix, key)) } type prefixedIterator struct { iterator Iterator prefix []byte } func (p prefixedIterator) Rewind() { p.iterator.Rewind() } func (p prefixedIterator) Next() { p.iterator.Next() } func (p prefixedIterator) Item() Item { return newPrefixedItem(p.iterator.Item(), p.prefix) } func (p prefixedIterator) Valid() bool { return p.iterator.Valid() } func (p prefixedIterator) Close() { p.iterator.Close() } func (p prefixedIterator) Seek(key []byte) { p.iterator.Seek(addPrefix(p.prefix, key)) } type prefixedItem struct { item Item prefix []byte } func newPrefixedItem(item Item, prefix []byte) prefixedItem { return prefixedItem{ item: item, prefix: prefix, } } func (p prefixedItem) Key() []byte { return p.item.Key()[len(p.prefix):] } func (p prefixedItem) Value(handle func([]byte) error) error { return p.item.Value(handle) } func (p prefixedItem) ValueCopy(dst []byte) ([]byte, error) { return p.item.ValueCopy(dst) } func addPrefix(prefix, key []byte) []byte { prefixedKey := make([]byte, 0, len(prefix)+len(key)) return append(append(prefixedKey, prefix...), key...) }