"Fossies" - the Fresh Open Source Software Archive

Member "cri-o-1.25.1/vendor/go.etcd.io/etcd/server/v3/storage/schema/actions.go" (7 Oct 2022, 2656 Bytes) of package /linux/misc/cri-o-1.25.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Go source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 // Copyright 2021 The etcd Authors
    2 //
    3 // Licensed under the Apache License, Version 2.0 (the "License");
    4 // you may not use this file except in compliance with the License.
    5 // You may obtain a copy of the License at
    6 //
    7 //     http://www.apache.org/licenses/LICENSE-2.0
    8 //
    9 // Unless required by applicable law or agreed to in writing, software
   10 // distributed under the License is distributed on an "AS IS" BASIS,
   11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   12 // See the License for the specific language governing permissions and
   13 // limitations under the License.
   14 
   15 package schema
   16 
   17 import (
   18     "go.etcd.io/etcd/server/v3/storage/backend"
   19     "go.uber.org/zap"
   20 )
   21 
   22 type action interface {
   23     // unsafeDo executes the action and returns revert action, when executed
   24     // should restore the state from before.
   25     unsafeDo(tx backend.BatchTx) (revert action, err error)
   26 }
   27 
   28 type setKeyAction struct {
   29     Bucket     backend.Bucket
   30     FieldName  []byte
   31     FieldValue []byte
   32 }
   33 
   34 func (a setKeyAction) unsafeDo(tx backend.BatchTx) (action, error) {
   35     revert := restoreFieldValueAction(tx, a.Bucket, a.FieldName)
   36     tx.UnsafePut(a.Bucket, a.FieldName, a.FieldValue)
   37     return revert, nil
   38 }
   39 
   40 type deleteKeyAction struct {
   41     Bucket    backend.Bucket
   42     FieldName []byte
   43 }
   44 
   45 func (a deleteKeyAction) unsafeDo(tx backend.BatchTx) (action, error) {
   46     revert := restoreFieldValueAction(tx, a.Bucket, a.FieldName)
   47     tx.UnsafeDelete(a.Bucket, a.FieldName)
   48     return revert, nil
   49 }
   50 
   51 func restoreFieldValueAction(tx backend.BatchTx, bucket backend.Bucket, fieldName []byte) action {
   52     _, vs := tx.UnsafeRange(bucket, fieldName, nil, 1)
   53     if len(vs) == 1 {
   54         return &setKeyAction{
   55             Bucket:     bucket,
   56             FieldName:  fieldName,
   57             FieldValue: vs[0],
   58         }
   59     }
   60     return &deleteKeyAction{
   61         Bucket:    bucket,
   62         FieldName: fieldName,
   63     }
   64 }
   65 
   66 type ActionList []action
   67 
   68 // unsafeExecute executes actions one by one. If one of actions returns error,
   69 // it will revert them.
   70 func (as ActionList) unsafeExecute(lg *zap.Logger, tx backend.BatchTx) error {
   71     var revertActions = make(ActionList, 0, len(as))
   72     for _, a := range as {
   73         revert, err := a.unsafeDo(tx)
   74 
   75         if err != nil {
   76             revertActions.unsafeExecuteInReversedOrder(lg, tx)
   77             return err
   78         }
   79         revertActions = append(revertActions, revert)
   80     }
   81     return nil
   82 }
   83 
   84 // unsafeExecuteInReversedOrder executes actions in revered order. Will panic on
   85 // action error. Should be used when reverting.
   86 func (as ActionList) unsafeExecuteInReversedOrder(lg *zap.Logger, tx backend.BatchTx) {
   87     for j := len(as) - 1; j >= 0; j-- {
   88         _, err := as[j].unsafeDo(tx)
   89         if err != nil {
   90             lg.Panic("Cannot recover from revert error", zap.Error(err))
   91         }
   92     }
   93 }