| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- // Copyright 2021 Andrew Werner.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- // implied. See the License for the specific language governing
- // permissions and limitations under the License.
- package abstract
- // Config is used to configure the tree. It consists of a comparison function
- // for keys and any auxiliary data provided by the instantiator. It is provided
- // on the iterator and passed to the augmentation's Update method.
- type Config[K, V, A any] struct {
- // Updater is used to update the augmentations to the tree.
- Updater Updater[K, V, A]
- cmp func(K, K) int
- }
- // Updater is used to update the augmentation of the node when the subtree
- // changes.
- type Updater[K, V, A any] interface {
- // Update should update the augmentation of the passed node, optionally
- // using the data in the UpdataMeta to optimize the update. If the
- // augmentation changed, and thus, changes should occur in the ancestors
- // of the subtree rooted at this node, return true.
- Update(*Node[K, V, A], UpdateInfo[K, A]) (changed bool)
- }
- // UpdateInfo is used to describe the update operation.
- type UpdateInfo[K, A any] struct {
- // Action indicates the semantics of the below fields. If Default, no
- // fields will be populated.
- Action Action
- // ModifiedOther is the augmentation of a node which was either a previous
- // child (Removal), new child (Insertion), or represents the new
- // right-hand-side after a split.
- ModifiedOther *A
- // RelevantKey will be populated in all non-Default events.
- RelevantKey K
- }
- // Action is used to classify the type of Update in order to permit various
- // optimizations when updated the augmented state.
- type Action int
- const (
- // Default implies that no assumptions may be made with regards to the
- // change in state of the node and thus the augmented state should be
- // recalculated in full.
- Default Action = iota
- // Split indicates that this node is the left-hand side of a split.
- // The ModifiedOther will correspond to the updated state of the
- // augmentation for the right-hand side and the RelevantKey is the split
- // key to be moved into the parent.
- Split
- // Removal indicates that this is a removal event. If the RelevantNode is
- // populated, it indicates a rebalance which caused the node rooted
- // at that subtree to also be removed.
- Removal
- // Insertion indicates that this is a insertion event. If the RelevantNode is
- // populated, it indicates a rebalance which caused the node rooted
- // at that subtree to also be added.
- Insertion
- )
- // Compare compares two values using the same comparison function as the Map.
- func (c *Config[K, V, A]) Compare(a, b K) int { return c.cmp(a, b) }
- type config[K, V, A any] struct {
- Config[K, V, A]
- np *nodePool[K, V, A]
- }
- func makeConfig[K, V, A any](
- cmp func(K, K) int, up Updater[K, V, A],
- ) (c config[K, V, A]) {
- c.Updater = up
- c.cmp = cmp
- c.np = getNodePool[K, V, A]()
- return c
- }
|