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.
Files changed (248) hide show
  1. exonware/__init__.py +1 -1
  2. exonware/xwnode/__init__.py +18 -5
  3. exonware/xwnode/add_strategy_types.py +165 -0
  4. exonware/xwnode/common/__init__.py +1 -1
  5. exonware/xwnode/common/graph/__init__.py +30 -0
  6. exonware/xwnode/common/graph/caching.py +131 -0
  7. exonware/xwnode/common/graph/contracts.py +100 -0
  8. exonware/xwnode/common/graph/errors.py +44 -0
  9. exonware/xwnode/common/graph/indexing.py +260 -0
  10. exonware/xwnode/common/graph/manager.py +568 -0
  11. exonware/xwnode/common/management/__init__.py +3 -5
  12. exonware/xwnode/common/management/manager.py +2 -2
  13. exonware/xwnode/common/management/migration.py +3 -3
  14. exonware/xwnode/common/monitoring/__init__.py +3 -5
  15. exonware/xwnode/common/monitoring/metrics.py +6 -2
  16. exonware/xwnode/common/monitoring/pattern_detector.py +1 -1
  17. exonware/xwnode/common/monitoring/performance_monitor.py +5 -1
  18. exonware/xwnode/common/patterns/__init__.py +3 -5
  19. exonware/xwnode/common/patterns/flyweight.py +5 -1
  20. exonware/xwnode/common/patterns/registry.py +202 -183
  21. exonware/xwnode/common/utils/__init__.py +25 -11
  22. exonware/xwnode/common/utils/simple.py +1 -1
  23. exonware/xwnode/config.py +3 -8
  24. exonware/xwnode/contracts.py +4 -105
  25. exonware/xwnode/defs.py +413 -159
  26. exonware/xwnode/edges/strategies/__init__.py +86 -4
  27. exonware/xwnode/edges/strategies/_base_edge.py +2 -2
  28. exonware/xwnode/edges/strategies/adj_list.py +287 -121
  29. exonware/xwnode/edges/strategies/adj_matrix.py +316 -222
  30. exonware/xwnode/edges/strategies/base.py +1 -1
  31. exonware/xwnode/edges/strategies/{edge_bidir_wrapper.py → bidir_wrapper.py} +45 -4
  32. exonware/xwnode/edges/strategies/bitemporal.py +520 -0
  33. exonware/xwnode/edges/strategies/{edge_block_adj_matrix.py → block_adj_matrix.py} +77 -6
  34. exonware/xwnode/edges/strategies/bv_graph.py +664 -0
  35. exonware/xwnode/edges/strategies/compressed_graph.py +217 -0
  36. exonware/xwnode/edges/strategies/{edge_coo.py → coo.py} +46 -4
  37. exonware/xwnode/edges/strategies/{edge_csc.py → csc.py} +45 -4
  38. exonware/xwnode/edges/strategies/{edge_csr.py → csr.py} +94 -12
  39. exonware/xwnode/edges/strategies/{edge_dynamic_adj_list.py → dynamic_adj_list.py} +46 -4
  40. exonware/xwnode/edges/strategies/edge_list.py +168 -0
  41. exonware/xwnode/edges/strategies/edge_property_store.py +2 -2
  42. exonware/xwnode/edges/strategies/euler_tour.py +560 -0
  43. exonware/xwnode/edges/strategies/{edge_flow_network.py → flow_network.py} +2 -2
  44. exonware/xwnode/edges/strategies/graphblas.py +449 -0
  45. exonware/xwnode/edges/strategies/hnsw.py +637 -0
  46. exonware/xwnode/edges/strategies/hop2_labels.py +467 -0
  47. exonware/xwnode/edges/strategies/{edge_hyperedge_set.py → hyperedge_set.py} +2 -2
  48. exonware/xwnode/edges/strategies/incidence_matrix.py +250 -0
  49. exonware/xwnode/edges/strategies/k2_tree.py +613 -0
  50. exonware/xwnode/edges/strategies/link_cut.py +626 -0
  51. exonware/xwnode/edges/strategies/multiplex.py +532 -0
  52. exonware/xwnode/edges/strategies/{edge_neural_graph.py → neural_graph.py} +2 -2
  53. exonware/xwnode/edges/strategies/{edge_octree.py → octree.py} +69 -11
  54. exonware/xwnode/edges/strategies/{edge_quadtree.py → quadtree.py} +66 -10
  55. exonware/xwnode/edges/strategies/roaring_adj.py +438 -0
  56. exonware/xwnode/edges/strategies/{edge_rtree.py → rtree.py} +43 -5
  57. exonware/xwnode/edges/strategies/{edge_temporal_edgeset.py → temporal_edgeset.py} +24 -5
  58. exonware/xwnode/edges/strategies/{edge_tree_graph_basic.py → tree_graph_basic.py} +78 -7
  59. exonware/xwnode/edges/strategies/{edge_weighted_graph.py → weighted_graph.py} +188 -10
  60. exonware/xwnode/errors.py +3 -6
  61. exonware/xwnode/facade.py +20 -20
  62. exonware/xwnode/nodes/strategies/__init__.py +29 -9
  63. exonware/xwnode/nodes/strategies/adjacency_list.py +650 -177
  64. exonware/xwnode/nodes/strategies/aho_corasick.py +358 -183
  65. exonware/xwnode/nodes/strategies/array_list.py +36 -3
  66. exonware/xwnode/nodes/strategies/art.py +581 -0
  67. exonware/xwnode/nodes/strategies/{node_avl_tree.py → avl_tree.py} +77 -6
  68. exonware/xwnode/nodes/strategies/{node_b_plus_tree.py → b_plus_tree.py} +81 -40
  69. exonware/xwnode/nodes/strategies/{node_btree.py → b_tree.py} +79 -9
  70. exonware/xwnode/nodes/strategies/base.py +469 -98
  71. exonware/xwnode/nodes/strategies/{node_bitmap.py → bitmap.py} +12 -12
  72. exonware/xwnode/nodes/strategies/{node_bitset_dynamic.py → bitset_dynamic.py} +11 -11
  73. exonware/xwnode/nodes/strategies/{node_bloom_filter.py → bloom_filter.py} +15 -2
  74. exonware/xwnode/nodes/strategies/bloomier_filter.py +519 -0
  75. exonware/xwnode/nodes/strategies/bw_tree.py +531 -0
  76. exonware/xwnode/nodes/strategies/contracts.py +1 -1
  77. exonware/xwnode/nodes/strategies/{node_count_min_sketch.py → count_min_sketch.py} +3 -2
  78. exonware/xwnode/nodes/strategies/{node_cow_tree.py → cow_tree.py} +135 -13
  79. exonware/xwnode/nodes/strategies/crdt_map.py +629 -0
  80. exonware/xwnode/nodes/strategies/{node_cuckoo_hash.py → cuckoo_hash.py} +2 -2
  81. exonware/xwnode/nodes/strategies/{node_xdata_optimized.py → data_interchange_optimized.py} +21 -4
  82. exonware/xwnode/nodes/strategies/dawg.py +876 -0
  83. exonware/xwnode/nodes/strategies/deque.py +321 -153
  84. exonware/xwnode/nodes/strategies/extendible_hash.py +93 -0
  85. exonware/xwnode/nodes/strategies/{node_fenwick_tree.py → fenwick_tree.py} +111 -19
  86. exonware/xwnode/nodes/strategies/hamt.py +403 -0
  87. exonware/xwnode/nodes/strategies/hash_map.py +354 -67
  88. exonware/xwnode/nodes/strategies/heap.py +105 -5
  89. exonware/xwnode/nodes/strategies/hopscotch_hash.py +525 -0
  90. exonware/xwnode/nodes/strategies/{node_hyperloglog.py → hyperloglog.py} +6 -5
  91. exonware/xwnode/nodes/strategies/interval_tree.py +742 -0
  92. exonware/xwnode/nodes/strategies/kd_tree.py +703 -0
  93. exonware/xwnode/nodes/strategies/learned_index.py +533 -0
  94. exonware/xwnode/nodes/strategies/linear_hash.py +93 -0
  95. exonware/xwnode/nodes/strategies/linked_list.py +316 -119
  96. exonware/xwnode/nodes/strategies/{node_lsm_tree.py → lsm_tree.py} +219 -15
  97. exonware/xwnode/nodes/strategies/masstree.py +130 -0
  98. exonware/xwnode/nodes/strategies/{node_persistent_tree.py → persistent_tree.py} +149 -9
  99. exonware/xwnode/nodes/strategies/priority_queue.py +544 -132
  100. exonware/xwnode/nodes/strategies/queue.py +249 -120
  101. exonware/xwnode/nodes/strategies/{node_red_black_tree.py → red_black_tree.py} +183 -72
  102. exonware/xwnode/nodes/strategies/{node_roaring_bitmap.py → roaring_bitmap.py} +19 -6
  103. exonware/xwnode/nodes/strategies/rope.py +717 -0
  104. exonware/xwnode/nodes/strategies/{node_segment_tree.py → segment_tree.py} +106 -106
  105. exonware/xwnode/nodes/strategies/{node_set_hash.py → set_hash.py} +30 -29
  106. exonware/xwnode/nodes/strategies/{node_skip_list.py → skip_list.py} +74 -6
  107. exonware/xwnode/nodes/strategies/sparse_matrix.py +427 -131
  108. exonware/xwnode/nodes/strategies/{node_splay_tree.py → splay_tree.py} +55 -6
  109. exonware/xwnode/nodes/strategies/stack.py +244 -112
  110. exonware/xwnode/nodes/strategies/{node_suffix_array.py → suffix_array.py} +5 -1
  111. exonware/xwnode/nodes/strategies/t_tree.py +94 -0
  112. exonware/xwnode/nodes/strategies/{node_treap.py → treap.py} +75 -6
  113. exonware/xwnode/nodes/strategies/{node_tree_graph_hybrid.py → tree_graph_hybrid.py} +46 -5
  114. exonware/xwnode/nodes/strategies/trie.py +153 -9
  115. exonware/xwnode/nodes/strategies/union_find.py +111 -5
  116. exonware/xwnode/nodes/strategies/veb_tree.py +856 -0
  117. exonware/xwnode/strategies/__init__.py +5 -51
  118. exonware/xwnode/version.py +3 -3
  119. {exonware_xwnode-0.0.1.22.dist-info → exonware_xwnode-0.0.1.23.dist-info}/METADATA +23 -3
  120. exonware_xwnode-0.0.1.23.dist-info/RECORD +130 -0
  121. exonware/xwnode/edges/strategies/edge_adj_list.py +0 -353
  122. exonware/xwnode/edges/strategies/edge_adj_matrix.py +0 -445
  123. exonware/xwnode/nodes/strategies/_base_node.py +0 -307
  124. exonware/xwnode/nodes/strategies/node_aho_corasick.py +0 -525
  125. exonware/xwnode/nodes/strategies/node_array_list.py +0 -179
  126. exonware/xwnode/nodes/strategies/node_hash_map.py +0 -273
  127. exonware/xwnode/nodes/strategies/node_heap.py +0 -196
  128. exonware/xwnode/nodes/strategies/node_linked_list.py +0 -413
  129. exonware/xwnode/nodes/strategies/node_trie.py +0 -257
  130. exonware/xwnode/nodes/strategies/node_union_find.py +0 -192
  131. exonware/xwnode/queries/executors/__init__.py +0 -47
  132. exonware/xwnode/queries/executors/advanced/__init__.py +0 -37
  133. exonware/xwnode/queries/executors/advanced/aggregate_executor.py +0 -50
  134. exonware/xwnode/queries/executors/advanced/ask_executor.py +0 -50
  135. exonware/xwnode/queries/executors/advanced/construct_executor.py +0 -50
  136. exonware/xwnode/queries/executors/advanced/describe_executor.py +0 -50
  137. exonware/xwnode/queries/executors/advanced/for_loop_executor.py +0 -50
  138. exonware/xwnode/queries/executors/advanced/foreach_executor.py +0 -50
  139. exonware/xwnode/queries/executors/advanced/join_executor.py +0 -50
  140. exonware/xwnode/queries/executors/advanced/let_executor.py +0 -50
  141. exonware/xwnode/queries/executors/advanced/mutation_executor.py +0 -50
  142. exonware/xwnode/queries/executors/advanced/options_executor.py +0 -50
  143. exonware/xwnode/queries/executors/advanced/pipe_executor.py +0 -50
  144. exonware/xwnode/queries/executors/advanced/subscribe_executor.py +0 -50
  145. exonware/xwnode/queries/executors/advanced/subscription_executor.py +0 -50
  146. exonware/xwnode/queries/executors/advanced/union_executor.py +0 -50
  147. exonware/xwnode/queries/executors/advanced/window_executor.py +0 -51
  148. exonware/xwnode/queries/executors/advanced/with_cte_executor.py +0 -50
  149. exonware/xwnode/queries/executors/aggregation/__init__.py +0 -21
  150. exonware/xwnode/queries/executors/aggregation/avg_executor.py +0 -50
  151. exonware/xwnode/queries/executors/aggregation/count_executor.py +0 -38
  152. exonware/xwnode/queries/executors/aggregation/distinct_executor.py +0 -50
  153. exonware/xwnode/queries/executors/aggregation/group_executor.py +0 -50
  154. exonware/xwnode/queries/executors/aggregation/having_executor.py +0 -50
  155. exonware/xwnode/queries/executors/aggregation/max_executor.py +0 -50
  156. exonware/xwnode/queries/executors/aggregation/min_executor.py +0 -50
  157. exonware/xwnode/queries/executors/aggregation/sum_executor.py +0 -50
  158. exonware/xwnode/queries/executors/aggregation/summarize_executor.py +0 -50
  159. exonware/xwnode/queries/executors/array/__init__.py +0 -9
  160. exonware/xwnode/queries/executors/array/indexing_executor.py +0 -51
  161. exonware/xwnode/queries/executors/array/slicing_executor.py +0 -51
  162. exonware/xwnode/queries/executors/base.py +0 -257
  163. exonware/xwnode/queries/executors/capability_checker.py +0 -204
  164. exonware/xwnode/queries/executors/contracts.py +0 -166
  165. exonware/xwnode/queries/executors/core/__init__.py +0 -17
  166. exonware/xwnode/queries/executors/core/create_executor.py +0 -96
  167. exonware/xwnode/queries/executors/core/delete_executor.py +0 -99
  168. exonware/xwnode/queries/executors/core/drop_executor.py +0 -100
  169. exonware/xwnode/queries/executors/core/insert_executor.py +0 -39
  170. exonware/xwnode/queries/executors/core/select_executor.py +0 -152
  171. exonware/xwnode/queries/executors/core/update_executor.py +0 -102
  172. exonware/xwnode/queries/executors/data/__init__.py +0 -13
  173. exonware/xwnode/queries/executors/data/alter_executor.py +0 -50
  174. exonware/xwnode/queries/executors/data/load_executor.py +0 -50
  175. exonware/xwnode/queries/executors/data/merge_executor.py +0 -50
  176. exonware/xwnode/queries/executors/data/store_executor.py +0 -50
  177. exonware/xwnode/queries/executors/defs.py +0 -93
  178. exonware/xwnode/queries/executors/engine.py +0 -221
  179. exonware/xwnode/queries/executors/errors.py +0 -68
  180. exonware/xwnode/queries/executors/filtering/__init__.py +0 -25
  181. exonware/xwnode/queries/executors/filtering/between_executor.py +0 -80
  182. exonware/xwnode/queries/executors/filtering/filter_executor.py +0 -79
  183. exonware/xwnode/queries/executors/filtering/has_executor.py +0 -70
  184. exonware/xwnode/queries/executors/filtering/in_executor.py +0 -70
  185. exonware/xwnode/queries/executors/filtering/like_executor.py +0 -76
  186. exonware/xwnode/queries/executors/filtering/optional_executor.py +0 -76
  187. exonware/xwnode/queries/executors/filtering/range_executor.py +0 -80
  188. exonware/xwnode/queries/executors/filtering/term_executor.py +0 -77
  189. exonware/xwnode/queries/executors/filtering/values_executor.py +0 -71
  190. exonware/xwnode/queries/executors/filtering/where_executor.py +0 -44
  191. exonware/xwnode/queries/executors/graph/__init__.py +0 -15
  192. exonware/xwnode/queries/executors/graph/in_traverse_executor.py +0 -51
  193. exonware/xwnode/queries/executors/graph/match_executor.py +0 -51
  194. exonware/xwnode/queries/executors/graph/out_executor.py +0 -51
  195. exonware/xwnode/queries/executors/graph/path_executor.py +0 -51
  196. exonware/xwnode/queries/executors/graph/return_executor.py +0 -51
  197. exonware/xwnode/queries/executors/ordering/__init__.py +0 -9
  198. exonware/xwnode/queries/executors/ordering/by_executor.py +0 -50
  199. exonware/xwnode/queries/executors/ordering/order_executor.py +0 -51
  200. exonware/xwnode/queries/executors/projection/__init__.py +0 -9
  201. exonware/xwnode/queries/executors/projection/extend_executor.py +0 -50
  202. exonware/xwnode/queries/executors/projection/project_executor.py +0 -50
  203. exonware/xwnode/queries/executors/registry.py +0 -173
  204. exonware/xwnode/queries/parsers/__init__.py +0 -26
  205. exonware/xwnode/queries/parsers/base.py +0 -86
  206. exonware/xwnode/queries/parsers/contracts.py +0 -46
  207. exonware/xwnode/queries/parsers/errors.py +0 -53
  208. exonware/xwnode/queries/parsers/sql_param_extractor.py +0 -318
  209. exonware/xwnode/queries/strategies/__init__.py +0 -24
  210. exonware/xwnode/queries/strategies/base.py +0 -236
  211. exonware/xwnode/queries/strategies/cql.py +0 -201
  212. exonware/xwnode/queries/strategies/cypher.py +0 -181
  213. exonware/xwnode/queries/strategies/datalog.py +0 -70
  214. exonware/xwnode/queries/strategies/elastic_dsl.py +0 -70
  215. exonware/xwnode/queries/strategies/eql.py +0 -70
  216. exonware/xwnode/queries/strategies/flux.py +0 -70
  217. exonware/xwnode/queries/strategies/gql.py +0 -70
  218. exonware/xwnode/queries/strategies/graphql.py +0 -240
  219. exonware/xwnode/queries/strategies/gremlin.py +0 -181
  220. exonware/xwnode/queries/strategies/hiveql.py +0 -214
  221. exonware/xwnode/queries/strategies/hql.py +0 -70
  222. exonware/xwnode/queries/strategies/jmespath.py +0 -219
  223. exonware/xwnode/queries/strategies/jq.py +0 -66
  224. exonware/xwnode/queries/strategies/json_query.py +0 -66
  225. exonware/xwnode/queries/strategies/jsoniq.py +0 -248
  226. exonware/xwnode/queries/strategies/kql.py +0 -70
  227. exonware/xwnode/queries/strategies/linq.py +0 -238
  228. exonware/xwnode/queries/strategies/logql.py +0 -70
  229. exonware/xwnode/queries/strategies/mql.py +0 -68
  230. exonware/xwnode/queries/strategies/n1ql.py +0 -210
  231. exonware/xwnode/queries/strategies/partiql.py +0 -70
  232. exonware/xwnode/queries/strategies/pig.py +0 -215
  233. exonware/xwnode/queries/strategies/promql.py +0 -70
  234. exonware/xwnode/queries/strategies/sparql.py +0 -220
  235. exonware/xwnode/queries/strategies/sql.py +0 -275
  236. exonware/xwnode/queries/strategies/xml_query.py +0 -66
  237. exonware/xwnode/queries/strategies/xpath.py +0 -223
  238. exonware/xwnode/queries/strategies/xquery.py +0 -258
  239. exonware/xwnode/queries/strategies/xwnode_executor.py +0 -332
  240. exonware/xwnode/queries/strategies/xwquery.py +0 -456
  241. exonware_xwnode-0.0.1.22.dist-info/RECORD +0 -214
  242. /exonware/xwnode/nodes/strategies/{node_ordered_map.py → ordered_map.py} +0 -0
  243. /exonware/xwnode/nodes/strategies/{node_ordered_map_balanced.py → ordered_map_balanced.py} +0 -0
  244. /exonware/xwnode/nodes/strategies/{node_patricia.py → patricia.py} +0 -0
  245. /exonware/xwnode/nodes/strategies/{node_radix_trie.py → radix_trie.py} +0 -0
  246. /exonware/xwnode/nodes/strategies/{node_set_tree.py → set_tree.py} +0 -0
  247. {exonware_xwnode-0.0.1.22.dist-info → exonware_xwnode-0.0.1.23.dist-info}/WHEEL +0 -0
  248. {exonware_xwnode-0.0.1.22.dist-info → exonware_xwnode-0.0.1.23.dist-info}/licenses/LICENSE +0 -0
@@ -1,307 +0,0 @@
1
- """
2
- Abstract Node Strategy Interface
3
-
4
- This module defines the abstract base class that all node strategies must implement
5
- in the strategy system.
6
- """
7
-
8
- from abc import ABC, abstractmethod
9
- from typing import Any, Dict, List, Optional, Iterator, Union
10
- from ...defs import NodeMode, NodeTrait
11
- from ...errors import XWNodeUnsupportedCapabilityError
12
-
13
-
14
- class aNodeStrategy(ABC):
15
- """
16
- Abstract base class for all node strategies.
17
-
18
- This abstract base class defines the contract that all node strategy
19
- implementations must follow, ensuring consistency and interoperability.
20
- """
21
-
22
- def __init__(self, mode: NodeMode, traits: NodeTrait = NodeTrait.NONE, **options):
23
- """Initialize the abstract node strategy."""
24
- self.mode = mode
25
- self.traits = traits
26
- self.options = options
27
- self._data: Dict[str, Any] = {}
28
- self._size = 0
29
-
30
- # Validate traits compatibility with mode
31
- self._validate_traits()
32
-
33
- def _validate_traits(self) -> None:
34
- """Validate that the requested traits are compatible with this strategy."""
35
- supported_traits = self.get_supported_traits()
36
- unsupported = self.traits & ~supported_traits
37
- if unsupported != NodeTrait.NONE:
38
- unsupported_names = [trait.name for trait in NodeTrait if trait in unsupported]
39
- raise ValueError(f"Strategy {self.mode.name} does not support traits: {unsupported_names}")
40
-
41
- def get_supported_traits(self) -> NodeTrait:
42
- """Get the traits supported by this strategy implementation."""
43
- # Default implementation - subclasses should override
44
- return NodeTrait.NONE
45
-
46
- def has_trait(self, trait: NodeTrait) -> bool:
47
- """Check if this strategy has a specific trait."""
48
- return bool(self.traits & trait)
49
-
50
- def require_trait(self, trait: NodeTrait, operation: str = "operation") -> None:
51
- """Require a specific trait for an operation."""
52
- if not self.has_trait(trait):
53
- from ...errors import UnsupportedCapabilityError
54
- raise UnsupportedCapabilityError(f"{operation} requires {trait.name} capability")
55
-
56
- # ============================================================================
57
- # CORE OPERATIONS (Required)
58
- # ============================================================================
59
-
60
- @abstractmethod
61
- def put(self, key: Any, value: Any = None) -> None:
62
- """
63
- Store a key-value pair.
64
-
65
- Args:
66
- key: The key to store
67
- value: The value to associate with the key
68
- """
69
- pass
70
-
71
- @abstractmethod
72
- def get(self, key: Any, default: Any = None) -> Any:
73
- """
74
- Retrieve a value by key.
75
-
76
- Args:
77
- key: The key to look up
78
- default: Default value if key not found
79
-
80
- Returns:
81
- The value associated with the key, or default if not found
82
- """
83
- pass
84
-
85
- @abstractmethod
86
- def delete(self, key: Any) -> bool:
87
- """
88
- Remove a key-value pair.
89
-
90
- Args:
91
- key: The key to remove
92
-
93
- Returns:
94
- True if key was found and removed, False otherwise
95
- """
96
- pass
97
-
98
- @abstractmethod
99
- def has(self, key: Any) -> bool:
100
- """
101
- Check if a key exists.
102
-
103
- Args:
104
- key: The key to check
105
-
106
- Returns:
107
- True if key exists, False otherwise
108
- """
109
- pass
110
-
111
- @abstractmethod
112
- def __len__(self) -> int:
113
- """Get the number of key-value pairs."""
114
- pass
115
-
116
- @abstractmethod
117
- def keys(self) -> Iterator[Any]:
118
- """Get an iterator over all keys."""
119
- pass
120
-
121
- @abstractmethod
122
- def values(self) -> Iterator[Any]:
123
- """Get an iterator over all values."""
124
- pass
125
-
126
- @abstractmethod
127
- def items(self) -> Iterator[tuple[Any, Any]]:
128
- """Get an iterator over all key-value pairs."""
129
- pass
130
-
131
- # ============================================================================
132
- # CAPABILITY-BASED OPERATIONS (Optional)
133
- # ============================================================================
134
-
135
- def get_ordered(self, start: Any = None, end: Any = None) -> List[tuple[Any, Any]]:
136
- """
137
- Get items in order (requires ORDERED trait).
138
-
139
- Args:
140
- start: Start key (inclusive)
141
- end: End key (exclusive)
142
-
143
- Returns:
144
- List of (key, value) pairs in order
145
-
146
- Raises:
147
- UnsupportedCapabilityError: If ORDERED trait not supported
148
- """
149
- if NodeTrait.ORDERED not in self.traits:
150
- raise XWNodeUnsupportedCapabilityError("ORDERED", self.mode.name, [str(t) for t in self.traits])
151
-
152
- # Default implementation for ordered strategies
153
- items = list(self.items())
154
- if start is not None:
155
- items = [(k, v) for k, v in items if k >= start]
156
- if end is not None:
157
- items = [(k, v) for k, v in items if k < end]
158
- return items
159
-
160
- def get_with_prefix(self, prefix: str) -> List[tuple[Any, Any]]:
161
- """
162
- Get items with given prefix (requires HIERARCHICAL trait).
163
-
164
- Args:
165
- prefix: The prefix to match
166
-
167
- Returns:
168
- List of (key, value) pairs with matching prefix
169
-
170
- Raises:
171
- UnsupportedCapabilityError: If HIERARCHICAL trait not supported
172
- """
173
- if NodeTrait.HIERARCHICAL not in self.traits:
174
- raise XWNodeUnsupportedCapabilityError("HIERARCHICAL", self.mode.name, [str(t) for t in self.traits])
175
-
176
- # Default implementation for hierarchical strategies
177
- return [(k, v) for k, v in self.items() if str(k).startswith(prefix)]
178
-
179
- def get_priority(self) -> Optional[tuple[Any, Any]]:
180
- """
181
- Get highest priority item (requires PRIORITY trait).
182
-
183
- Returns:
184
- (key, value) pair with highest priority, or None if empty
185
-
186
- Raises:
187
- UnsupportedCapabilityError: If PRIORITY trait not supported
188
- """
189
- if NodeTrait.PRIORITY not in self.traits:
190
- raise XWNodeUnsupportedCapabilityError("PRIORITY", self.mode.name, [str(t) for t in self.traits])
191
-
192
- # Default implementation for priority strategies
193
- if not self._data:
194
- return None
195
- return min(self.items(), key=lambda x: x[0])
196
-
197
- def get_weighted(self, key: Any) -> float:
198
- """
199
- Get weight for a key (requires WEIGHTED trait).
200
-
201
- Args:
202
- key: The key to get weight for
203
-
204
- Returns:
205
- Weight value for the key
206
-
207
- Raises:
208
- UnsupportedCapabilityError: If WEIGHTED trait not supported
209
- """
210
- if NodeTrait.WEIGHTED not in self.traits:
211
- raise XWNodeUnsupportedCapabilityError("WEIGHTED", self.mode.name, [str(t) for t in self.traits])
212
-
213
- # Default implementation for weighted strategies
214
- return self._data.get(key, {}).get('weight', 1.0)
215
-
216
- # ============================================================================
217
- # STRATEGY METADATA
218
- # ============================================================================
219
-
220
- def capabilities(self) -> NodeTrait:
221
- """Get the capabilities supported by this strategy."""
222
- return self.traits
223
-
224
- def backend_info(self) -> Dict[str, Any]:
225
- """Get information about the backend implementation."""
226
- return {
227
- "mode": self.mode.name,
228
- "traits": str(self.traits),
229
- "size": len(self),
230
- "options": self.options.copy()
231
- }
232
-
233
- def metrics(self) -> Dict[str, Any]:
234
- """Get performance metrics for this strategy."""
235
- return {
236
- "size": len(self),
237
- "mode": self.mode.name,
238
- "traits": str(self.traits)
239
- }
240
-
241
- # ============================================================================
242
- # FACTORY METHODS
243
- # ============================================================================
244
-
245
- @classmethod
246
- def create_from_data(cls, data: Any) -> 'aNodeStrategy':
247
- """
248
- Create a new strategy instance from data.
249
-
250
- Args:
251
- data: The data to create the strategy from
252
-
253
- Returns:
254
- A new strategy instance containing the data
255
- """
256
- instance = cls()
257
- if isinstance(data, dict):
258
- for key, value in data.items():
259
- instance.put(key, value)
260
- elif isinstance(data, (list, tuple)):
261
- for i, value in enumerate(data):
262
- instance.put(i, value)
263
- else:
264
- # For primitive values, store as root value
265
- instance.put('_value', data)
266
- return instance
267
-
268
- # ============================================================================
269
- # UTILITY METHODS
270
- # ============================================================================
271
-
272
- def clear(self) -> None:
273
- """Clear all data."""
274
- self._data.clear()
275
- self._size = 0
276
-
277
- def __contains__(self, key: Any) -> bool:
278
- """Check if key exists."""
279
- return self.has(key)
280
-
281
- def __getitem__(self, key: Any) -> Any:
282
- """Get value by key."""
283
- return self.get(key)
284
-
285
- def __setitem__(self, key: Any, value: Any) -> None:
286
- """Set value by key."""
287
- self.put(key, value)
288
-
289
- def __delitem__(self, key: Any) -> None:
290
- """Delete key."""
291
- if not self.delete(key):
292
- raise KeyError(key)
293
-
294
- def __iter__(self) -> Iterator[Any]:
295
- """Iterate over keys."""
296
- return self.keys()
297
-
298
- def __str__(self) -> str:
299
- """String representation."""
300
- return f"{self.__class__.__name__}(mode={self.mode.name}, size={len(self)})"
301
-
302
- def __repr__(self) -> str:
303
- """Detailed string representation."""
304
- return f"{self.__class__.__name__}(mode={self.mode.name}, traits={self.traits}, size={len(self)})"
305
-
306
-
307
-