99 lines
3.2 KiB
Go
99 lines
3.2 KiB
Go
// 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
|
|
}
|