diff options
| author | Miguel Pires <miguel.pires@canonical.com> | 2023-07-28 09:34:50 +0100 |
|---|---|---|
| committer | Miguel Pires <miguelpires94@gmail.com> | 2023-08-01 14:25:48 +0100 |
| commit | ab6d918d8be99b437e902674bd4bf3806d1f0e2b (patch) | |
| tree | e54e7dcc9b6b24f90eab312cc8d914fd04e7748c | |
| parent | 0b69df78e4a9b8d9c603fccbed4fbdacaf591a25 (diff) | |
aspects: optimise aspect tx Get
Cache a copy of the transaction's databag so that a new one doesn't have to be created and all the deltas applied.
| -rw-r--r-- | aspects/transaction.go | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/aspects/transaction.go b/aspects/transaction.go index dde36b2dad..0eaa2eb717 100644 --- a/aspects/transaction.go +++ b/aspects/transaction.go @@ -28,9 +28,12 @@ type DatabagWrite func(JSONDataBag) error // Transaction performs read and writes to a databag in an atomic way. type Transaction struct { pristine JSONDataBag - deltas []map[string]interface{} schema Schema + modified JSONDataBag + deltas []map[string]interface{} + appliedDeltas int + readDatabag DatabagRead writeDatabag DatabagWrite mu sync.RWMutex @@ -65,17 +68,26 @@ func (t *Transaction) Get(path string, value interface{}) error { t.mu.RLock() defer t.mu.RUnlock() - // if there are changes, create a copy before applying (for isolation) - bag := t.pristine - if len(t.deltas) != 0 { - bag = t.pristine.Copy() + // if there aren't any changes, just use the pristine bag + if len(t.deltas) == 0 { + return t.pristine.Get(path, value) + } - if err := applyDeltas(bag, t.deltas); err != nil { - return err - } + // if there are changes, use a cached bag with modifications to do the Get + if t.modified == nil { + t.modified = t.pristine.Copy() + t.appliedDeltas = 0 + } + + // apply new changes since the last get + if err := applyDeltas(t.modified, t.deltas[t.appliedDeltas:]); err != nil { + t.modified = nil + t.appliedDeltas = 0 + return err } + t.appliedDeltas = len(t.deltas) - return bag.Get(path, value) + return t.modified.Get(path, value) } // Commit applies the previous writes and validates the final databag. If any @@ -113,7 +125,9 @@ func (t *Transaction) Commit() error { } t.pristine = pristine + t.modified = nil t.deltas = nil + t.appliedDeltas = 0 return nil } |
