config.go 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // Copyright 2021 Andrew Werner.
  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
  12. // implied. See the License for the specific language governing
  13. // permissions and limitations under the License.
  14. package abstract
  15. // Config is used to configure the tree. It consists of a comparison function
  16. // for keys and any auxiliary data provided by the instantiator. It is provided
  17. // on the iterator and passed to the augmentation's Update method.
  18. type Config[K, V, A any] struct {
  19. // Updater is used to update the augmentations to the tree.
  20. Updater Updater[K, V, A]
  21. cmp func(K, K) int
  22. }
  23. // Updater is used to update the augmentation of the node when the subtree
  24. // changes.
  25. type Updater[K, V, A any] interface {
  26. // Update should update the augmentation of the passed node, optionally
  27. // using the data in the UpdataMeta to optimize the update. If the
  28. // augmentation changed, and thus, changes should occur in the ancestors
  29. // of the subtree rooted at this node, return true.
  30. Update(*Node[K, V, A], UpdateInfo[K, A]) (changed bool)
  31. }
  32. // UpdateInfo is used to describe the update operation.
  33. type UpdateInfo[K, A any] struct {
  34. // Action indicates the semantics of the below fields. If Default, no
  35. // fields will be populated.
  36. Action Action
  37. // ModifiedOther is the augmentation of a node which was either a previous
  38. // child (Removal), new child (Insertion), or represents the new
  39. // right-hand-side after a split.
  40. ModifiedOther *A
  41. // RelevantKey will be populated in all non-Default events.
  42. RelevantKey K
  43. }
  44. // Action is used to classify the type of Update in order to permit various
  45. // optimizations when updated the augmented state.
  46. type Action int
  47. const (
  48. // Default implies that no assumptions may be made with regards to the
  49. // change in state of the node and thus the augmented state should be
  50. // recalculated in full.
  51. Default Action = iota
  52. // Split indicates that this node is the left-hand side of a split.
  53. // The ModifiedOther will correspond to the updated state of the
  54. // augmentation for the right-hand side and the RelevantKey is the split
  55. // key to be moved into the parent.
  56. Split
  57. // Removal indicates that this is a removal event. If the RelevantNode is
  58. // populated, it indicates a rebalance which caused the node rooted
  59. // at that subtree to also be removed.
  60. Removal
  61. // Insertion indicates that this is a insertion event. If the RelevantNode is
  62. // populated, it indicates a rebalance which caused the node rooted
  63. // at that subtree to also be added.
  64. Insertion
  65. )
  66. // Compare compares two values using the same comparison function as the Map.
  67. func (c *Config[K, V, A]) Compare(a, b K) int { return c.cmp(a, b) }
  68. type config[K, V, A any] struct {
  69. Config[K, V, A]
  70. np *nodePool[K, V, A]
  71. }
  72. func makeConfig[K, V, A any](
  73. cmp func(K, K) int, up Updater[K, V, A],
  74. ) (c config[K, V, A]) {
  75. c.Updater = up
  76. c.cmp = cmp
  77. c.np = getNodePool[K, V, A]()
  78. return c
  79. }