exonware-xwnode 0.0.1.12__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- exonware/__init__.py +14 -0
- exonware/xwnode/__init__.py +127 -0
- exonware/xwnode/base.py +676 -0
- exonware/xwnode/config.py +178 -0
- exonware/xwnode/contracts.py +730 -0
- exonware/xwnode/errors.py +503 -0
- exonware/xwnode/facade.py +460 -0
- exonware/xwnode/strategies/__init__.py +158 -0
- exonware/xwnode/strategies/advisor.py +463 -0
- exonware/xwnode/strategies/edges/__init__.py +32 -0
- exonware/xwnode/strategies/edges/adj_list.py +227 -0
- exonware/xwnode/strategies/edges/adj_matrix.py +391 -0
- exonware/xwnode/strategies/edges/base.py +169 -0
- exonware/xwnode/strategies/flyweight.py +328 -0
- exonware/xwnode/strategies/impls/__init__.py +13 -0
- exonware/xwnode/strategies/impls/_base_edge.py +403 -0
- exonware/xwnode/strategies/impls/_base_node.py +307 -0
- exonware/xwnode/strategies/impls/edge_adj_list.py +353 -0
- exonware/xwnode/strategies/impls/edge_adj_matrix.py +445 -0
- exonware/xwnode/strategies/impls/edge_bidir_wrapper.py +455 -0
- exonware/xwnode/strategies/impls/edge_block_adj_matrix.py +539 -0
- exonware/xwnode/strategies/impls/edge_coo.py +533 -0
- exonware/xwnode/strategies/impls/edge_csc.py +447 -0
- exonware/xwnode/strategies/impls/edge_csr.py +492 -0
- exonware/xwnode/strategies/impls/edge_dynamic_adj_list.py +503 -0
- exonware/xwnode/strategies/impls/edge_flow_network.py +555 -0
- exonware/xwnode/strategies/impls/edge_hyperedge_set.py +516 -0
- exonware/xwnode/strategies/impls/edge_neural_graph.py +650 -0
- exonware/xwnode/strategies/impls/edge_octree.py +574 -0
- exonware/xwnode/strategies/impls/edge_property_store.py +655 -0
- exonware/xwnode/strategies/impls/edge_quadtree.py +519 -0
- exonware/xwnode/strategies/impls/edge_rtree.py +820 -0
- exonware/xwnode/strategies/impls/edge_temporal_edgeset.py +558 -0
- exonware/xwnode/strategies/impls/edge_tree_graph_basic.py +271 -0
- exonware/xwnode/strategies/impls/edge_weighted_graph.py +411 -0
- exonware/xwnode/strategies/manager.py +775 -0
- exonware/xwnode/strategies/metrics.py +538 -0
- exonware/xwnode/strategies/migration.py +432 -0
- exonware/xwnode/strategies/nodes/__init__.py +50 -0
- exonware/xwnode/strategies/nodes/_base_node.py +307 -0
- exonware/xwnode/strategies/nodes/adjacency_list.py +267 -0
- exonware/xwnode/strategies/nodes/aho_corasick.py +345 -0
- exonware/xwnode/strategies/nodes/array_list.py +209 -0
- exonware/xwnode/strategies/nodes/base.py +247 -0
- exonware/xwnode/strategies/nodes/deque.py +200 -0
- exonware/xwnode/strategies/nodes/hash_map.py +135 -0
- exonware/xwnode/strategies/nodes/heap.py +307 -0
- exonware/xwnode/strategies/nodes/linked_list.py +232 -0
- exonware/xwnode/strategies/nodes/node_aho_corasick.py +520 -0
- exonware/xwnode/strategies/nodes/node_array_list.py +175 -0
- exonware/xwnode/strategies/nodes/node_avl_tree.py +371 -0
- exonware/xwnode/strategies/nodes/node_b_plus_tree.py +542 -0
- exonware/xwnode/strategies/nodes/node_bitmap.py +420 -0
- exonware/xwnode/strategies/nodes/node_bitset_dynamic.py +513 -0
- exonware/xwnode/strategies/nodes/node_bloom_filter.py +347 -0
- exonware/xwnode/strategies/nodes/node_btree.py +357 -0
- exonware/xwnode/strategies/nodes/node_count_min_sketch.py +470 -0
- exonware/xwnode/strategies/nodes/node_cow_tree.py +473 -0
- exonware/xwnode/strategies/nodes/node_cuckoo_hash.py +392 -0
- exonware/xwnode/strategies/nodes/node_fenwick_tree.py +301 -0
- exonware/xwnode/strategies/nodes/node_hash_map.py +269 -0
- exonware/xwnode/strategies/nodes/node_heap.py +191 -0
- exonware/xwnode/strategies/nodes/node_hyperloglog.py +407 -0
- exonware/xwnode/strategies/nodes/node_linked_list.py +409 -0
- exonware/xwnode/strategies/nodes/node_lsm_tree.py +400 -0
- exonware/xwnode/strategies/nodes/node_ordered_map.py +390 -0
- exonware/xwnode/strategies/nodes/node_ordered_map_balanced.py +565 -0
- exonware/xwnode/strategies/nodes/node_patricia.py +512 -0
- exonware/xwnode/strategies/nodes/node_persistent_tree.py +378 -0
- exonware/xwnode/strategies/nodes/node_radix_trie.py +452 -0
- exonware/xwnode/strategies/nodes/node_red_black_tree.py +497 -0
- exonware/xwnode/strategies/nodes/node_roaring_bitmap.py +570 -0
- exonware/xwnode/strategies/nodes/node_segment_tree.py +289 -0
- exonware/xwnode/strategies/nodes/node_set_hash.py +354 -0
- exonware/xwnode/strategies/nodes/node_set_tree.py +480 -0
- exonware/xwnode/strategies/nodes/node_skip_list.py +316 -0
- exonware/xwnode/strategies/nodes/node_splay_tree.py +393 -0
- exonware/xwnode/strategies/nodes/node_suffix_array.py +487 -0
- exonware/xwnode/strategies/nodes/node_treap.py +387 -0
- exonware/xwnode/strategies/nodes/node_tree_graph_hybrid.py +1434 -0
- exonware/xwnode/strategies/nodes/node_trie.py +252 -0
- exonware/xwnode/strategies/nodes/node_union_find.py +187 -0
- exonware/xwnode/strategies/nodes/node_xdata_optimized.py +369 -0
- exonware/xwnode/strategies/nodes/priority_queue.py +209 -0
- exonware/xwnode/strategies/nodes/queue.py +161 -0
- exonware/xwnode/strategies/nodes/sparse_matrix.py +206 -0
- exonware/xwnode/strategies/nodes/stack.py +152 -0
- exonware/xwnode/strategies/nodes/trie.py +274 -0
- exonware/xwnode/strategies/nodes/union_find.py +283 -0
- exonware/xwnode/strategies/pattern_detector.py +603 -0
- exonware/xwnode/strategies/performance_monitor.py +487 -0
- exonware/xwnode/strategies/queries/__init__.py +24 -0
- exonware/xwnode/strategies/queries/base.py +236 -0
- exonware/xwnode/strategies/queries/cql.py +201 -0
- exonware/xwnode/strategies/queries/cypher.py +181 -0
- exonware/xwnode/strategies/queries/datalog.py +70 -0
- exonware/xwnode/strategies/queries/elastic_dsl.py +70 -0
- exonware/xwnode/strategies/queries/eql.py +70 -0
- exonware/xwnode/strategies/queries/flux.py +70 -0
- exonware/xwnode/strategies/queries/gql.py +70 -0
- exonware/xwnode/strategies/queries/graphql.py +240 -0
- exonware/xwnode/strategies/queries/gremlin.py +181 -0
- exonware/xwnode/strategies/queries/hiveql.py +214 -0
- exonware/xwnode/strategies/queries/hql.py +70 -0
- exonware/xwnode/strategies/queries/jmespath.py +219 -0
- exonware/xwnode/strategies/queries/jq.py +66 -0
- exonware/xwnode/strategies/queries/json_query.py +66 -0
- exonware/xwnode/strategies/queries/jsoniq.py +248 -0
- exonware/xwnode/strategies/queries/kql.py +70 -0
- exonware/xwnode/strategies/queries/linq.py +238 -0
- exonware/xwnode/strategies/queries/logql.py +70 -0
- exonware/xwnode/strategies/queries/mql.py +68 -0
- exonware/xwnode/strategies/queries/n1ql.py +210 -0
- exonware/xwnode/strategies/queries/partiql.py +70 -0
- exonware/xwnode/strategies/queries/pig.py +215 -0
- exonware/xwnode/strategies/queries/promql.py +70 -0
- exonware/xwnode/strategies/queries/sparql.py +220 -0
- exonware/xwnode/strategies/queries/sql.py +275 -0
- exonware/xwnode/strategies/queries/xml_query.py +66 -0
- exonware/xwnode/strategies/queries/xpath.py +223 -0
- exonware/xwnode/strategies/queries/xquery.py +258 -0
- exonware/xwnode/strategies/queries/xwnode_executor.py +332 -0
- exonware/xwnode/strategies/queries/xwquery_strategy.py +424 -0
- exonware/xwnode/strategies/registry.py +604 -0
- exonware/xwnode/strategies/simple.py +273 -0
- exonware/xwnode/strategies/utils.py +532 -0
- exonware/xwnode/types.py +912 -0
- exonware/xwnode/version.py +78 -0
- exonware_xwnode-0.0.1.12.dist-info/METADATA +169 -0
- exonware_xwnode-0.0.1.12.dist-info/RECORD +132 -0
- exonware_xwnode-0.0.1.12.dist-info/WHEEL +4 -0
- exonware_xwnode-0.0.1.12.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,247 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
Node Strategy Base Classes
|
4
|
+
|
5
|
+
This module defines the abstract base classes for all node strategy implementations:
|
6
|
+
- ANodeStrategy: Base strategy for all node implementations
|
7
|
+
- ANodeLinearStrategy: Phase 1 - Linear data structure capabilities
|
8
|
+
- ANodeTreeStrategy: Phase 2 - Tree data structure capabilities
|
9
|
+
- ANodeGraphStrategy: Phase 3&4 - Graph data structure capabilities
|
10
|
+
|
11
|
+
Company: eXonware.com
|
12
|
+
Author: Eng. Muhammad AlShehri
|
13
|
+
Email: connect@exonware.com
|
14
|
+
Version: 0.0.1.12
|
15
|
+
Generation Date: January 2, 2025
|
16
|
+
"""
|
17
|
+
|
18
|
+
from abc import ABC, abstractmethod
|
19
|
+
from typing import Any, Optional, List, Dict, Iterator
|
20
|
+
|
21
|
+
from ...contracts import iNodeStrategy
|
22
|
+
from ...errors import XWNodeTypeError, XWNodeValueError
|
23
|
+
|
24
|
+
|
25
|
+
class ANodeStrategy(ABC):
|
26
|
+
"""Base strategy for all node implementations."""
|
27
|
+
|
28
|
+
def __init__(self, data: Any = None, **options):
|
29
|
+
"""Initialize node strategy."""
|
30
|
+
self._data = data
|
31
|
+
self._options = options
|
32
|
+
self._mode = options.get('mode', 'AUTO')
|
33
|
+
self._traits = options.get('traits', None)
|
34
|
+
|
35
|
+
@abstractmethod
|
36
|
+
def insert(self, key: Any, value: Any) -> None:
|
37
|
+
"""Insert key-value pair."""
|
38
|
+
pass
|
39
|
+
|
40
|
+
@abstractmethod
|
41
|
+
def find(self, key: Any) -> Optional[Any]:
|
42
|
+
"""Find value by key."""
|
43
|
+
pass
|
44
|
+
|
45
|
+
@abstractmethod
|
46
|
+
def delete(self, key: Any) -> bool:
|
47
|
+
"""Delete by key."""
|
48
|
+
pass
|
49
|
+
|
50
|
+
@abstractmethod
|
51
|
+
def size(self) -> int:
|
52
|
+
"""Get size of structure."""
|
53
|
+
pass
|
54
|
+
|
55
|
+
@abstractmethod
|
56
|
+
def is_empty(self) -> bool:
|
57
|
+
"""Check if structure is empty."""
|
58
|
+
pass
|
59
|
+
|
60
|
+
@abstractmethod
|
61
|
+
def to_native(self) -> Any:
|
62
|
+
"""Convert to native Python object."""
|
63
|
+
pass
|
64
|
+
|
65
|
+
def get_mode(self) -> str:
|
66
|
+
"""Get strategy mode."""
|
67
|
+
return self._mode
|
68
|
+
|
69
|
+
def get_traits(self):
|
70
|
+
"""Get strategy traits."""
|
71
|
+
return self._traits
|
72
|
+
|
73
|
+
|
74
|
+
class ANodeLinearStrategy(ANodeStrategy):
|
75
|
+
"""Phase 1: Linear data structure capabilities."""
|
76
|
+
|
77
|
+
def push_front(self, value: Any) -> None:
|
78
|
+
"""Add element to front."""
|
79
|
+
raise NotImplementedError("Subclasses must implement push_front")
|
80
|
+
|
81
|
+
def push_back(self, value: Any) -> None:
|
82
|
+
"""Add element to back."""
|
83
|
+
raise NotImplementedError("Subclasses must implement push_back")
|
84
|
+
|
85
|
+
def pop_front(self) -> Any:
|
86
|
+
"""Remove element from front."""
|
87
|
+
raise NotImplementedError("Subclasses must implement pop_front")
|
88
|
+
|
89
|
+
def pop_back(self) -> Any:
|
90
|
+
"""Remove element from back."""
|
91
|
+
raise NotImplementedError("Subclasses must implement pop_back")
|
92
|
+
|
93
|
+
def get_at_index(self, index: int) -> Any:
|
94
|
+
"""Get element at index."""
|
95
|
+
raise NotImplementedError("Subclasses must implement get_at_index")
|
96
|
+
|
97
|
+
def set_at_index(self, index: int, value: Any) -> None:
|
98
|
+
"""Set element at index."""
|
99
|
+
raise NotImplementedError("Subclasses must implement set_at_index")
|
100
|
+
|
101
|
+
# AUTO-3 Phase 1 methods
|
102
|
+
def as_linked_list(self):
|
103
|
+
"""Provide LinkedList behavioral view."""
|
104
|
+
raise NotImplementedError("Subclasses must implement as_linked_list")
|
105
|
+
|
106
|
+
def as_stack(self):
|
107
|
+
"""Provide Stack behavioral view."""
|
108
|
+
raise NotImplementedError("Subclasses must implement as_stack")
|
109
|
+
|
110
|
+
def as_queue(self):
|
111
|
+
"""Provide Queue behavioral view."""
|
112
|
+
raise NotImplementedError("Subclasses must implement as_queue")
|
113
|
+
|
114
|
+
def as_deque(self):
|
115
|
+
"""Provide Deque behavioral view."""
|
116
|
+
raise NotImplementedError("Subclasses must implement as_deque")
|
117
|
+
|
118
|
+
|
119
|
+
class ANodeGraphStrategy(ANodeStrategy):
|
120
|
+
"""Phase 3&4: Graph data structure capabilities."""
|
121
|
+
|
122
|
+
def add_edge(self, from_node: Any, to_node: Any, weight: float = 1.0) -> None:
|
123
|
+
"""Add edge between nodes."""
|
124
|
+
raise NotImplementedError("Subclasses must implement add_edge")
|
125
|
+
|
126
|
+
def remove_edge(self, from_node: Any, to_node: Any) -> bool:
|
127
|
+
"""Remove edge between nodes."""
|
128
|
+
raise NotImplementedError("Subclasses must implement remove_edge")
|
129
|
+
|
130
|
+
def has_edge(self, from_node: Any, to_node: Any) -> bool:
|
131
|
+
"""Check if edge exists."""
|
132
|
+
raise NotImplementedError("Subclasses must implement has_edge")
|
133
|
+
|
134
|
+
def find_path(self, start: Any, end: Any) -> List[Any]:
|
135
|
+
"""Find path between nodes."""
|
136
|
+
raise NotImplementedError("Subclasses must implement find_path")
|
137
|
+
|
138
|
+
def get_neighbors(self, node: Any) -> List[Any]:
|
139
|
+
"""Get neighboring nodes."""
|
140
|
+
raise NotImplementedError("Subclasses must implement get_neighbors")
|
141
|
+
|
142
|
+
def get_edge_weight(self, from_node: Any, to_node: Any) -> float:
|
143
|
+
"""Get edge weight."""
|
144
|
+
raise NotImplementedError("Subclasses must implement get_edge_weight")
|
145
|
+
|
146
|
+
# AUTO-3 Phase 3&4 methods
|
147
|
+
def as_union_find(self):
|
148
|
+
"""Provide Union-Find behavioral view."""
|
149
|
+
raise NotImplementedError("Subclasses must implement as_union_find")
|
150
|
+
|
151
|
+
def as_neural_graph(self):
|
152
|
+
"""Provide Neural Graph behavioral view."""
|
153
|
+
raise NotImplementedError("Subclasses must implement as_neural_graph")
|
154
|
+
|
155
|
+
def as_flow_network(self):
|
156
|
+
"""Provide Flow Network behavioral view."""
|
157
|
+
raise NotImplementedError("Subclasses must implement as_flow_network")
|
158
|
+
|
159
|
+
|
160
|
+
class ANodeMatrixStrategy(ANodeStrategy):
|
161
|
+
"""Matrix-based data structure capabilities."""
|
162
|
+
|
163
|
+
def get_dimensions(self) -> tuple:
|
164
|
+
"""Get matrix dimensions (rows, cols)."""
|
165
|
+
raise NotImplementedError("Subclasses must implement get_dimensions")
|
166
|
+
|
167
|
+
def get_at_position(self, row: int, col: int) -> Any:
|
168
|
+
"""Get element at matrix position."""
|
169
|
+
raise NotImplementedError("Subclasses must implement get_at_position")
|
170
|
+
|
171
|
+
def set_at_position(self, row: int, col: int, value: Any) -> None:
|
172
|
+
"""Set element at matrix position."""
|
173
|
+
raise NotImplementedError("Subclasses must implement set_at_position")
|
174
|
+
|
175
|
+
def get_row(self, row: int) -> List[Any]:
|
176
|
+
"""Get entire row."""
|
177
|
+
raise NotImplementedError("Subclasses must implement get_row")
|
178
|
+
|
179
|
+
def get_column(self, col: int) -> List[Any]:
|
180
|
+
"""Get entire column."""
|
181
|
+
raise NotImplementedError("Subclasses must implement get_column")
|
182
|
+
|
183
|
+
def transpose(self) -> 'ANodeMatrixStrategy':
|
184
|
+
"""Transpose the matrix."""
|
185
|
+
raise NotImplementedError("Subclasses must implement transpose")
|
186
|
+
|
187
|
+
def multiply(self, other: 'ANodeMatrixStrategy') -> 'ANodeMatrixStrategy':
|
188
|
+
"""Matrix multiplication."""
|
189
|
+
raise NotImplementedError("Subclasses must implement multiply")
|
190
|
+
|
191
|
+
def add(self, other: 'ANodeMatrixStrategy') -> 'ANodeMatrixStrategy':
|
192
|
+
"""Matrix addition."""
|
193
|
+
raise NotImplementedError("Subclasses must implement add")
|
194
|
+
|
195
|
+
# Matrix-specific behavioral views
|
196
|
+
def as_adjacency_matrix(self):
|
197
|
+
"""Provide Adjacency Matrix behavioral view."""
|
198
|
+
raise NotImplementedError("Subclasses must implement as_adjacency_matrix")
|
199
|
+
|
200
|
+
def as_incidence_matrix(self):
|
201
|
+
"""Provide Incidence Matrix behavioral view."""
|
202
|
+
raise NotImplementedError("Subclasses must implement as_incidence_matrix")
|
203
|
+
|
204
|
+
def as_sparse_matrix(self):
|
205
|
+
"""Provide Sparse Matrix behavioral view."""
|
206
|
+
raise NotImplementedError("Subclasses must implement as_sparse_matrix")
|
207
|
+
|
208
|
+
|
209
|
+
class ANodeTreeStrategy(ANodeGraphStrategy):
|
210
|
+
"""Phase 2: Tree data structure capabilities."""
|
211
|
+
|
212
|
+
def insert(self, key: Any, value: Any) -> None:
|
213
|
+
"""Insert with tree ordering."""
|
214
|
+
raise NotImplementedError("Subclasses must implement insert")
|
215
|
+
|
216
|
+
def find(self, key: Any) -> Optional[Any]:
|
217
|
+
"""Find with tree traversal."""
|
218
|
+
raise NotImplementedError("Subclasses must implement find")
|
219
|
+
|
220
|
+
def delete(self, key: Any) -> bool:
|
221
|
+
"""Delete with tree restructuring."""
|
222
|
+
raise NotImplementedError("Subclasses must implement delete")
|
223
|
+
|
224
|
+
def traverse(self, order: str = 'inorder') -> List[Any]:
|
225
|
+
"""Traverse tree in specified order."""
|
226
|
+
raise NotImplementedError("Subclasses must implement traverse")
|
227
|
+
|
228
|
+
def get_min(self) -> Any:
|
229
|
+
"""Get minimum key."""
|
230
|
+
raise NotImplementedError("Subclasses must implement get_min")
|
231
|
+
|
232
|
+
def get_max(self) -> Any:
|
233
|
+
"""Get maximum key."""
|
234
|
+
raise NotImplementedError("Subclasses must implement get_max")
|
235
|
+
|
236
|
+
# AUTO-3 Phase 2 methods
|
237
|
+
def as_trie(self):
|
238
|
+
"""Provide Trie behavioral view."""
|
239
|
+
raise NotImplementedError("Subclasses must implement as_trie")
|
240
|
+
|
241
|
+
def as_heap(self):
|
242
|
+
"""Provide Heap behavioral view."""
|
243
|
+
raise NotImplementedError("Subclasses must implement as_heap")
|
244
|
+
|
245
|
+
def as_skip_list(self):
|
246
|
+
"""Provide SkipList behavioral view."""
|
247
|
+
raise NotImplementedError("Subclasses must implement as_skip_list")
|
@@ -0,0 +1,200 @@
|
|
1
|
+
"""
|
2
|
+
Deque Strategy Implementation
|
3
|
+
|
4
|
+
Implements a double-ended queue using Python's deque for efficient operations at both ends.
|
5
|
+
|
6
|
+
Company: eXonware.com
|
7
|
+
Author: Eng. Muhammad AlShehri
|
8
|
+
Email: connect@exonware.com
|
9
|
+
Version: 0.0.1.12
|
10
|
+
Generation Date: 07-Sep-2025
|
11
|
+
"""
|
12
|
+
|
13
|
+
from typing import Any, Iterator, Optional, Dict, Union
|
14
|
+
from collections import deque
|
15
|
+
from .base import ANodeLinearStrategy
|
16
|
+
from ...types import NodeMode, NodeTrait
|
17
|
+
|
18
|
+
|
19
|
+
class DequeStrategy(ANodeLinearStrategy):
|
20
|
+
"""
|
21
|
+
Deque (Double-ended queue) node strategy for efficient operations at both ends.
|
22
|
+
|
23
|
+
Provides O(1) operations for adding/removing elements at both front and back,
|
24
|
+
ideal for sliding window algorithms and breadth-first search.
|
25
|
+
"""
|
26
|
+
|
27
|
+
def __init__(self):
|
28
|
+
"""Initialize an empty deque."""
|
29
|
+
super().__init__()
|
30
|
+
self._deque: deque = deque()
|
31
|
+
self._mode = NodeMode.DEQUE
|
32
|
+
self._traits = {NodeTrait.DOUBLE_ENDED, NodeTrait.FAST_INSERT, NodeTrait.FAST_DELETE}
|
33
|
+
|
34
|
+
def insert(self, key: str, value: Any) -> None:
|
35
|
+
"""Insert an item (defaults to back)."""
|
36
|
+
self._deque.append((key, value))
|
37
|
+
|
38
|
+
def find(self, key: str) -> Optional[Any]:
|
39
|
+
"""Find an item in the deque (O(n) operation)."""
|
40
|
+
for k, v in self._deque:
|
41
|
+
if k == key:
|
42
|
+
return v
|
43
|
+
return None
|
44
|
+
|
45
|
+
def delete(self, key: str) -> bool:
|
46
|
+
"""Remove an item from the deque."""
|
47
|
+
for i, (k, v) in enumerate(self._deque):
|
48
|
+
if k == key:
|
49
|
+
del self._deque[i]
|
50
|
+
return True
|
51
|
+
return False
|
52
|
+
|
53
|
+
def size(self) -> int:
|
54
|
+
"""Get the number of items in the deque."""
|
55
|
+
return len(self._deque)
|
56
|
+
|
57
|
+
def is_empty(self) -> bool:
|
58
|
+
"""Check if the deque is empty."""
|
59
|
+
return len(self._deque) == 0
|
60
|
+
|
61
|
+
def to_native(self) -> Dict[str, Any]:
|
62
|
+
"""Convert deque to native dictionary format."""
|
63
|
+
return dict(self._deque)
|
64
|
+
|
65
|
+
def from_native(self, data: Dict[str, Any]) -> None:
|
66
|
+
"""Load deque from native dictionary format."""
|
67
|
+
self._deque = deque(data.items())
|
68
|
+
|
69
|
+
def append(self, value: Any) -> None:
|
70
|
+
"""Add an item to the right end."""
|
71
|
+
key = f"item_{len(self._deque)}"
|
72
|
+
self._deque.append((key, value))
|
73
|
+
|
74
|
+
def appendleft(self, value: Any) -> None:
|
75
|
+
"""Add an item to the left end."""
|
76
|
+
key = f"item_{len(self._deque)}"
|
77
|
+
self._deque.appendleft((key, value))
|
78
|
+
|
79
|
+
def pop(self) -> Optional[Any]:
|
80
|
+
"""Remove and return an item from the right end."""
|
81
|
+
if self.is_empty():
|
82
|
+
return None
|
83
|
+
key, value = self._deque.pop()
|
84
|
+
return value
|
85
|
+
|
86
|
+
def popleft(self) -> Optional[Any]:
|
87
|
+
"""Remove and return an item from the left end."""
|
88
|
+
if self.is_empty():
|
89
|
+
return None
|
90
|
+
key, value = self._deque.popleft()
|
91
|
+
return value
|
92
|
+
|
93
|
+
def peek_right(self) -> Optional[Any]:
|
94
|
+
"""Peek at the rightmost item without removing it."""
|
95
|
+
if self.is_empty():
|
96
|
+
return None
|
97
|
+
key, value = self._deque[-1]
|
98
|
+
return value
|
99
|
+
|
100
|
+
def peek_left(self) -> Optional[Any]:
|
101
|
+
"""Peek at the leftmost item without removing it."""
|
102
|
+
if self.is_empty():
|
103
|
+
return None
|
104
|
+
key, value = self._deque[0]
|
105
|
+
return value
|
106
|
+
|
107
|
+
def rotate(self, n: int = 1) -> None:
|
108
|
+
"""Rotate the deque n steps to the right (positive) or left (negative)."""
|
109
|
+
self._deque.rotate(n)
|
110
|
+
|
111
|
+
def reverse(self) -> None:
|
112
|
+
"""Reverse the deque in place."""
|
113
|
+
self._deque.reverse()
|
114
|
+
|
115
|
+
def clear(self) -> None:
|
116
|
+
"""Clear all items from the deque."""
|
117
|
+
self._deque.clear()
|
118
|
+
|
119
|
+
def get_at_index(self, index: int) -> Optional[Any]:
|
120
|
+
"""Get item at specific index."""
|
121
|
+
if 0 <= index < len(self._deque):
|
122
|
+
key, value = self._deque[index]
|
123
|
+
return value
|
124
|
+
return None
|
125
|
+
|
126
|
+
def set_at_index(self, index: int, value: Any) -> bool:
|
127
|
+
"""Set item at specific index."""
|
128
|
+
if 0 <= index < len(self._deque):
|
129
|
+
key, old_value = self._deque[index]
|
130
|
+
self._deque[index] = (key, value)
|
131
|
+
return True
|
132
|
+
return False
|
133
|
+
|
134
|
+
def push_front(self, value: Any) -> None:
|
135
|
+
"""Push to front (left end)."""
|
136
|
+
self.appendleft(value)
|
137
|
+
|
138
|
+
def push_back(self, value: Any) -> None:
|
139
|
+
"""Push to back (right end)."""
|
140
|
+
self.append(value)
|
141
|
+
|
142
|
+
def remove(self, value: Any) -> bool:
|
143
|
+
"""Remove the first occurrence of a value."""
|
144
|
+
for i, (key, v) in enumerate(self._deque):
|
145
|
+
if v == value:
|
146
|
+
del self._deque[i]
|
147
|
+
return True
|
148
|
+
return False
|
149
|
+
|
150
|
+
def count(self, value: Any) -> int:
|
151
|
+
"""Count occurrences of a value."""
|
152
|
+
count = 0
|
153
|
+
for key, v in self._deque:
|
154
|
+
if v == value:
|
155
|
+
count += 1
|
156
|
+
return count
|
157
|
+
|
158
|
+
def extend(self, values: list) -> None:
|
159
|
+
"""Extend the deque with values from the right."""
|
160
|
+
for value in values:
|
161
|
+
self.append(value)
|
162
|
+
|
163
|
+
def extendleft(self, values: list) -> None:
|
164
|
+
"""Extend the deque with values from the left."""
|
165
|
+
for value in reversed(values):
|
166
|
+
self.appendleft(value)
|
167
|
+
|
168
|
+
def __iter__(self) -> Iterator[Any]:
|
169
|
+
"""Iterate through deque items (left to right)."""
|
170
|
+
for key, value in self._deque:
|
171
|
+
yield value
|
172
|
+
|
173
|
+
def __repr__(self) -> str:
|
174
|
+
"""String representation of the deque."""
|
175
|
+
return f"DequeStrategy(size={len(self._deque)}, left={self.peek_left()}, right={self.peek_right()})"
|
176
|
+
|
177
|
+
# Required abstract methods from base classes
|
178
|
+
def pop_front(self) -> Any:
|
179
|
+
"""Remove element from front (same as popleft for deque)."""
|
180
|
+
return self.popleft()
|
181
|
+
|
182
|
+
def pop_back(self) -> Any:
|
183
|
+
"""Remove element from back (same as pop for deque)."""
|
184
|
+
return self.pop()
|
185
|
+
|
186
|
+
def as_linked_list(self):
|
187
|
+
"""Provide LinkedList behavioral view."""
|
188
|
+
return self
|
189
|
+
|
190
|
+
def as_stack(self):
|
191
|
+
"""Provide Stack behavioral view."""
|
192
|
+
return self
|
193
|
+
|
194
|
+
def as_queue(self):
|
195
|
+
"""Provide Queue behavioral view."""
|
196
|
+
return self
|
197
|
+
|
198
|
+
def as_deque(self):
|
199
|
+
"""Provide Deque behavioral view."""
|
200
|
+
return self
|
@@ -0,0 +1,135 @@
|
|
1
|
+
"""
|
2
|
+
Hash Map Node Strategy Implementation
|
3
|
+
|
4
|
+
This module implements the HASH_MAP strategy for fast key-value operations
|
5
|
+
using Python's built-in dictionary.
|
6
|
+
"""
|
7
|
+
|
8
|
+
from typing import Any, Iterator, Dict, List, Optional, Union
|
9
|
+
from .base import ANodeStrategy
|
10
|
+
from ...types import NodeMode, NodeTrait
|
11
|
+
|
12
|
+
|
13
|
+
class HashMapStrategy(ANodeStrategy):
|
14
|
+
"""
|
15
|
+
Hash Map node strategy for fast O(1) key-value operations.
|
16
|
+
|
17
|
+
Uses Python's built-in dictionary for optimal performance
|
18
|
+
with associative operations.
|
19
|
+
"""
|
20
|
+
|
21
|
+
def __init__(self, traits: NodeTrait = NodeTrait.NONE, **options):
|
22
|
+
"""Initialize the hash map strategy."""
|
23
|
+
super().__init__(data=None, **options)
|
24
|
+
self._mode = NodeMode.HASH_MAP
|
25
|
+
self._traits = traits
|
26
|
+
self._data: Dict[str, Any] = {}
|
27
|
+
|
28
|
+
def get_supported_traits(self) -> NodeTrait:
|
29
|
+
"""Get the traits supported by the hash map strategy."""
|
30
|
+
return (NodeTrait.INDEXED | NodeTrait.HIERARCHICAL)
|
31
|
+
|
32
|
+
# ============================================================================
|
33
|
+
# CORE OPERATIONS
|
34
|
+
# ============================================================================
|
35
|
+
|
36
|
+
def insert(self, key: Any, value: Any) -> None:
|
37
|
+
"""Store a key-value pair."""
|
38
|
+
str_key = str(key)
|
39
|
+
self._data[str_key] = value
|
40
|
+
|
41
|
+
def find(self, key: Any) -> Any:
|
42
|
+
"""Retrieve a value by key."""
|
43
|
+
str_key = str(key)
|
44
|
+
return self._data.get(str_key)
|
45
|
+
|
46
|
+
def delete(self, key: Any) -> bool:
|
47
|
+
"""Remove a key-value pair."""
|
48
|
+
str_key = str(key)
|
49
|
+
if str_key in self._data:
|
50
|
+
del self._data[str_key]
|
51
|
+
return True
|
52
|
+
return False
|
53
|
+
|
54
|
+
def size(self) -> int:
|
55
|
+
"""Get the number of items."""
|
56
|
+
return len(self._data)
|
57
|
+
|
58
|
+
def is_empty(self) -> bool:
|
59
|
+
"""Check if the structure is empty."""
|
60
|
+
return len(self._data) == 0
|
61
|
+
|
62
|
+
def to_native(self) -> Dict[str, Any]:
|
63
|
+
"""Convert to native Python dictionary."""
|
64
|
+
return self._data.copy()
|
65
|
+
|
66
|
+
# ============================================================================
|
67
|
+
# ITERATION
|
68
|
+
# ============================================================================
|
69
|
+
|
70
|
+
def keys(self) -> Iterator[str]:
|
71
|
+
"""Get all keys."""
|
72
|
+
return iter(self._data.keys())
|
73
|
+
|
74
|
+
def values(self) -> Iterator[Any]:
|
75
|
+
"""Get all values."""
|
76
|
+
return iter(self._data.values())
|
77
|
+
|
78
|
+
def items(self) -> Iterator[tuple[str, Any]]:
|
79
|
+
"""Get all key-value pairs."""
|
80
|
+
return iter(self._data.items())
|
81
|
+
|
82
|
+
# ============================================================================
|
83
|
+
# HASH MAP SPECIFIC OPERATIONS
|
84
|
+
# ============================================================================
|
85
|
+
|
86
|
+
def get(self, key: Any, default: Any = None) -> Any:
|
87
|
+
"""Get value with default."""
|
88
|
+
str_key = str(key)
|
89
|
+
return self._data.get(str_key, default)
|
90
|
+
|
91
|
+
def setdefault(self, key: Any, default: Any = None) -> Any:
|
92
|
+
"""Set default value if key doesn't exist."""
|
93
|
+
str_key = str(key)
|
94
|
+
return self._data.setdefault(str_key, default)
|
95
|
+
|
96
|
+
def update(self, other: Dict[str, Any]) -> None:
|
97
|
+
"""Update with another dictionary."""
|
98
|
+
self._data.update(other)
|
99
|
+
|
100
|
+
def pop(self, key: Any, default: Any = None) -> Any:
|
101
|
+
"""Remove and return value."""
|
102
|
+
str_key = str(key)
|
103
|
+
return self._data.pop(str_key, default)
|
104
|
+
|
105
|
+
def clear(self) -> None:
|
106
|
+
"""Clear all data."""
|
107
|
+
self._data.clear()
|
108
|
+
|
109
|
+
# ============================================================================
|
110
|
+
# PERFORMANCE CHARACTERISTICS
|
111
|
+
# ============================================================================
|
112
|
+
|
113
|
+
@property
|
114
|
+
def backend_info(self) -> Dict[str, Any]:
|
115
|
+
"""Get backend implementation info."""
|
116
|
+
return {
|
117
|
+
'strategy': 'HASH_MAP',
|
118
|
+
'backend': 'Python dict',
|
119
|
+
'complexity': {
|
120
|
+
'get': 'O(1)',
|
121
|
+
'put': 'O(1)',
|
122
|
+
'delete': 'O(1)',
|
123
|
+
'keys': 'O(n)',
|
124
|
+
'values': 'O(n)'
|
125
|
+
}
|
126
|
+
}
|
127
|
+
|
128
|
+
@property
|
129
|
+
def metrics(self) -> Dict[str, Any]:
|
130
|
+
"""Get performance metrics."""
|
131
|
+
return {
|
132
|
+
'size': len(self._data),
|
133
|
+
'memory_usage': f"{len(self._data) * 24} bytes (estimated)",
|
134
|
+
'load_factor': 'N/A (Python dict)'
|
135
|
+
}
|