go.ligato.io/vpp-agent/v3@v3.5.0/plugins/kvscheduler/txn_order.go (about)

     1  // Copyright (c) 2018 Cisco and/or its affiliates.
     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 kvscheduler
    16  
    17  import (
    18  	"sort"
    19  )
    20  
    21  // orderValuesByOp orders values by operations (in average should yield the shortest
    22  // sequence of operations):
    23  //  1. delete
    24  //  2. update with re-create
    25  //  3. create
    26  //  4. update
    27  func (s *Scheduler) orderValuesByOp(values []kvForTxn) []kvForTxn {
    28  	graphR := s.graph.Read()
    29  	defer graphR.Release()
    30  
    31  	// first order values alphabetically by keys to get deterministic behaviour and
    32  	// output that is easier to read
    33  	sort.Slice(values, func(i, j int) bool {
    34  		return values[i].key < values[j].key
    35  	})
    36  
    37  	// sort values by operations
    38  	var delete, recreate, create, update []kvForTxn
    39  	for _, kv := range values {
    40  		descriptor := s.registry.GetDescriptorForKey(kv.key)
    41  		handler := newDescriptorHandler(descriptor)
    42  		node := graphR.GetNode(kv.key)
    43  
    44  		if kv.value == nil {
    45  			delete = append(delete, kv)
    46  			continue
    47  		}
    48  		if node == nil || node.GetFlag(UnavailValueFlagIndex) != nil {
    49  			create = append(create, kv)
    50  			continue
    51  		}
    52  		if handler.updateWithRecreate(kv.key, node.GetValue(), kv.value, node.GetMetadata()) {
    53  			recreate = append(recreate, kv)
    54  		} else {
    55  			update = append(update, kv)
    56  		}
    57  	}
    58  
    59  	ordered := make([]kvForTxn, 0, len(values))
    60  	ordered = append(ordered, delete...)
    61  	ordered = append(ordered, recreate...)
    62  	ordered = append(ordered, create...)
    63  	ordered = append(ordered, update...)
    64  	return ordered
    65  }