Documentation ¶
Overview ¶
Package memdb provides an in-memory database that supports transactions and MVCC.
Index ¶
- Variables
- func IsIntType(k reflect.Kind) (size int, okay bool)
- func IsUintType(k reflect.Kind) (size int, okay bool)
- type BoolFieldIndex
- type Change
- type Changes
- type CompoundIndex
- type CompoundMultiIndex
- type ConditionalIndex
- type ConditionalIndexFunc
- type DBSchema
- type FieldSetIndex
- type FilterFunc
- type FilterIterator
- type IndexSchema
- type Indexer
- type IntFieldIndex
- 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) Changes() Changes
- 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) GetReverse(table, index string, args ...interface{}) (ResultIterator, error)
- func (txn *Txn) Insert(table string, obj interface{}) error
- func (txn *Txn) Last(table, index string, args ...interface{}) (interface{}, error)
- func (txn *Txn) LastWatch(table, index string, args ...interface{}) (<-chan struct{}, interface{}, error)
- func (txn *Txn) LongestPrefix(table, index string, args ...interface{}) (interface{}, error)
- func (txn *Txn) LowerBound(table, index string, args ...interface{}) (ResultIterator, error)
- func (txn *Txn) ReverseLowerBound(table, index string, args ...interface{}) (ResultIterator, error)
- func (txn *Txn) Snapshot() *Txn
- func (txn *Txn) TrackChanges()
- type UUIDFieldIndex
- type UintFieldIndex
- type WatchSet
- func (w WatchSet) Add(watchCh <-chan struct{})
- func (w WatchSet) AddWithLimit(softLimit int, watchCh <-chan struct{}, altCh <-chan struct{})
- func (w WatchSet) Watch(timeoutCh <-chan time.Time) bool
- func (w WatchSet) WatchCh(ctx context.Context) <-chan error
- func (w WatchSet) WatchCtx(ctx context.Context) error
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 BoolFieldIndex ¶ added in v1.1.1
type BoolFieldIndex struct {
Field string
}
BoolFieldIndex is used to extract an boolean field from an object using reflection and builds an index on that field.
func (*BoolFieldIndex) FromArgs ¶ added in v1.1.1
func (i *BoolFieldIndex) FromArgs(args ...interface{}) ([]byte, error)
func (*BoolFieldIndex) FromObject ¶ added in v1.1.1
func (i *BoolFieldIndex) FromObject(obj interface{}) (bool, []byte, error)
type Change ¶ added in v1.1.0
type Change struct { Table string Before interface{} After interface{} // contains filtered or unexported fields }
Change describes a mutation to an object in a table.
func (*Change) Created ¶ added in v1.1.0
Created returns true if the mutation describes a new object being inserted.
type Changes ¶ added in v1.1.0
type Changes []Change
Changes describes a set of mutations to memDB tables performed during a transaction.
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 CompoundMultiIndex ¶ added in v1.0.2
type CompoundMultiIndex 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, // CompoundMultiIndex requires all indexers to be satisfied. AllowMissing bool }
CompoundMultiIndex is used to build an index using multiple sub-indexes.
Unlike CompoundIndex, CompoundMultiIndex can have both SingleIndexer and MultiIndexer sub-indexers. However, each MultiIndexer adds considerable overhead/complexity in terms of the number of indexes created under-the-hood. It is not suggested to use more than one or two, if possible.
Another change from CompoundIndexer is that if AllowMissing is set, not only is it valid to have empty index fields, but it will still create index values up to the first empty index. This means that if you have a value with an empty field, rather than using a prefix for lookup, you can simply pass in less arguments. As an example, if {Foo, Bar} is indexed but Bar is missing for a value and AllowMissing is set, an index will still be created for {Foo} and it is valid to do a lookup passing in only Foo as an argument. Note that the ordering isn't guaranteed -- it's last-insert wins, but this is true if you have two objects that have the same indexes not using AllowMissing anyways.
Because StringMapFieldIndexers can take a varying number of args, it is currently a requirement that whenever it is used, two arguments must _always_ be provided for it. In theory we only need one, except a bug in that indexer means the single-argument version will never work. You can leave the second argument nil, but it will never produce a value. We support this for whenever that bug is fixed, likely in a next major version bump.
Prefix-based indexing is not currently supported.
func (*CompoundMultiIndex) FromArgs ¶ added in v1.0.2
func (c *CompoundMultiIndex) FromArgs(args ...interface{}) ([]byte, error)
func (*CompoundMultiIndex) FromObject ¶ added in v1.0.2
func (c *CompoundMultiIndex) FromObject(raw interface{}) (bool, [][]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(iter ResultIterator, filter FilterFunc) *FilterIterator
NewFilterIterator wraps a ResultIterator. The filter function is applied to each value returned by a call to iter.Next.
See the documentation for ResultIterator to understand the behaviour of the returned 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 IntFieldIndex ¶ added in v1.0.1
type IntFieldIndex struct {
Field string
}
IntFieldIndex is used to extract an int field from an object using reflection and builds an index on that field.
func (*IntFieldIndex) FromArgs ¶ added in v1.0.1
func (i *IntFieldIndex) FromArgs(args ...interface{}) ([]byte, error)
func (*IntFieldIndex) FromObject ¶ added in v1.0.1
func (i *IntFieldIndex) FromObject(obj interface{}) (bool, []byte, error)
type MemDB ¶
type MemDB struct {
// contains filtered or unexported fields
}
MemDB is an in-memory database providing Atomicity, Consistency, and Isolation from ACID. MemDB doesn't provide Durability since it 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.
Objects inserted into MemDB are not copied. It is **extremely important** that objects are not modified in-place after they are inserted since they are stored directly in MemDB. It remains unsafe to modify inserted objects even after they've been deleted from MemDB since there may still be older snapshots of the DB being read from other goroutines.
func (*MemDB) DBSchema ¶ added in v1.3.3
DBSchema returns schema in use for introspection.
The method is intended for *read-only* debugging use cases, returned schema should *never be modified in-place*.
func (*MemDB) Snapshot ¶
Snapshot is used to capture a point-in-time snapshot of the database that will not be affected by any write operations to the existing DB.
If MemDB is storing reference-based values (pointers, maps, slices, etc.), the Snapshot will not deep copy those values. Therefore, it is still unsafe to modify any inserted values in either DB.
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 returns the next result from the iterator. If there are no more results // nil is returned. Next() interface{} }
ResultIterator is used to iterate over a list of results from a query on a table.
When a ResultIterator is created from a write transaction, the results from Next will reflect a snapshot of the table at the time the ResultIterator is created. This means that calling Insert or Delete on a transaction while iterating is allowed, but the changes made by Insert or Delete will not be observed in the results returned from subsequent calls to Next. For example if an item is deleted from the index used by the iterator it will still be returned by Next. If an item is inserted into the index used by the iterator, it will not be returned by Next. However, an iterator created after a call to Insert or Delete will reflect the modifications.
When a ResultIterator is created from a write transaction, and there are already modifications to the index used by the iterator, the modification cache of the index will be invalidated. This may result in some additional allocations if the same node in the index is modified again.
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.
Note that although FromArgs in theory supports using either one or two arguments, there is a bug: FromObject only creates an index using key/value, and does not also create an index using key. This means a lookup using one argument will never actually work.
It is currently left as-is to prevent backwards compatibility issues.
TODO: Fix this in the next major bump.
func (*StringMapFieldIndex) FromArgs ¶
func (s *StringMapFieldIndex) FromArgs(args ...interface{}) ([]byte, error)
WARNING: Because of a bug in FromObject, this function will never return a value when using the single-argument version.
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, already aborted or commited transactions.
func (*Txn) Changes ¶ added in v1.1.0
Changes returns the set of object changes that have been made in the transaction so far. If change tracking is not enabled it wil always return nil. It can be called before or after Commit. If it is before Commit it will return all changes made so far which may not be the same as the final Changes. After abort it will always return nil. As with other Txn methods it's not safe to call this from a different goroutine than the one making mutations or committing the transaction. Mutations will appear in the order they were performed in the transaction but multiple operations to the same object will be collapsed so only the effective overall change to that object is present. If transaction operations are dependent (e.g. copy object X to Y then delete X) this might mean the set of mutations is incomplete to verify history, but it is complete in that the net effect is preserved (Y got a new value, X got removed).
func (*Txn) Commit ¶
func (txn *Txn) Commit()
Commit is used to finalize this transaction. This is a noop for read transactions, already aborted or committed 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.
Note that all values read in the transaction form a consistent snapshot from the time when the transaction was created.
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.
Note that all values read in the transaction form a consistent snapshot from the time when the transaction was created.
The watch channel is closed when a subsequent write transaction has updated the result of the query. Since each read transaction operates on an isolated snapshot, a new read transaction must be started to observe the changes that have been made.
If the value of index ends with "_prefix", FirstWatch will perform a prefix match instead of full match on the index. The registered indexer must implement PrefixIndexer, otherwise an error is returned.
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. The index values must match exactly (this is not a range-based or prefix-based lookup) by default.
Prefix lookups: if the named index implements PrefixIndexer, you may perform prefix-based lookups by appending "_prefix" to the index name. In this scenario, the index values given in args are treated as prefix lookups. For example, a StringFieldIndex will match any string with the given value as a prefix: "mem" matches "memdb".
See the documentation for ResultIterator to understand the behaviour of the returned ResultIterator.
func (*Txn) GetReverse ¶ added in v1.3.0
func (txn *Txn) GetReverse(table, index string, args ...interface{}) (ResultIterator, error)
GetReverse is used to construct a Reverse ResultIterator over all the rows that match the given constraints of an index. The returned ResultIterator's Next() will return the next Previous value.
See the documentation on Get for details on arguments.
See the documentation for ResultIterator to understand the behaviour of the returned ResultIterator.
func (*Txn) Insert ¶
Insert is used to add or update an object into the given table.
When updating an object, the obj provided should be a copy rather than a value updated in-place. Modifying values in-place that are already inserted into MemDB is not supported behavior.
func (*Txn) Last ¶ added in v1.3.0
Last is used to return the last matching object for the given constraints on the index.
Note that all values read in the transaction form a consistent snapshot from the time when the transaction was created.
func (*Txn) LastWatch ¶ added in v1.3.0
func (txn *Txn) LastWatch(table, index string, args ...interface{}) (<-chan struct{}, interface{}, error)
LastWatch is used to return the last matching object for the given constraints on the index along with the watch channel.
Note that all values read in the transaction form a consistent snapshot from the time when the transaction was created.
The watch channel is closed when a subsequent write transaction has updated the result of the query. Since each read transaction operates on an isolated snapshot, a new read transaction must be started to observe the changes that have been made.
If the value of index ends with "_prefix", LastWatch will perform a prefix match instead of full match on the index. The registered indexer must implement PrefixIndexer, otherwise an error is returned.
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.
Note that all values read in the transaction form a consistent snapshot from the time when the transaction was created.
func (*Txn) LowerBound ¶ added in v1.0.3
func (txn *Txn) LowerBound(table, index string, args ...interface{}) (ResultIterator, error)
LowerBound is used to construct a ResultIterator over all the the range of rows that have an index value greater than or equal to the provide args. Calling this then iterating until the rows are larger than required allows range scans within an index. It is not possible to watch the resulting iterator since the radix tree doesn't efficiently allow watching on lower bound changes. The WatchCh returned will be nill and so will block forever.
If the value of index ends with "_prefix", LowerBound will perform a prefix match instead of a full match on the index. The registered index must implement PrefixIndexer, otherwise an error is returned.
See the documentation for ResultIterator to understand the behaviour of the returned ResultIterator.
func (*Txn) ReverseLowerBound ¶ added in v1.3.0
func (txn *Txn) ReverseLowerBound(table, index string, args ...interface{}) (ResultIterator, error)
ReverseLowerBound is used to construct a Reverse ResultIterator over all the the range of rows that have an index value less than or equal to the provide args. Calling this then iterating until the rows are lower than required allows range scans within an index. It is not possible to watch the resulting iterator since the radix tree doesn't efficiently allow watching on lower bound changes. The WatchCh returned will be nill and so will block forever.
See the documentation for ResultIterator to understand the behaviour of the returned ResultIterator.
func (*Txn) Snapshot ¶ added in v1.2.0
Snapshot creates a snapshot of the current state of the transaction. Returns a new read-only transaction or nil if the transaction is already aborted or committed.
func (*Txn) TrackChanges ¶ added in v1.1.0
func (txn *Txn) TrackChanges()
TrackChanges enables change tracking for the transaction. If called at any point before commit, subsequent mutations will be recorded and can be retrieved using ChangeSet. Once this has been called on a transaction it can't be unset. As with other Txn methods it's not safe to call this from a different goroutine than the one making mutations or committing the transaction.
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. The zero value is not usable. Use NewWatchSet to create a WatchSet.
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 of an iterator higher up in the radix tree) that will watch a superset of items.
func (WatchSet) Watch ¶
Watch blocks until one of the channels in the watch set is closed, or timeoutCh sends a value. Returns true if timeoutCh is what caused Watch to unblock.
func (WatchSet) WatchCh ¶ added in v1.2.1
WatchCh returns a channel that is used to wait for any channel of the watch set to trigger or for the context to be cancelled. WatchCh creates a new goroutine each call, so callers may need to cache the returned channel to avoid creating extra goroutines.