File: addrtrieiterator.go

package info (click to toggle)
golang-github-seancfoley-ipaddress-go 1.5.4-3
  • links: PTS, VCS
  • area: main
  • in suites: experimental, forky, sid, trixie
  • size: 3,700 kB
  • sloc: makefile: 3
file content (164 lines) | stat: -rw-r--r-- 6,147 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
//
// Copyright 2020-2022 Sean C Foley
//
// 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 ipaddr

import "github.com/seancfoley/bintree/tree"

type Cached = tree.C

// CachingTrieIterator is an iterator of a tree that allows you to cache an object with the
// lower or upper sub-node of the currently visited node.
// The cached object can be retrieved later when iterating the sub-node.
// That allows you to provide iteration context from a parent to its sub-nodes when iterating,
// but can only be provided with iterators in which parent nodes are visited before their sub-nodes.
// The caching and retrieval is done in constant-time.
type CachingTrieIterator[T any] interface {
	IteratorWithRemove[T]

	// Note: We could theoretically try to make the cached type generic.
	// But the problem with that is that the iterator methods that return them cannot be generic on their own, the whole type would need to specify the cache type.
	// The other problem is that even if we could, some callers would not care about the caching behaviour and thus would not want to have to specify a cache type.

	// GetCached returns an object previously cached with the current iterated node.
	// After Next has returned a node,
	// if an object was cached by a call to CacheWithLowerSubNode or CacheWithUpperSubNode
	// was called when that node's parent was previously returned by Next,
	// then this returns that cached object.
	GetCached() Cached

	// CacheWithLowerSubNode caches an object with the lower sub-node of the current iterated node.
	// After Next has returned a node,
	// calling this method caches the provided object with the lower sub-node so that it can
	// be retrieved with GetCached when the lower sub-node is visited later.
	//
	// Returns false if it could not be cached, either because the node has since been removed with a call to Remove,
	// because Next has not been called yet, or because there is no lower sub node for the node previously returned by  Next.
	//
	// The caching and retrieval is done in constant time.
	CacheWithLowerSubNode(Cached) bool

	// CacheWithUpperSubNode caches an object with the upper sub-node of the current iterated node.
	// After Next has returned a node,
	// calling this method caches the provided object with the upper sub-node so that it can
	// be retrieved with GetCached when the upper sub-node is visited later.
	//
	// Returns false if it could not be cached, either because the node has since been removed with a call to Remove,
	// because Next has not been called yet, or because there is no upper sub node for the node previously returned by Next.
	//
	// The caching and retrieval is done in constant time.
	CacheWithUpperSubNode(Cached) bool
}

// addressKeyIterator implements the address key iterator for tries
type addressKeyIterator[T TrieKeyConstraint[T]] struct {
	tree.TrieKeyIterator[trieKey[T]]
}

func (iter addressKeyIterator[T]) Next() (t T) {
	return iter.TrieKeyIterator.Next().address
}

func (iter addressKeyIterator[T]) Remove() (t T) {
	return iter.TrieKeyIterator.Remove().address
}

//
type addrTrieNodeIteratorRem[T TrieKeyConstraint[T], V any] struct {
	tree.TrieNodeIteratorRem[trieKey[T], V]
}

func (iter addrTrieNodeIteratorRem[T, V]) Next() *TrieNode[T] {
	return toAddressTrieNode[T](iter.TrieNodeIteratorRem.Next())
}

func (iter addrTrieNodeIteratorRem[T, V]) Remove() *TrieNode[T] {
	return toAddressTrieNode[T](iter.TrieNodeIteratorRem.Remove())
}

//
type addrTrieNodeIterator[T TrieKeyConstraint[T], V any] struct {
	tree.TrieNodeIterator[trieKey[T], V]
}

func (iter addrTrieNodeIterator[T, V]) Next() *TrieNode[T] {
	return toAddressTrieNode[T](iter.TrieNodeIterator.Next())
}

//
type cachingAddressTrieNodeIterator[T TrieKeyConstraint[T], V any] struct {
	tree.CachingTrieNodeIterator[trieKey[T], V]
}

func (iter cachingAddressTrieNodeIterator[T, V]) Next() *TrieNode[T] {
	return toAddressTrieNode[T](iter.CachingTrieNodeIterator.Next())
}

func (iter cachingAddressTrieNodeIterator[T, V]) Remove() *TrieNode[T] {
	return toAddressTrieNode[T](iter.CachingTrieNodeIterator.Remove())
}

//////////////////////////////////////////////////////////////////
//////

type associativeAddressTrieNodeIteratorRem[T TrieKeyConstraint[T], V any] struct {
	tree.TrieNodeIteratorRem[trieKey[T], V]
}

func (iter associativeAddressTrieNodeIteratorRem[T, V]) Next() *AssociativeTrieNode[T, V] {
	return toAssociativeTrieNode[T, V](iter.TrieNodeIteratorRem.Next())
}

func (iter associativeAddressTrieNodeIteratorRem[T, V]) Remove() *AssociativeTrieNode[T, V] {
	return toAssociativeTrieNode[T, V](iter.TrieNodeIteratorRem.Remove())
}

//
type associativeAddressTrieNodeIterator[T TrieKeyConstraint[T], V any] struct {
	tree.TrieNodeIterator[trieKey[T], V]
}

func (iter associativeAddressTrieNodeIterator[T, V]) Next() *AssociativeTrieNode[T, V] {
	return toAssociativeTrieNode[T, V](iter.TrieNodeIterator.Next())
}

//
type cachingAssociativeAddressTrieNodeIteratorX[T TrieKeyConstraint[T], V any] struct {
	tree.CachingTrieNodeIterator[trieKey[T], V]
}

func (iter cachingAssociativeAddressTrieNodeIteratorX[T, V]) Next() *AssociativeTrieNode[T, V] {
	return toAssociativeTrieNode[T, V](iter.CachingTrieNodeIterator.Next())
}

func (iter cachingAssociativeAddressTrieNodeIteratorX[T, V]) Remove() *AssociativeTrieNode[T, V] {
	return toAssociativeTrieNode[T, V](iter.CachingTrieNodeIterator.Remove())
}

//
type emptyIterator[T any] struct{}

func (it emptyIterator[T]) HasNext() bool {
	return false
}

func (it emptyIterator[T]) Next() (t T) {
	return
}

func nilAddressIterator[T any]() Iterator[T] {
	return emptyIterator[T]{}
}