exonware-xwnode 0.0.1.22__py3-none-any.whl → 0.0.1.23__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 +1 -1
- exonware/xwnode/__init__.py +18 -5
- exonware/xwnode/add_strategy_types.py +165 -0
- exonware/xwnode/common/__init__.py +1 -1
- exonware/xwnode/common/graph/__init__.py +30 -0
- exonware/xwnode/common/graph/caching.py +131 -0
- exonware/xwnode/common/graph/contracts.py +100 -0
- exonware/xwnode/common/graph/errors.py +44 -0
- exonware/xwnode/common/graph/indexing.py +260 -0
- exonware/xwnode/common/graph/manager.py +568 -0
- exonware/xwnode/common/management/__init__.py +3 -5
- exonware/xwnode/common/management/manager.py +2 -2
- exonware/xwnode/common/management/migration.py +3 -3
- exonware/xwnode/common/monitoring/__init__.py +3 -5
- exonware/xwnode/common/monitoring/metrics.py +6 -2
- exonware/xwnode/common/monitoring/pattern_detector.py +1 -1
- exonware/xwnode/common/monitoring/performance_monitor.py +5 -1
- exonware/xwnode/common/patterns/__init__.py +3 -5
- exonware/xwnode/common/patterns/flyweight.py +5 -1
- exonware/xwnode/common/patterns/registry.py +202 -183
- exonware/xwnode/common/utils/__init__.py +25 -11
- exonware/xwnode/common/utils/simple.py +1 -1
- exonware/xwnode/config.py +3 -8
- exonware/xwnode/contracts.py +4 -105
- exonware/xwnode/defs.py +413 -159
- exonware/xwnode/edges/strategies/__init__.py +86 -4
- exonware/xwnode/edges/strategies/_base_edge.py +2 -2
- exonware/xwnode/edges/strategies/adj_list.py +287 -121
- exonware/xwnode/edges/strategies/adj_matrix.py +316 -222
- exonware/xwnode/edges/strategies/base.py +1 -1
- exonware/xwnode/edges/strategies/{edge_bidir_wrapper.py → bidir_wrapper.py} +45 -4
- exonware/xwnode/edges/strategies/bitemporal.py +520 -0
- exonware/xwnode/edges/strategies/{edge_block_adj_matrix.py → block_adj_matrix.py} +77 -6
- exonware/xwnode/edges/strategies/bv_graph.py +664 -0
- exonware/xwnode/edges/strategies/compressed_graph.py +217 -0
- exonware/xwnode/edges/strategies/{edge_coo.py → coo.py} +46 -4
- exonware/xwnode/edges/strategies/{edge_csc.py → csc.py} +45 -4
- exonware/xwnode/edges/strategies/{edge_csr.py → csr.py} +94 -12
- exonware/xwnode/edges/strategies/{edge_dynamic_adj_list.py → dynamic_adj_list.py} +46 -4
- exonware/xwnode/edges/strategies/edge_list.py +168 -0
- exonware/xwnode/edges/strategies/edge_property_store.py +2 -2
- exonware/xwnode/edges/strategies/euler_tour.py +560 -0
- exonware/xwnode/edges/strategies/{edge_flow_network.py → flow_network.py} +2 -2
- exonware/xwnode/edges/strategies/graphblas.py +449 -0
- exonware/xwnode/edges/strategies/hnsw.py +637 -0
- exonware/xwnode/edges/strategies/hop2_labels.py +467 -0
- exonware/xwnode/edges/strategies/{edge_hyperedge_set.py → hyperedge_set.py} +2 -2
- exonware/xwnode/edges/strategies/incidence_matrix.py +250 -0
- exonware/xwnode/edges/strategies/k2_tree.py +613 -0
- exonware/xwnode/edges/strategies/link_cut.py +626 -0
- exonware/xwnode/edges/strategies/multiplex.py +532 -0
- exonware/xwnode/edges/strategies/{edge_neural_graph.py → neural_graph.py} +2 -2
- exonware/xwnode/edges/strategies/{edge_octree.py → octree.py} +69 -11
- exonware/xwnode/edges/strategies/{edge_quadtree.py → quadtree.py} +66 -10
- exonware/xwnode/edges/strategies/roaring_adj.py +438 -0
- exonware/xwnode/edges/strategies/{edge_rtree.py → rtree.py} +43 -5
- exonware/xwnode/edges/strategies/{edge_temporal_edgeset.py → temporal_edgeset.py} +24 -5
- exonware/xwnode/edges/strategies/{edge_tree_graph_basic.py → tree_graph_basic.py} +78 -7
- exonware/xwnode/edges/strategies/{edge_weighted_graph.py → weighted_graph.py} +188 -10
- exonware/xwnode/errors.py +3 -6
- exonware/xwnode/facade.py +20 -20
- exonware/xwnode/nodes/strategies/__init__.py +29 -9
- exonware/xwnode/nodes/strategies/adjacency_list.py +650 -177
- exonware/xwnode/nodes/strategies/aho_corasick.py +358 -183
- exonware/xwnode/nodes/strategies/array_list.py +36 -3
- exonware/xwnode/nodes/strategies/art.py +581 -0
- exonware/xwnode/nodes/strategies/{node_avl_tree.py → avl_tree.py} +77 -6
- exonware/xwnode/nodes/strategies/{node_b_plus_tree.py → b_plus_tree.py} +81 -40
- exonware/xwnode/nodes/strategies/{node_btree.py → b_tree.py} +79 -9
- exonware/xwnode/nodes/strategies/base.py +469 -98
- exonware/xwnode/nodes/strategies/{node_bitmap.py → bitmap.py} +12 -12
- exonware/xwnode/nodes/strategies/{node_bitset_dynamic.py → bitset_dynamic.py} +11 -11
- exonware/xwnode/nodes/strategies/{node_bloom_filter.py → bloom_filter.py} +15 -2
- exonware/xwnode/nodes/strategies/bloomier_filter.py +519 -0
- exonware/xwnode/nodes/strategies/bw_tree.py +531 -0
- exonware/xwnode/nodes/strategies/contracts.py +1 -1
- exonware/xwnode/nodes/strategies/{node_count_min_sketch.py → count_min_sketch.py} +3 -2
- exonware/xwnode/nodes/strategies/{node_cow_tree.py → cow_tree.py} +135 -13
- exonware/xwnode/nodes/strategies/crdt_map.py +629 -0
- exonware/xwnode/nodes/strategies/{node_cuckoo_hash.py → cuckoo_hash.py} +2 -2
- exonware/xwnode/nodes/strategies/{node_xdata_optimized.py → data_interchange_optimized.py} +21 -4
- exonware/xwnode/nodes/strategies/dawg.py +876 -0
- exonware/xwnode/nodes/strategies/deque.py +321 -153
- exonware/xwnode/nodes/strategies/extendible_hash.py +93 -0
- exonware/xwnode/nodes/strategies/{node_fenwick_tree.py → fenwick_tree.py} +111 -19
- exonware/xwnode/nodes/strategies/hamt.py +403 -0
- exonware/xwnode/nodes/strategies/hash_map.py +354 -67
- exonware/xwnode/nodes/strategies/heap.py +105 -5
- exonware/xwnode/nodes/strategies/hopscotch_hash.py +525 -0
- exonware/xwnode/nodes/strategies/{node_hyperloglog.py → hyperloglog.py} +6 -5
- exonware/xwnode/nodes/strategies/interval_tree.py +742 -0
- exonware/xwnode/nodes/strategies/kd_tree.py +703 -0
- exonware/xwnode/nodes/strategies/learned_index.py +533 -0
- exonware/xwnode/nodes/strategies/linear_hash.py +93 -0
- exonware/xwnode/nodes/strategies/linked_list.py +316 -119
- exonware/xwnode/nodes/strategies/{node_lsm_tree.py → lsm_tree.py} +219 -15
- exonware/xwnode/nodes/strategies/masstree.py +130 -0
- exonware/xwnode/nodes/strategies/{node_persistent_tree.py → persistent_tree.py} +149 -9
- exonware/xwnode/nodes/strategies/priority_queue.py +544 -132
- exonware/xwnode/nodes/strategies/queue.py +249 -120
- exonware/xwnode/nodes/strategies/{node_red_black_tree.py → red_black_tree.py} +183 -72
- exonware/xwnode/nodes/strategies/{node_roaring_bitmap.py → roaring_bitmap.py} +19 -6
- exonware/xwnode/nodes/strategies/rope.py +717 -0
- exonware/xwnode/nodes/strategies/{node_segment_tree.py → segment_tree.py} +106 -106
- exonware/xwnode/nodes/strategies/{node_set_hash.py → set_hash.py} +30 -29
- exonware/xwnode/nodes/strategies/{node_skip_list.py → skip_list.py} +74 -6
- exonware/xwnode/nodes/strategies/sparse_matrix.py +427 -131
- exonware/xwnode/nodes/strategies/{node_splay_tree.py → splay_tree.py} +55 -6
- exonware/xwnode/nodes/strategies/stack.py +244 -112
- exonware/xwnode/nodes/strategies/{node_suffix_array.py → suffix_array.py} +5 -1
- exonware/xwnode/nodes/strategies/t_tree.py +94 -0
- exonware/xwnode/nodes/strategies/{node_treap.py → treap.py} +75 -6
- exonware/xwnode/nodes/strategies/{node_tree_graph_hybrid.py → tree_graph_hybrid.py} +46 -5
- exonware/xwnode/nodes/strategies/trie.py +153 -9
- exonware/xwnode/nodes/strategies/union_find.py +111 -5
- exonware/xwnode/nodes/strategies/veb_tree.py +856 -0
- exonware/xwnode/strategies/__init__.py +5 -51
- exonware/xwnode/version.py +3 -3
- {exonware_xwnode-0.0.1.22.dist-info → exonware_xwnode-0.0.1.23.dist-info}/METADATA +23 -3
- exonware_xwnode-0.0.1.23.dist-info/RECORD +130 -0
- exonware/xwnode/edges/strategies/edge_adj_list.py +0 -353
- exonware/xwnode/edges/strategies/edge_adj_matrix.py +0 -445
- exonware/xwnode/nodes/strategies/_base_node.py +0 -307
- exonware/xwnode/nodes/strategies/node_aho_corasick.py +0 -525
- exonware/xwnode/nodes/strategies/node_array_list.py +0 -179
- exonware/xwnode/nodes/strategies/node_hash_map.py +0 -273
- exonware/xwnode/nodes/strategies/node_heap.py +0 -196
- exonware/xwnode/nodes/strategies/node_linked_list.py +0 -413
- exonware/xwnode/nodes/strategies/node_trie.py +0 -257
- exonware/xwnode/nodes/strategies/node_union_find.py +0 -192
- exonware/xwnode/queries/executors/__init__.py +0 -47
- exonware/xwnode/queries/executors/advanced/__init__.py +0 -37
- exonware/xwnode/queries/executors/advanced/aggregate_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/ask_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/construct_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/describe_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/for_loop_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/foreach_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/join_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/let_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/mutation_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/options_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/pipe_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/subscribe_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/subscription_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/union_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/window_executor.py +0 -51
- exonware/xwnode/queries/executors/advanced/with_cte_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/__init__.py +0 -21
- exonware/xwnode/queries/executors/aggregation/avg_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/count_executor.py +0 -38
- exonware/xwnode/queries/executors/aggregation/distinct_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/group_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/having_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/max_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/min_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/sum_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/summarize_executor.py +0 -50
- exonware/xwnode/queries/executors/array/__init__.py +0 -9
- exonware/xwnode/queries/executors/array/indexing_executor.py +0 -51
- exonware/xwnode/queries/executors/array/slicing_executor.py +0 -51
- exonware/xwnode/queries/executors/base.py +0 -257
- exonware/xwnode/queries/executors/capability_checker.py +0 -204
- exonware/xwnode/queries/executors/contracts.py +0 -166
- exonware/xwnode/queries/executors/core/__init__.py +0 -17
- exonware/xwnode/queries/executors/core/create_executor.py +0 -96
- exonware/xwnode/queries/executors/core/delete_executor.py +0 -99
- exonware/xwnode/queries/executors/core/drop_executor.py +0 -100
- exonware/xwnode/queries/executors/core/insert_executor.py +0 -39
- exonware/xwnode/queries/executors/core/select_executor.py +0 -152
- exonware/xwnode/queries/executors/core/update_executor.py +0 -102
- exonware/xwnode/queries/executors/data/__init__.py +0 -13
- exonware/xwnode/queries/executors/data/alter_executor.py +0 -50
- exonware/xwnode/queries/executors/data/load_executor.py +0 -50
- exonware/xwnode/queries/executors/data/merge_executor.py +0 -50
- exonware/xwnode/queries/executors/data/store_executor.py +0 -50
- exonware/xwnode/queries/executors/defs.py +0 -93
- exonware/xwnode/queries/executors/engine.py +0 -221
- exonware/xwnode/queries/executors/errors.py +0 -68
- exonware/xwnode/queries/executors/filtering/__init__.py +0 -25
- exonware/xwnode/queries/executors/filtering/between_executor.py +0 -80
- exonware/xwnode/queries/executors/filtering/filter_executor.py +0 -79
- exonware/xwnode/queries/executors/filtering/has_executor.py +0 -70
- exonware/xwnode/queries/executors/filtering/in_executor.py +0 -70
- exonware/xwnode/queries/executors/filtering/like_executor.py +0 -76
- exonware/xwnode/queries/executors/filtering/optional_executor.py +0 -76
- exonware/xwnode/queries/executors/filtering/range_executor.py +0 -80
- exonware/xwnode/queries/executors/filtering/term_executor.py +0 -77
- exonware/xwnode/queries/executors/filtering/values_executor.py +0 -71
- exonware/xwnode/queries/executors/filtering/where_executor.py +0 -44
- exonware/xwnode/queries/executors/graph/__init__.py +0 -15
- exonware/xwnode/queries/executors/graph/in_traverse_executor.py +0 -51
- exonware/xwnode/queries/executors/graph/match_executor.py +0 -51
- exonware/xwnode/queries/executors/graph/out_executor.py +0 -51
- exonware/xwnode/queries/executors/graph/path_executor.py +0 -51
- exonware/xwnode/queries/executors/graph/return_executor.py +0 -51
- exonware/xwnode/queries/executors/ordering/__init__.py +0 -9
- exonware/xwnode/queries/executors/ordering/by_executor.py +0 -50
- exonware/xwnode/queries/executors/ordering/order_executor.py +0 -51
- exonware/xwnode/queries/executors/projection/__init__.py +0 -9
- exonware/xwnode/queries/executors/projection/extend_executor.py +0 -50
- exonware/xwnode/queries/executors/projection/project_executor.py +0 -50
- exonware/xwnode/queries/executors/registry.py +0 -173
- exonware/xwnode/queries/parsers/__init__.py +0 -26
- exonware/xwnode/queries/parsers/base.py +0 -86
- exonware/xwnode/queries/parsers/contracts.py +0 -46
- exonware/xwnode/queries/parsers/errors.py +0 -53
- exonware/xwnode/queries/parsers/sql_param_extractor.py +0 -318
- exonware/xwnode/queries/strategies/__init__.py +0 -24
- exonware/xwnode/queries/strategies/base.py +0 -236
- exonware/xwnode/queries/strategies/cql.py +0 -201
- exonware/xwnode/queries/strategies/cypher.py +0 -181
- exonware/xwnode/queries/strategies/datalog.py +0 -70
- exonware/xwnode/queries/strategies/elastic_dsl.py +0 -70
- exonware/xwnode/queries/strategies/eql.py +0 -70
- exonware/xwnode/queries/strategies/flux.py +0 -70
- exonware/xwnode/queries/strategies/gql.py +0 -70
- exonware/xwnode/queries/strategies/graphql.py +0 -240
- exonware/xwnode/queries/strategies/gremlin.py +0 -181
- exonware/xwnode/queries/strategies/hiveql.py +0 -214
- exonware/xwnode/queries/strategies/hql.py +0 -70
- exonware/xwnode/queries/strategies/jmespath.py +0 -219
- exonware/xwnode/queries/strategies/jq.py +0 -66
- exonware/xwnode/queries/strategies/json_query.py +0 -66
- exonware/xwnode/queries/strategies/jsoniq.py +0 -248
- exonware/xwnode/queries/strategies/kql.py +0 -70
- exonware/xwnode/queries/strategies/linq.py +0 -238
- exonware/xwnode/queries/strategies/logql.py +0 -70
- exonware/xwnode/queries/strategies/mql.py +0 -68
- exonware/xwnode/queries/strategies/n1ql.py +0 -210
- exonware/xwnode/queries/strategies/partiql.py +0 -70
- exonware/xwnode/queries/strategies/pig.py +0 -215
- exonware/xwnode/queries/strategies/promql.py +0 -70
- exonware/xwnode/queries/strategies/sparql.py +0 -220
- exonware/xwnode/queries/strategies/sql.py +0 -275
- exonware/xwnode/queries/strategies/xml_query.py +0 -66
- exonware/xwnode/queries/strategies/xpath.py +0 -223
- exonware/xwnode/queries/strategies/xquery.py +0 -258
- exonware/xwnode/queries/strategies/xwnode_executor.py +0 -332
- exonware/xwnode/queries/strategies/xwquery.py +0 -456
- exonware_xwnode-0.0.1.22.dist-info/RECORD +0 -214
- /exonware/xwnode/nodes/strategies/{node_ordered_map.py → ordered_map.py} +0 -0
- /exonware/xwnode/nodes/strategies/{node_ordered_map_balanced.py → ordered_map_balanced.py} +0 -0
- /exonware/xwnode/nodes/strategies/{node_patricia.py → patricia.py} +0 -0
- /exonware/xwnode/nodes/strategies/{node_radix_trie.py → radix_trie.py} +0 -0
- /exonware/xwnode/nodes/strategies/{node_set_tree.py → set_tree.py} +0 -0
- {exonware_xwnode-0.0.1.22.dist-info → exonware_xwnode-0.0.1.23.dist-info}/WHEEL +0 -0
- {exonware_xwnode-0.0.1.22.dist-info → exonware_xwnode-0.0.1.23.dist-info}/licenses/LICENSE +0 -0
@@ -1,273 +0,0 @@
|
|
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_node import aNodeStrategy
|
10
|
-
from ...defs import NodeMode, NodeTrait
|
11
|
-
from ..utils import (
|
12
|
-
safe_to_native_conversion,
|
13
|
-
is_list_like,
|
14
|
-
create_basic_metrics,
|
15
|
-
create_basic_backend_info,
|
16
|
-
create_size_tracker,
|
17
|
-
create_access_tracker,
|
18
|
-
update_size_tracker,
|
19
|
-
record_access,
|
20
|
-
get_access_metrics
|
21
|
-
)
|
22
|
-
|
23
|
-
|
24
|
-
class xHashMapStrategy(aNodeStrategy):
|
25
|
-
"""
|
26
|
-
Hash Map node strategy for fast O(1) key-value operations.
|
27
|
-
|
28
|
-
Uses Python's built-in dictionary for optimal performance
|
29
|
-
with associative operations.
|
30
|
-
"""
|
31
|
-
|
32
|
-
# Strategy type classification
|
33
|
-
STRATEGY_TYPE = NodeType.TREE
|
34
|
-
|
35
|
-
|
36
|
-
def __init__(self, traits: NodeTrait = NodeTrait.NONE, **options):
|
37
|
-
"""Initialize the hash map strategy."""
|
38
|
-
super().__init__(NodeMode.HASH_MAP, traits, **options)
|
39
|
-
self._data: Dict[str, Any] = {}
|
40
|
-
self._size_tracker = create_size_tracker()
|
41
|
-
self._access_tracker = create_access_tracker()
|
42
|
-
|
43
|
-
def get_supported_traits(self) -> NodeTrait:
|
44
|
-
"""Get the traits supported by the hash map strategy."""
|
45
|
-
return (NodeTrait.INDEXED | NodeTrait.HIERARCHICAL)
|
46
|
-
|
47
|
-
# ============================================================================
|
48
|
-
# CORE OPERATIONS
|
49
|
-
# ============================================================================
|
50
|
-
|
51
|
-
def put(self, key: Any, value: Any = None) -> None:
|
52
|
-
"""Store a key-value pair."""
|
53
|
-
str_key = str(key)
|
54
|
-
if str_key not in self._data:
|
55
|
-
update_size_tracker(self._size_tracker, 1)
|
56
|
-
self._data[str_key] = value
|
57
|
-
record_access(self._access_tracker, 'put_count')
|
58
|
-
|
59
|
-
def get(self, path: str, default: Any = None) -> Any:
|
60
|
-
"""Retrieve a value by path."""
|
61
|
-
record_access(self._access_tracker, 'get_count')
|
62
|
-
|
63
|
-
# Handle simple key lookup
|
64
|
-
if '.' not in path:
|
65
|
-
return self._data.get(path, default)
|
66
|
-
|
67
|
-
# Handle path navigation
|
68
|
-
parts = path.split('.')
|
69
|
-
current = self._data
|
70
|
-
|
71
|
-
for part in parts:
|
72
|
-
if isinstance(current, dict) and part in current:
|
73
|
-
current = current[part]
|
74
|
-
else:
|
75
|
-
return default
|
76
|
-
|
77
|
-
return current
|
78
|
-
|
79
|
-
def has(self, key: Any) -> bool:
|
80
|
-
"""Check if key exists."""
|
81
|
-
return str(key) in self._data
|
82
|
-
|
83
|
-
def exists(self, path: str) -> bool:
|
84
|
-
"""Check if path exists."""
|
85
|
-
return self.get(path) is not None
|
86
|
-
|
87
|
-
def remove(self, key: Any) -> bool:
|
88
|
-
"""Remove a key-value pair."""
|
89
|
-
str_key = str(key)
|
90
|
-
if str_key in self._data:
|
91
|
-
del self._data[str_key]
|
92
|
-
update_size_tracker(self._size_tracker, -1)
|
93
|
-
record_access(self._access_tracker, 'delete_count')
|
94
|
-
return True
|
95
|
-
return False
|
96
|
-
|
97
|
-
def delete(self, key: Any) -> bool:
|
98
|
-
"""Remove a key-value pair (alias for remove)."""
|
99
|
-
return self.remove(key)
|
100
|
-
|
101
|
-
def put(self, path: str, value: Any) -> 'xHashMapStrategy':
|
102
|
-
"""Set a value at path."""
|
103
|
-
# Handle simple key setting (non-string or string without dots)
|
104
|
-
if not isinstance(path, str) or '.' not in path:
|
105
|
-
str_key = str(path)
|
106
|
-
if str_key not in self._data:
|
107
|
-
update_size_tracker(self._size_tracker, 1)
|
108
|
-
self._data[str_key] = value
|
109
|
-
record_access(self._access_tracker, 'put_count')
|
110
|
-
return self
|
111
|
-
|
112
|
-
# Handle path setting
|
113
|
-
parts = path.split('.')
|
114
|
-
current = self._data
|
115
|
-
|
116
|
-
# Navigate to the parent of the target
|
117
|
-
for part in parts[:-1]:
|
118
|
-
if part not in current:
|
119
|
-
current[part] = {}
|
120
|
-
current = current[part]
|
121
|
-
|
122
|
-
# Set the value
|
123
|
-
current[parts[-1]] = value
|
124
|
-
return self
|
125
|
-
|
126
|
-
def clear(self) -> None:
|
127
|
-
"""Clear all data."""
|
128
|
-
self._data.clear()
|
129
|
-
self._size_tracker['size'] = 0
|
130
|
-
|
131
|
-
def keys(self) -> Iterator[str]:
|
132
|
-
"""Get all keys."""
|
133
|
-
return iter(self._data.keys())
|
134
|
-
|
135
|
-
def values(self) -> Iterator[Any]:
|
136
|
-
"""Get all values."""
|
137
|
-
return iter(self._data.values())
|
138
|
-
|
139
|
-
def items(self) -> Iterator[tuple[str, Any]]:
|
140
|
-
"""Get all key-value pairs."""
|
141
|
-
return iter(self._data.items())
|
142
|
-
|
143
|
-
def __len__(self) -> int:
|
144
|
-
"""Get the number of items."""
|
145
|
-
return self._size_tracker['size']
|
146
|
-
|
147
|
-
def __getitem__(self, key: Union[str, int]) -> Any:
|
148
|
-
"""Get item by key or index."""
|
149
|
-
return self.get(str(key))
|
150
|
-
|
151
|
-
def __setitem__(self, key: Union[str, int], value: Any) -> None:
|
152
|
-
"""Set item by key or index."""
|
153
|
-
self.put(str(key), value)
|
154
|
-
|
155
|
-
def __contains__(self, key: Union[str, int]) -> bool:
|
156
|
-
"""Check if key exists."""
|
157
|
-
return self.has(str(key))
|
158
|
-
|
159
|
-
def __iter__(self) -> Iterator[Any]:
|
160
|
-
"""Iterate over values."""
|
161
|
-
return self.values()
|
162
|
-
|
163
|
-
@classmethod
|
164
|
-
def create_from_data(cls, data: Any) -> 'xHashMapStrategy':
|
165
|
-
"""
|
166
|
-
Create a new strategy instance from data.
|
167
|
-
|
168
|
-
Args:
|
169
|
-
data: The data to create the strategy from
|
170
|
-
|
171
|
-
Returns:
|
172
|
-
A new strategy instance containing the data
|
173
|
-
"""
|
174
|
-
instance = cls()
|
175
|
-
if isinstance(data, dict):
|
176
|
-
for key, value in data.items():
|
177
|
-
instance.put(key, value)
|
178
|
-
elif isinstance(data, (list, tuple)):
|
179
|
-
for i, value in enumerate(data):
|
180
|
-
instance.put(i, value)
|
181
|
-
else:
|
182
|
-
# For primitive values, store directly
|
183
|
-
instance.put('_value', data)
|
184
|
-
return instance
|
185
|
-
|
186
|
-
def to_native(self) -> Dict[str, Any]:
|
187
|
-
"""Convert to native Python dictionary."""
|
188
|
-
# Return a copy with all nested XWNode objects converted to native types
|
189
|
-
return {k: safe_to_native_conversion(v) for k, v in self._data.items()}
|
190
|
-
|
191
|
-
@property
|
192
|
-
def value(self) -> Any:
|
193
|
-
"""Get the value of this node."""
|
194
|
-
# If this is a primitive value node (has only _value key), return the value directly
|
195
|
-
if len(self._data) == 1 and '_value' in self._data:
|
196
|
-
return self._data['_value']
|
197
|
-
# Otherwise return the native representation
|
198
|
-
return self.to_native()
|
199
|
-
|
200
|
-
@property
|
201
|
-
def is_leaf(self) -> bool:
|
202
|
-
"""Check if this is a leaf node."""
|
203
|
-
return len(self._data) == 0
|
204
|
-
|
205
|
-
@property
|
206
|
-
def is_list(self) -> bool:
|
207
|
-
"""This is never a list strategy."""
|
208
|
-
return False
|
209
|
-
|
210
|
-
@property
|
211
|
-
def is_dict(self) -> bool:
|
212
|
-
"""This is always a dict strategy."""
|
213
|
-
return True
|
214
|
-
|
215
|
-
@property
|
216
|
-
def is_reference(self) -> bool:
|
217
|
-
"""Check if this is a reference node."""
|
218
|
-
return False
|
219
|
-
|
220
|
-
@property
|
221
|
-
def is_object(self) -> bool:
|
222
|
-
"""Check if this is an object node."""
|
223
|
-
return False
|
224
|
-
|
225
|
-
@property
|
226
|
-
def type(self) -> str:
|
227
|
-
"""Get the type of this node."""
|
228
|
-
return "dict"
|
229
|
-
|
230
|
-
@property
|
231
|
-
def uri(self) -> Optional[str]:
|
232
|
-
"""Get the URI of this node."""
|
233
|
-
return None
|
234
|
-
|
235
|
-
@property
|
236
|
-
def reference_type(self) -> Optional[str]:
|
237
|
-
"""Get the reference type of this node."""
|
238
|
-
return None
|
239
|
-
|
240
|
-
@property
|
241
|
-
def object_type(self) -> Optional[str]:
|
242
|
-
"""Get the object type of this node."""
|
243
|
-
return None
|
244
|
-
|
245
|
-
@property
|
246
|
-
def mime_type(self) -> Optional[str]:
|
247
|
-
"""Get the MIME type of this node."""
|
248
|
-
return None
|
249
|
-
|
250
|
-
@property
|
251
|
-
def metadata(self) -> Optional[Dict[str, Any]]:
|
252
|
-
"""Get the metadata of this node."""
|
253
|
-
return None
|
254
|
-
|
255
|
-
# ============================================================================
|
256
|
-
# PERFORMANCE CHARACTERISTICS
|
257
|
-
# ============================================================================
|
258
|
-
|
259
|
-
def backend_info(self) -> Dict[str, Any]:
|
260
|
-
"""Get backend implementation info."""
|
261
|
-
return create_basic_backend_info(
|
262
|
-
'HASH_MAP',
|
263
|
-
'Python dict',
|
264
|
-
load_factor=len(self._data) / max(8, len(self._data)),
|
265
|
-
collision_rate='~5% (Python dict optimized)'
|
266
|
-
)
|
267
|
-
|
268
|
-
def metrics(self) -> Dict[str, Any]:
|
269
|
-
"""Get performance metrics."""
|
270
|
-
base_metrics = create_basic_metrics('HASH_MAP', self._size_tracker['size'])
|
271
|
-
access_metrics = get_access_metrics(self._access_tracker)
|
272
|
-
base_metrics.update(access_metrics)
|
273
|
-
return base_metrics
|
@@ -1,196 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Heap Node Strategy Implementation
|
3
|
-
|
4
|
-
This module implements the HEAP strategy for priority queue operations.
|
5
|
-
"""
|
6
|
-
|
7
|
-
import heapq
|
8
|
-
from typing import Any, Iterator, List, Optional, Dict
|
9
|
-
from .base import ANodeTreeStrategy
|
10
|
-
from .contracts import NodeType
|
11
|
-
from ...defs import NodeMode, NodeTrait
|
12
|
-
from ..utils import (
|
13
|
-
MinHeap,
|
14
|
-
safe_to_native_conversion,
|
15
|
-
create_basic_metrics,
|
16
|
-
create_basic_backend_info,
|
17
|
-
create_size_tracker,
|
18
|
-
create_access_tracker,
|
19
|
-
update_size_tracker,
|
20
|
-
record_access,
|
21
|
-
get_access_metrics
|
22
|
-
)
|
23
|
-
|
24
|
-
|
25
|
-
class HeapStrategy(ANodeTreeStrategy):
|
26
|
-
"""
|
27
|
-
Heap node strategy for priority queue operations.
|
28
|
-
|
29
|
-
Optimized for push, pop, and peek operations with config
|
30
|
-
|
31
|
-
# Strategy type classification
|
32
|
-
STRATEGY_TYPE = NodeType.TREE
|
33
|
-
urable min/max behavior.
|
34
|
-
"""
|
35
|
-
|
36
|
-
def __init__(self, traits: NodeTrait = NodeTrait.NONE, **options):
|
37
|
-
"""Initialize the heap strategy."""
|
38
|
-
super().__init__(NodeMode.HEAP, traits, **options)
|
39
|
-
self._is_max_heap = options.get('max_heap', False)
|
40
|
-
self._heap = MinHeap(max_heap=self._is_max_heap)
|
41
|
-
self._size_tracker = create_size_tracker()
|
42
|
-
self._access_tracker = create_access_tracker()
|
43
|
-
|
44
|
-
def get_supported_traits(self) -> NodeTrait:
|
45
|
-
"""Get the traits supported by the heap strategy."""
|
46
|
-
return (NodeTrait.ORDERED | NodeTrait.PRIORITY_QUEUE)
|
47
|
-
|
48
|
-
# ============================================================================
|
49
|
-
# CORE OPERATIONS
|
50
|
-
# ============================================================================
|
51
|
-
|
52
|
-
def put(self, key: Any, value: Any = None) -> None:
|
53
|
-
"""Store a key-value pair (key is priority, value is data)."""
|
54
|
-
priority = float(key) if key is not None else 0.0
|
55
|
-
data = value if value is not None else key
|
56
|
-
self._heap.push(data, priority)
|
57
|
-
update_size_tracker(self._size_tracker, 1)
|
58
|
-
record_access(self._access_tracker, 'put_count')
|
59
|
-
|
60
|
-
def get(self, key: Any, default: Any = None) -> Any:
|
61
|
-
"""Retrieve a value by key (peek operation)."""
|
62
|
-
record_access(self._access_tracker, 'get_count')
|
63
|
-
try:
|
64
|
-
return self._heap.peek()
|
65
|
-
except IndexError:
|
66
|
-
return default
|
67
|
-
|
68
|
-
def has(self, key: Any) -> bool:
|
69
|
-
"""Check if heap has any items."""
|
70
|
-
return len(self._heap) > 0
|
71
|
-
|
72
|
-
def remove(self, key: Any) -> bool:
|
73
|
-
"""Remove the top item from the heap."""
|
74
|
-
try:
|
75
|
-
self._heap.pop()
|
76
|
-
update_size_tracker(self._size_tracker, -1)
|
77
|
-
record_access(self._access_tracker, 'delete_count')
|
78
|
-
return True
|
79
|
-
except IndexError:
|
80
|
-
return False
|
81
|
-
|
82
|
-
def delete(self, key: Any) -> bool:
|
83
|
-
"""Remove the top item (alias for remove)."""
|
84
|
-
return self.remove(key)
|
85
|
-
|
86
|
-
def clear(self) -> None:
|
87
|
-
"""Clear all data."""
|
88
|
-
self._heap = MinHeap(max_heap=self._is_max_heap)
|
89
|
-
self._size_tracker['size'] = 0
|
90
|
-
|
91
|
-
def keys(self) -> Iterator[str]:
|
92
|
-
"""Get all keys (priorities) in heap order."""
|
93
|
-
return (str(priority) for priority, _, _ in self._heap._heap)
|
94
|
-
|
95
|
-
def values(self) -> Iterator[Any]:
|
96
|
-
"""Get all values in heap order."""
|
97
|
-
return (value for _, _, value in self._heap._heap)
|
98
|
-
|
99
|
-
def items(self) -> Iterator[tuple[str, Any]]:
|
100
|
-
"""Get all key-value pairs in heap order."""
|
101
|
-
return ((str(priority), value) for priority, _, value in self._heap._heap)
|
102
|
-
|
103
|
-
def __len__(self) -> int:
|
104
|
-
"""Get the number of items."""
|
105
|
-
return self._size_tracker['size']
|
106
|
-
|
107
|
-
def to_native(self) -> List[Any]:
|
108
|
-
"""Convert to native Python list sorted by priority."""
|
109
|
-
return [safe_to_native_conversion(value) for _, _, value in sorted(self._heap._heap)]
|
110
|
-
|
111
|
-
@property
|
112
|
-
def is_list(self) -> bool:
|
113
|
-
"""This behaves like a list (priority-ordered)."""
|
114
|
-
return True
|
115
|
-
|
116
|
-
@property
|
117
|
-
def is_dict(self) -> bool:
|
118
|
-
"""This is not a dict strategy."""
|
119
|
-
return False
|
120
|
-
|
121
|
-
# ============================================================================
|
122
|
-
# HEAP-SPECIFIC OPERATIONS
|
123
|
-
# ============================================================================
|
124
|
-
|
125
|
-
def push(self, value: Any, priority: float = None) -> str:
|
126
|
-
"""Push a value with optional priority. Returns the generated key."""
|
127
|
-
key = self._heap.push(value, priority)
|
128
|
-
update_size_tracker(self._size_tracker, 1)
|
129
|
-
return key
|
130
|
-
|
131
|
-
def pop(self) -> Any:
|
132
|
-
"""Remove and return the highest/lowest priority item."""
|
133
|
-
value = self._heap.pop()
|
134
|
-
update_size_tracker(self._size_tracker, -1)
|
135
|
-
return value
|
136
|
-
|
137
|
-
def peek(self) -> Any:
|
138
|
-
"""Peek at the highest/lowest priority item without removing."""
|
139
|
-
return self._heap.peek()
|
140
|
-
|
141
|
-
def peek_priority(self) -> float:
|
142
|
-
"""Peek at the priority of the top item."""
|
143
|
-
return self._heap.peek_priority()
|
144
|
-
|
145
|
-
def pushpop(self, value: Any, priority: float = None) -> Any:
|
146
|
-
"""Push value and pop the highest/lowest priority item efficiently."""
|
147
|
-
old_value = self._heap.pushpop(value, priority)
|
148
|
-
if old_value is None:
|
149
|
-
update_size_tracker(self._size_tracker, 1)
|
150
|
-
return old_value
|
151
|
-
|
152
|
-
def replace(self, value: Any, priority: float = None) -> Any:
|
153
|
-
"""Replace the top item and return the old top item."""
|
154
|
-
old_value = self._heap.replace(value, priority)
|
155
|
-
return old_value
|
156
|
-
|
157
|
-
def heapify(self) -> None:
|
158
|
-
"""Rebuild the heap in-place."""
|
159
|
-
self._heap.heapify()
|
160
|
-
|
161
|
-
def nlargest(self, n: int) -> List[Any]:
|
162
|
-
"""Get the n largest items."""
|
163
|
-
return self._heap.nlargest(n)
|
164
|
-
|
165
|
-
def nsmallest(self, n: int) -> List[Any]:
|
166
|
-
"""Get the n smallest items."""
|
167
|
-
return self._heap.nsmallest(n)
|
168
|
-
|
169
|
-
# ============================================================================
|
170
|
-
# PERFORMANCE CHARACTERISTICS
|
171
|
-
# ============================================================================
|
172
|
-
|
173
|
-
def backend_info(self) -> Dict[str, Any]:
|
174
|
-
"""Get backend implementation info."""
|
175
|
-
heap_type = "Max Heap" if self._is_max_heap else "Min Heap"
|
176
|
-
return create_basic_backend_info(
|
177
|
-
'HEAP',
|
178
|
-
f'Python heapq ({heap_type})',
|
179
|
-
complexity={
|
180
|
-
'push': 'O(log n)',
|
181
|
-
'pop': 'O(log n)',
|
182
|
-
'peek': 'O(1)',
|
183
|
-
'heapify': 'O(n)'
|
184
|
-
}
|
185
|
-
)
|
186
|
-
|
187
|
-
def metrics(self) -> Dict[str, Any]:
|
188
|
-
"""Get performance metrics."""
|
189
|
-
base_metrics = create_basic_metrics('HEAP', self._size_tracker['size'])
|
190
|
-
access_metrics = get_access_metrics(self._access_tracker)
|
191
|
-
base_metrics.update(access_metrics)
|
192
|
-
base_metrics.update({
|
193
|
-
'heap_type': 'max' if self._is_max_heap else 'min',
|
194
|
-
'is_empty': len(self._heap) == 0
|
195
|
-
})
|
196
|
-
return base_metrics
|