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,273 @@
|
|
1
|
+
"""
|
2
|
+
Simple node strategy implementation.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import Any, Iterator, Optional, List, Dict, Union
|
6
|
+
from ..contracts import iNodeStrategy, NodeTrait
|
7
|
+
|
8
|
+
|
9
|
+
class SimpleNodeStrategy(iNodeStrategy):
|
10
|
+
"""Simple hash map-based node strategy."""
|
11
|
+
|
12
|
+
def __init__(self, data: Any = None):
|
13
|
+
self._data = data
|
14
|
+
self._type = self._determine_type(data)
|
15
|
+
|
16
|
+
@classmethod
|
17
|
+
def create_from_data(cls, data: Any) -> 'SimpleNodeStrategy':
|
18
|
+
"""Create a new strategy instance from data."""
|
19
|
+
return cls(data)
|
20
|
+
|
21
|
+
def _determine_type(self, data: Any) -> str:
|
22
|
+
"""Determine the type of the data."""
|
23
|
+
if isinstance(data, dict):
|
24
|
+
return "dict"
|
25
|
+
elif isinstance(data, list):
|
26
|
+
return "list"
|
27
|
+
else:
|
28
|
+
return "leaf"
|
29
|
+
|
30
|
+
def to_native(self) -> Any:
|
31
|
+
"""Convert to native Python object."""
|
32
|
+
return self._data
|
33
|
+
|
34
|
+
def size(self) -> int:
|
35
|
+
"""Get the number of items."""
|
36
|
+
if isinstance(self._data, dict):
|
37
|
+
return len(self._data)
|
38
|
+
elif isinstance(self._data, list):
|
39
|
+
return len(self._data)
|
40
|
+
else:
|
41
|
+
return 1 if self._data is not None else 0
|
42
|
+
|
43
|
+
def is_empty(self) -> bool:
|
44
|
+
"""Check if the node is empty."""
|
45
|
+
if isinstance(self._data, dict):
|
46
|
+
return len(self._data) == 0
|
47
|
+
elif isinstance(self._data, list):
|
48
|
+
return len(self._data) == 0
|
49
|
+
else:
|
50
|
+
return self._data is None
|
51
|
+
|
52
|
+
def insert(self, key: Any, value: Any) -> None:
|
53
|
+
"""Insert a key-value pair."""
|
54
|
+
if isinstance(self._data, dict):
|
55
|
+
self._data[key] = value
|
56
|
+
elif isinstance(self._data, list):
|
57
|
+
if isinstance(key, int):
|
58
|
+
self._data[key] = value
|
59
|
+
else:
|
60
|
+
raise ValueError(f"Cannot insert with non-integer key '{key}' into list")
|
61
|
+
else:
|
62
|
+
# Convert to dict if it's a leaf node
|
63
|
+
self._data = {key: value}
|
64
|
+
|
65
|
+
def find(self, key: Any) -> Any:
|
66
|
+
"""Find a value by key."""
|
67
|
+
if isinstance(self._data, dict):
|
68
|
+
return self._data.get(key)
|
69
|
+
elif isinstance(self._data, list):
|
70
|
+
if isinstance(key, int) and 0 <= key < len(self._data):
|
71
|
+
return self._data[key]
|
72
|
+
else:
|
73
|
+
return None
|
74
|
+
else:
|
75
|
+
return None
|
76
|
+
|
77
|
+
def delete(self, key: Any) -> bool:
|
78
|
+
"""Delete a key-value pair."""
|
79
|
+
if isinstance(self._data, dict):
|
80
|
+
if key in self._data:
|
81
|
+
del self._data[key]
|
82
|
+
return True
|
83
|
+
return False
|
84
|
+
elif isinstance(self._data, list):
|
85
|
+
if isinstance(key, int) and 0 <= key < len(self._data):
|
86
|
+
del self._data[key]
|
87
|
+
return True
|
88
|
+
return False
|
89
|
+
else:
|
90
|
+
return False
|
91
|
+
|
92
|
+
def get(self, path: str, default: Any = None) -> Optional['SimpleNodeStrategy']:
|
93
|
+
"""Get a child node by path."""
|
94
|
+
try:
|
95
|
+
parts = path.split('.')
|
96
|
+
current = self._data
|
97
|
+
|
98
|
+
for part in parts:
|
99
|
+
if isinstance(current, dict):
|
100
|
+
current = current[part]
|
101
|
+
elif isinstance(current, list):
|
102
|
+
current = current[int(part)]
|
103
|
+
else:
|
104
|
+
return None
|
105
|
+
|
106
|
+
return SimpleNodeStrategy(current)
|
107
|
+
except (KeyError, IndexError, ValueError, TypeError):
|
108
|
+
return None
|
109
|
+
|
110
|
+
def put(self, path: str, value: Any) -> 'SimpleNodeStrategy':
|
111
|
+
"""Set a value at path."""
|
112
|
+
# For simplicity, return a new instance
|
113
|
+
new_data = self._data.copy() if isinstance(self._data, (dict, list)) else self._data
|
114
|
+
|
115
|
+
try:
|
116
|
+
parts = path.split('.')
|
117
|
+
current = new_data
|
118
|
+
|
119
|
+
for part in parts[:-1]:
|
120
|
+
if isinstance(current, dict):
|
121
|
+
current = current[part]
|
122
|
+
elif isinstance(current, list):
|
123
|
+
current = current[int(part)]
|
124
|
+
|
125
|
+
# Set the final value
|
126
|
+
final_key = parts[-1]
|
127
|
+
if isinstance(current, dict):
|
128
|
+
current[final_key] = value
|
129
|
+
elif isinstance(current, list):
|
130
|
+
current[int(final_key)] = value
|
131
|
+
except (KeyError, IndexError, ValueError, TypeError):
|
132
|
+
pass
|
133
|
+
|
134
|
+
return SimpleNodeStrategy(new_data)
|
135
|
+
|
136
|
+
def delete(self, path: str) -> bool:
|
137
|
+
"""Delete a node at path."""
|
138
|
+
try:
|
139
|
+
parts = path.split('.')
|
140
|
+
current = self._data
|
141
|
+
|
142
|
+
for part in parts[:-1]:
|
143
|
+
if isinstance(current, dict):
|
144
|
+
current = current[part]
|
145
|
+
elif isinstance(current, list):
|
146
|
+
current = current[int(part)]
|
147
|
+
|
148
|
+
# Delete the final key
|
149
|
+
final_key = parts[-1]
|
150
|
+
if isinstance(current, dict):
|
151
|
+
del current[final_key]
|
152
|
+
elif isinstance(current, list):
|
153
|
+
current.pop(int(final_key))
|
154
|
+
|
155
|
+
return True
|
156
|
+
except (KeyError, IndexError, ValueError, TypeError):
|
157
|
+
return False
|
158
|
+
|
159
|
+
def exists(self, path: str) -> bool:
|
160
|
+
"""Check if path exists."""
|
161
|
+
return self.get(path) is not None
|
162
|
+
|
163
|
+
def keys(self) -> Iterator[str]:
|
164
|
+
"""Get keys (for dict-like nodes)."""
|
165
|
+
if isinstance(self._data, dict):
|
166
|
+
yield from self._data.keys()
|
167
|
+
elif isinstance(self._data, list):
|
168
|
+
yield from (str(i) for i in range(len(self._data)))
|
169
|
+
|
170
|
+
def values(self) -> Iterator['SimpleNodeStrategy']:
|
171
|
+
"""Get values (for dict-like nodes)."""
|
172
|
+
if isinstance(self._data, dict):
|
173
|
+
for value in self._data.values():
|
174
|
+
yield SimpleNodeStrategy(value)
|
175
|
+
elif isinstance(self._data, list):
|
176
|
+
for value in self._data:
|
177
|
+
yield SimpleNodeStrategy(value)
|
178
|
+
|
179
|
+
def items(self) -> Iterator[tuple[str, 'SimpleNodeStrategy']]:
|
180
|
+
"""Get items (for dict-like nodes)."""
|
181
|
+
if isinstance(self._data, dict):
|
182
|
+
for key, value in self._data.items():
|
183
|
+
yield key, SimpleNodeStrategy(value)
|
184
|
+
elif isinstance(self._data, list):
|
185
|
+
for i, value in enumerate(self._data):
|
186
|
+
yield str(i), SimpleNodeStrategy(value)
|
187
|
+
|
188
|
+
def __len__(self) -> int:
|
189
|
+
"""Get length."""
|
190
|
+
if hasattr(self._data, '__len__'):
|
191
|
+
return len(self._data)
|
192
|
+
return 0
|
193
|
+
|
194
|
+
def __iter__(self) -> Iterator['SimpleNodeStrategy']:
|
195
|
+
"""Iterate over children."""
|
196
|
+
if isinstance(self._data, (dict, list)):
|
197
|
+
for value in self.values():
|
198
|
+
yield value
|
199
|
+
|
200
|
+
def __getitem__(self, key: Union[str, int]) -> 'SimpleNodeStrategy':
|
201
|
+
"""Get child by key or index."""
|
202
|
+
if isinstance(self._data, dict):
|
203
|
+
return SimpleNodeStrategy(self._data[str(key)])
|
204
|
+
elif isinstance(self._data, list):
|
205
|
+
return SimpleNodeStrategy(self._data[int(key)])
|
206
|
+
else:
|
207
|
+
raise KeyError(key)
|
208
|
+
|
209
|
+
def __setitem__(self, key: Union[str, int], value: Any) -> None:
|
210
|
+
"""Set child by key or index."""
|
211
|
+
if isinstance(self._data, dict):
|
212
|
+
self._data[str(key)] = value
|
213
|
+
elif isinstance(self._data, list):
|
214
|
+
self._data[int(key)] = value
|
215
|
+
|
216
|
+
def __contains__(self, key: Union[str, int]) -> bool:
|
217
|
+
"""Check if key exists."""
|
218
|
+
try:
|
219
|
+
if isinstance(self._data, dict):
|
220
|
+
return str(key) in self._data
|
221
|
+
elif isinstance(self._data, list):
|
222
|
+
idx = int(key)
|
223
|
+
return 0 <= idx < len(self._data)
|
224
|
+
except (ValueError, TypeError):
|
225
|
+
pass
|
226
|
+
return False
|
227
|
+
|
228
|
+
# Type checking properties
|
229
|
+
@property
|
230
|
+
def is_leaf(self) -> bool:
|
231
|
+
"""Check if this is a leaf node."""
|
232
|
+
return self._type == "leaf"
|
233
|
+
|
234
|
+
@property
|
235
|
+
def is_list(self) -> bool:
|
236
|
+
"""Check if this is a list node."""
|
237
|
+
return self._type == "list"
|
238
|
+
|
239
|
+
@property
|
240
|
+
def is_dict(self) -> bool:
|
241
|
+
"""Check if this is a dict node."""
|
242
|
+
return self._type == "dict"
|
243
|
+
|
244
|
+
@property
|
245
|
+
def is_reference(self) -> bool:
|
246
|
+
"""Check if this is a reference node."""
|
247
|
+
return False
|
248
|
+
|
249
|
+
@property
|
250
|
+
def is_object(self) -> bool:
|
251
|
+
"""Check if this is an object node."""
|
252
|
+
return False
|
253
|
+
|
254
|
+
@property
|
255
|
+
def type(self) -> str:
|
256
|
+
"""Get the type of this node."""
|
257
|
+
return self._type
|
258
|
+
|
259
|
+
@property
|
260
|
+
def value(self) -> Any:
|
261
|
+
"""Get the value of this node."""
|
262
|
+
return self._data
|
263
|
+
|
264
|
+
# Strategy information
|
265
|
+
@property
|
266
|
+
def strategy_name(self) -> str:
|
267
|
+
"""Get the name of this strategy."""
|
268
|
+
return "simple"
|
269
|
+
|
270
|
+
@property
|
271
|
+
def supported_traits(self) -> List[NodeTrait]:
|
272
|
+
"""Get supported traits for this strategy."""
|
273
|
+
return [NodeTrait.NONE]
|