Documentation ¶
Overview ¶
Package memdb provides an in-memory database that supports transactions and MVCC.
Index ¶
- Variables
- func IsUintType(k reflect.Kind) (size int, okay bool)
- type CompoundIndex
- type ConditionalIndex
- type ConditionalIndexFunc
- type DBSchema
- type FieldSetIndex
- type FilterFunc
- type FilterIterator
- type IndexSchema
- type Indexer
- type MemDB
- type MultiIndexer
- type PrefixIndexer
- type ResultIterator
- type SingleIndexer
- type StringFieldIndex
- type StringMapFieldIndex
- type StringSliceFieldIndex
- type TableSchema
- type Txn
- func (txn *Txn) Abort()
- func (txn *Txn) Commit()
- func (txn *Txn) Defer(fn func())
- func (txn *Txn) Delete(table string, obj interface{}) error
- func (txn *Txn) DeleteAll(table, index string, args ...interface{}) (int, error)
- func (txn *Txn) DeletePrefix(table string, prefix_index string, prefix string) (bool, error)
- func (txn *Txn) First(table, index string, args ...interface{}) (interface{}, error)
- func (txn *Txn) FirstWatch(table, index string, args ...interface{}) (<-chan struct{}, interface{}, error)
- func (txn *Txn) Get(table, index string, args ...interface{}) (ResultIterator, error)
- func (txn *Txn) Insert(table string, obj interface{}) error
- func (txn *Txn) LongestPrefix(table, index string, args ...interface{}) (interface{}, error)
- type UUIDFieldIndex
- type UintFieldIndex
- type WatchSet
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNotFound is returned when the requested item is not found ErrNotFound = fmt.Errorf("not found") )
Functions ¶
Types ¶
type CompoundIndex ¶
type CompoundIndex struct { Indexes []Indexer // AllowMissing results in an index based on only the indexers // that return data. If true, you may end up with 2/3 columns // indexed which might be useful for an index scan. Otherwise, // the CompoundIndex requires all indexers to be satisfied. AllowMissing bool }
CompoundIndex is used to build an index using multiple sub-indexes Prefix based iteration is supported as long as the appropriate prefix of indexers support it. All sub-indexers are only assumed to expect a single argument.
func (*CompoundIndex) FromArgs ¶
func (c *CompoundIndex) FromArgs(args ...interface{}) ([]byte, error)
func (*CompoundIndex) FromObject ¶
func (c *CompoundIndex) FromObject(raw interface{}) (bool, []byte, error)
func (*CompoundIndex) PrefixFromArgs ¶
func (c *CompoundIndex) PrefixFromArgs(args ...interface{}) ([]byte, error)
type ConditionalIndex ¶
type ConditionalIndex struct {
Conditional ConditionalIndexFunc
}
ConditionalIndex builds an index based on a condition specified by a passed user function. This function may examine the passed object and return a boolean to encapsulate an arbitrarily complex conditional.
func (*ConditionalIndex) FromArgs ¶
func (c *ConditionalIndex) FromArgs(args ...interface{}) ([]byte, error)
func (*ConditionalIndex) FromObject ¶
func (c *ConditionalIndex) FromObject(obj interface{}) (bool, []byte, error)
type ConditionalIndexFunc ¶
ConditionalIndexFunc is the required function interface for a ConditionalIndex.
type DBSchema ¶
type DBSchema struct { // Tables is the set of tables within this database. The key is the // table name and must match the Name in TableSchema. Tables map[string]*TableSchema }
DBSchema is the schema to use for the full database with a MemDB instance.
MemDB will require a valid schema. Schema validation can be tested using the Validate function. Calling this function is recommended in unit tests.
type FieldSetIndex ¶
type FieldSetIndex struct {
Field string
}
FieldSetIndex is used to extract a field from an object using reflection and builds an index on whether the field is set by comparing it against its type's nil value.
func (*FieldSetIndex) FromArgs ¶
func (f *FieldSetIndex) FromArgs(args ...interface{}) ([]byte, error)
func (*FieldSetIndex) FromObject ¶
func (f *FieldSetIndex) FromObject(obj interface{}) (bool, []byte, error)
type FilterFunc ¶
type FilterFunc func(interface{}) bool
FilterFunc is a function that takes the results of an iterator and returns whether the result should be filtered out.
type FilterIterator ¶
type FilterIterator struct {
// contains filtered or unexported fields
}
FilterIterator is used to wrap a ResultIterator and apply a filter over it.
func NewFilterIterator ¶
func NewFilterIterator(wrap ResultIterator, filter FilterFunc) *FilterIterator
func (*FilterIterator) Next ¶
func (f *FilterIterator) Next() interface{}
Next returns the next non-filtered result from the wrapped iterator
func (*FilterIterator) WatchCh ¶
func (f *FilterIterator) WatchCh() <-chan struct{}
WatchCh returns the watch channel of the wrapped iterator.
type IndexSchema ¶
type IndexSchema struct { // Name of the index. This must be unique among a tables set of indexes. // This must match the key in the map of Indexes for a TableSchema. Name string // AllowMissing if true ignores this index if it doesn't produce a // value. For example, an index that extracts a field that doesn't // exist from a structure. AllowMissing bool Unique bool Indexer Indexer }
IndexSchema is the schema for an index. An index defines how a table is queried.
func (*IndexSchema) Validate ¶
func (s *IndexSchema) Validate() error
type Indexer ¶
type Indexer interface { // FromArgs is called to build the exact index key from a list of arguments. FromArgs(args ...interface{}) ([]byte, error) }
Indexer is an interface used for defining indexes. Indexes are used for efficient lookup of objects in a MemDB table. An Indexer must also implement one of SingleIndexer or MultiIndexer.
Indexers are primarily responsible for returning the lookup key as a byte slice. The byte slice is the key data in the underlying data storage.
type MemDB ¶
type MemDB struct {
// contains filtered or unexported fields
}
MemDB is an in-memory database.
MemDB provides a table abstraction to store objects (rows) with multiple indexes based on inserted values. The database makes use of immutable radix trees to provide transactions and MVCC.
type MultiIndexer ¶
type MultiIndexer interface { // FromObject extracts index values from an object. The return values // are the same as a SingleIndexer except there can be multiple index // values. FromObject(raw interface{}) (bool, [][]byte, error) }
MultiIndexer is an interface used for defining indexes that generate multiple values per object. Each value is stored as a seperate index pointing to the same object.
For example, an index that extracts the first and last name of a person and allows lookup based on eitherd would be a MultiIndexer. The FromObject of this example would split the first and last name and return both as values.
type PrefixIndexer ¶
type PrefixIndexer interface { // PrefixFromArgs is the same as FromArgs for an Indexer except that // the index value returned should return all prefix-matched values. PrefixFromArgs(args ...interface{}) ([]byte, error) }
PrefixIndexer is an optional interface on top of an Indexer that allows indexes to support prefix-based iteration.
type ResultIterator ¶
type ResultIterator interface { WatchCh() <-chan struct{} Next() interface{} }
ResultIterator is used to iterate over a list of results from a Get query on a table.
type SingleIndexer ¶
type SingleIndexer interface { // FromObject extracts the index value from an object. The return values // are whether the index value was found, the index value, and any error // while extracting the index value, respectively. FromObject(raw interface{}) (bool, []byte, error) }
SingleIndexer is an interface used for defining indexes that generate a single value per object
type StringFieldIndex ¶
StringFieldIndex is used to extract a field from an object using reflection and builds an index on that field.
func (*StringFieldIndex) FromArgs ¶
func (s *StringFieldIndex) FromArgs(args ...interface{}) ([]byte, error)
func (*StringFieldIndex) FromObject ¶
func (s *StringFieldIndex) FromObject(obj interface{}) (bool, []byte, error)
func (*StringFieldIndex) PrefixFromArgs ¶
func (s *StringFieldIndex) PrefixFromArgs(args ...interface{}) ([]byte, error)
type StringMapFieldIndex ¶
StringMapFieldIndex is used to extract a field of type map[string]string from an object using reflection and builds an index on that field.
func (*StringMapFieldIndex) FromArgs ¶
func (s *StringMapFieldIndex) FromArgs(args ...interface{}) ([]byte, error)
func (*StringMapFieldIndex) FromObject ¶
func (s *StringMapFieldIndex) FromObject(obj interface{}) (bool, [][]byte, error)
type StringSliceFieldIndex ¶
StringSliceFieldIndex builds an index from a field on an object that is a string slice ([]string). Each value within the string slice can be used for lookup.
func (*StringSliceFieldIndex) FromArgs ¶
func (s *StringSliceFieldIndex) FromArgs(args ...interface{}) ([]byte, error)
func (*StringSliceFieldIndex) FromObject ¶
func (s *StringSliceFieldIndex) FromObject(obj interface{}) (bool, [][]byte, error)
func (*StringSliceFieldIndex) PrefixFromArgs ¶
func (s *StringSliceFieldIndex) PrefixFromArgs(args ...interface{}) ([]byte, error)
type TableSchema ¶
type TableSchema struct { // Name of the table. This must match the key in the Tables map in DBSchema. Name string // Indexes is the set of indexes for querying this table. The key // is a unique name for the index and must match the Name in the // IndexSchema. Indexes map[string]*IndexSchema }
TableSchema is the schema for a single table.
func (*TableSchema) Validate ¶
func (s *TableSchema) Validate() error
Validate is used to validate the table schema
type Txn ¶
type Txn struct {
// contains filtered or unexported fields
}
Txn is a transaction against a MemDB. This can be a read or write transaction.
func (*Txn) Abort ¶
func (txn *Txn) Abort()
Abort is used to cancel this transaction. This is a noop for read transactions.
func (*Txn) Commit ¶
func (txn *Txn) Commit()
Commit is used to finalize this transaction. This is a noop for read transactions.
func (*Txn) Defer ¶
func (txn *Txn) Defer(fn func())
Defer is used to push a new arbitrary function onto a stack which gets called when a transaction is committed and finished. Deferred functions are called in LIFO order, and only invoked at the end of write transactions.
func (*Txn) Delete ¶
Delete is used to delete a single object from the given table This object must already exist in the table
func (*Txn) DeleteAll ¶
DeleteAll is used to delete all the objects in a given table matching the constraints on the index
func (*Txn) DeletePrefix ¶
DeletePrefix is used to delete an entire subtree based on a prefix. The given index must be a prefix index, and will be used to perform a scan and enumerate the set of objects to delete. These will be removed from all other indexes, and then a special prefix operation will delete the objects from the given index in an efficient subtree delete operation. This is useful when you have a very large number of objects indexed by the given index, along with a much smaller number of entries in the other indexes for those objects.
func (*Txn) First ¶
First is used to return the first matching object for the given constraints on the index
func (*Txn) FirstWatch ¶
func (txn *Txn) FirstWatch(table, index string, args ...interface{}) (<-chan struct{}, interface{}, error)
FirstWatch is used to return the first matching object for the given constraints on the index along with the watch channel
func (*Txn) Get ¶
func (txn *Txn) Get(table, index string, args ...interface{}) (ResultIterator, error)
Get is used to construct a ResultIterator over all the rows that match the given constraints of an index.
func (*Txn) LongestPrefix ¶
LongestPrefix is used to fetch the longest prefix match for the given constraints on the index. Note that this will not work with the memdb StringFieldIndex because it adds null terminators which prevent the algorithm from correctly finding a match (it will get to right before the null and fail to find a leaf node). This should only be used where the prefix given is capable of matching indexed entries directly, which typically only applies to a custom indexer. See the unit test for an example.
type UUIDFieldIndex ¶
type UUIDFieldIndex struct {
Field string
}
UUIDFieldIndex is used to extract a field from an object using reflection and builds an index on that field by treating it as a UUID. This is an optimization to using a StringFieldIndex as the UUID can be more compactly represented in byte form.
func (*UUIDFieldIndex) FromArgs ¶
func (u *UUIDFieldIndex) FromArgs(args ...interface{}) ([]byte, error)
func (*UUIDFieldIndex) FromObject ¶
func (u *UUIDFieldIndex) FromObject(obj interface{}) (bool, []byte, error)
func (*UUIDFieldIndex) PrefixFromArgs ¶
func (u *UUIDFieldIndex) PrefixFromArgs(args ...interface{}) ([]byte, error)
type UintFieldIndex ¶
type UintFieldIndex struct {
Field string
}
UintFieldIndex is used to extract a uint field from an object using reflection and builds an index on that field.
func (*UintFieldIndex) FromArgs ¶
func (u *UintFieldIndex) FromArgs(args ...interface{}) ([]byte, error)
func (*UintFieldIndex) FromObject ¶
func (u *UintFieldIndex) FromObject(obj interface{}) (bool, []byte, error)
type WatchSet ¶
type WatchSet map[<-chan struct{}]struct{}
WatchSet is a collection of watch channels.
func (WatchSet) Add ¶
func (w WatchSet) Add(watchCh <-chan struct{})
Add appends a watchCh to the WatchSet if non-nil.
func (WatchSet) AddWithLimit ¶
AddWithLimit appends a watchCh to the WatchSet if non-nil, and if the given softLimit hasn't been exceeded. Otherwise, it will watch the given alternate channel. It's expected that the altCh will be the same on many calls to this function, so you will exceed the soft limit a little bit if you hit this, but not by much.
This is useful if you want to track individual items up to some limit, after which you watch a higher-level channel (usually a channel from start start of an iterator higher up in the radix tree) that will watch a superset of items.
func (WatchSet) Watch ¶
Watch is used to wait for either the watch set to trigger or a timeout. Returns true on timeout.