From cae4b2c0eb954622309ed92e9e6bc45d0ee5afda Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Thu, 28 Jan 2021 17:19:55 -0500 Subject: [PATCH] Update go-memdb To use a version that will not panic when an iterator is used with modifications. --- go.mod | 2 +- go.sum | 4 +- .../github.com/hashicorp/go-memdb/filter.go | 11 +++-- vendor/github.com/hashicorp/go-memdb/txn.go | 49 +++++++++++++++---- vendor/modules.txt | 2 +- 5 files changed, 51 insertions(+), 17 deletions(-) diff --git a/go.mod b/go.mod index cb4e79192b..a4bdef6de7 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( github.com/hashicorp/go-connlimit v0.3.0 github.com/hashicorp/go-discover v0.0.0-20200501174627-ad1e96bde088 github.com/hashicorp/go-hclog v0.14.1 - github.com/hashicorp/go-memdb v1.3.0 + github.com/hashicorp/go-memdb v1.3.1 github.com/hashicorp/go-msgpack v0.5.5 github.com/hashicorp/go-multierror v1.1.0 github.com/hashicorp/go-raftchunking v0.6.1 diff --git a/go.sum b/go.sum index b3e7c9a346..f3abf59c30 100644 --- a/go.sum +++ b/go.sum @@ -240,8 +240,8 @@ github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjh github.com/hashicorp/go-immutable-radix v1.3.0 h1:8exGP7ego3OmkfksihtSouGMZ+hQrhxx+FVELeXpVPE= github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-kms-wrapping/entropy v0.1.0/go.mod h1:d1g9WGtAunDNpek8jUIEJnBlbgKS1N2Q61QkHiZyR1g= -github.com/hashicorp/go-memdb v1.3.0 h1:xdXq34gBOMEloa9rlGStLxmfX/dyIK8htOv36dQUwHU= -github.com/hashicorp/go-memdb v1.3.0/go.mod h1:Mluclgwib3R93Hk5fxEfiRhB+6Dar64wWh71LpNSe3g= +github.com/hashicorp/go-memdb v1.3.1 h1:EIj6L28rTL41BDHBvwq1VJXzcmY2R2JBrxpWxF7Etyk= +github.com/hashicorp/go-memdb v1.3.1/go.mod h1:Mluclgwib3R93Hk5fxEfiRhB+6Dar64wWh71LpNSe3g= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= diff --git a/vendor/github.com/hashicorp/go-memdb/filter.go b/vendor/github.com/hashicorp/go-memdb/filter.go index 2e3a9b3f7b..0071ab311a 100644 --- a/vendor/github.com/hashicorp/go-memdb/filter.go +++ b/vendor/github.com/hashicorp/go-memdb/filter.go @@ -13,17 +13,22 @@ type FilterIterator struct { iter ResultIterator } -func NewFilterIterator(wrap 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 NewFilterIterator(iter ResultIterator, filter FilterFunc) *FilterIterator { return &FilterIterator{ filter: filter, - iter: wrap, + iter: iter, } } // WatchCh returns the watch channel of the wrapped iterator. func (f *FilterIterator) WatchCh() <-chan struct{} { return f.iter.WatchCh() } -// Next returns the next non-filtered result from the wrapped iterator +// Next returns the next non-filtered result from the wrapped iterator. func (f *FilterIterator) Next() interface{} { for { if value := f.iter.Next(); value == nil || !f.filter(value) { diff --git a/vendor/github.com/hashicorp/go-memdb/txn.go b/vendor/github.com/hashicorp/go-memdb/txn.go index 68734e37c8..177d361122 100644 --- a/vendor/github.com/hashicorp/go-memdb/txn.go +++ b/vendor/github.com/hashicorp/go-memdb/txn.go @@ -52,16 +52,16 @@ func (txn *Txn) TrackChanges() { } } -// readableIndex returns a transaction usable for reading the given -// index in a table. If a write transaction is in progress, we may need -// to use an existing modified txn. +// readableIndex returns a transaction usable for reading the given index in a +// table. If the transaction is a write transaction with modifications, a clone of the +// modified index will be returned. func (txn *Txn) readableIndex(table, index string) *iradix.Txn { // Look for existing transaction if txn.write && txn.modified != nil { key := tableIndex{table, index} exist, ok := txn.modified[key] if ok { - return exist + return exist.Clone() } } @@ -663,15 +663,35 @@ func (txn *Txn) getIndexValue(table, index string, args ...interface{}) (*IndexS return indexSchema, val, err } -// ResultIterator is used to iterate over a list of results -// from a Get query on a table. +// 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 ResultIterator interface { WatchCh() <-chan struct{} + // Next returns the next result from the iterator. If there are no more results + // nil is returned. Next() interface{} } -// Get is used to construct a ResultIterator over all the -// rows that match the given constraints of an index. +// Get is used to construct a ResultIterator over all the rows that match the +// given constraints of an index. +// +// See the documentation for ResultIterator to understand the behaviour of the +// returned ResultIterator. func (txn *Txn) Get(table, index string, args ...interface{}) (ResultIterator, error) { indexIter, val, err := txn.getIndexIterator(table, index, args...) if err != nil { @@ -691,7 +711,10 @@ func (txn *Txn) Get(table, index string, args ...interface{}) (ResultIterator, e // 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 +// The returned ResultIterator's Next() will return the next Previous value. +// +// See the documentation for ResultIterator to understand the behaviour of the +// returned ResultIterator. func (txn *Txn) GetReverse(table, index string, args ...interface{}) (ResultIterator, error) { indexIter, val, err := txn.getIndexIteratorReverse(table, index, args...) if err != nil { @@ -715,6 +738,9 @@ func (txn *Txn) GetReverse(table, index string, args ...interface{}) (ResultIter // 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 *Txn) LowerBound(table, index string, args ...interface{}) (ResultIterator, error) { indexIter, val, err := txn.getIndexIterator(table, index, args...) if err != nil { @@ -738,6 +764,9 @@ func (txn *Txn) LowerBound(table, index string, args ...interface{}) (ResultIter // 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 *Txn) ReverseLowerBound(table, index string, args ...interface{}) (ResultIterator, error) { indexIter, val, err := txn.getIndexIteratorReverse(table, index, args...) if err != nil { @@ -850,7 +879,7 @@ func (txn *Txn) getIndexIterator(table, index string, args ...interface{}) (*ira indexTxn := txn.readableIndex(table, indexSchema.Name) indexRoot := indexTxn.Root() - // Get an interator over the index + // Get an iterator over the index indexIter := indexRoot.Iterator() return indexIter, val, nil } diff --git a/vendor/modules.txt b/vendor/modules.txt index 4bd16dde9f..65f914cff7 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -231,7 +231,7 @@ github.com/hashicorp/go-discover/provider/vsphere github.com/hashicorp/go-hclog # github.com/hashicorp/go-immutable-radix v1.3.0 github.com/hashicorp/go-immutable-radix -# github.com/hashicorp/go-memdb v1.3.0 +# github.com/hashicorp/go-memdb v1.3.1 github.com/hashicorp/go-memdb # github.com/hashicorp/go-msgpack v0.5.5 github.com/hashicorp/go-msgpack/codec