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
@@ -41,15 +41,76 @@ class TreapNode:
41
41
 
42
42
  class TreapStrategy(ANodeTreeStrategy):
43
43
  """
44
- Treap node strategy for randomized balanced trees.
45
-
46
- Combines binary search tree and heap properties with randomized
47
- priorities for
44
+ Treap strategy for randomized balanced binary search trees.
45
+
46
+ WHY Treap (Tree + Heap):
47
+ - Simpler than AVL/Red-Black (only rotations, no complex rules)
48
+ - Probabilistic O(log n) expected height (randomized balancing)
49
+ - Combines BST property (keys) with max-heap property (priorities)
50
+ - No explicit height/color tracking needed (priorities handle balancing)
51
+ - Excellent for dynamic scenarios (frequent insert/delete)
52
+
53
+ WHY this implementation:
54
+ - Random priorities assigned at insertion (1 to 1,000,000 range)
55
+ - BST property maintained by keys (sorted order)
56
+ - Max-heap property maintained by priorities (parent > children)
57
+ - Rotations restore heap property after insertions/deletions
58
+ - Parent-free implementation (simpler, less memory)
59
+
60
+ Time Complexity:
61
+ - Insert: O(log n) expected, O(n) worst case (probabilistic)
62
+ - Search: O(log n) expected, O(n) worst case (probabilistic)
63
+ - Delete: O(log n) expected, O(n) worst case (probabilistic)
64
+ - Min/Max: O(log n) - leftmost/rightmost traversal
65
+ - Iteration: O(n) in sorted order (BST property)
66
+
67
+ Space Complexity: O(n) - one node per key + priority integer
68
+
69
+ Trade-offs:
70
+ - Advantage: Simpler than AVL/Red-Black (no complex rebalancing rules)
71
+ - Advantage: Good performance in practice (expected O(log n))
72
+ - Limitation: Probabilistic (no worst-case guarantees like AVL/RB)
73
+ - Limitation: Randomness may complicate debugging/testing
74
+ - Compared to Skip List: More memory efficient, but rotations overhead
75
+ - Compared to AVL: Simpler, but probabilistic vs deterministic
76
+
77
+ Best for:
78
+ - When simplicity is valued over worst-case guarantees
79
+ - Dynamic scenarios with frequent insert/delete
80
+ - When deterministic balancing is not required
81
+ - Educational purposes (elegant combination of BST + heap)
82
+ - Randomized algorithms and Monte Carlo simulations
83
+
84
+ Not recommended for:
85
+ - Hard real-time systems (probabilistic behavior)
86
+ - When worst-case guarantees are critical (use AVL/Red-Black)
87
+ - Adversarial inputs (can be exploited with known priorities)
88
+ - Deterministic testing environments (randomness complicates tests)
89
+ - Production systems requiring predictable performance
90
+
91
+ Following eXonware Priorities:
92
+ 1. Usability: Simplest self-balancing tree (no complex rules)
93
+ 2. Maintainability: Clean randomized design, easy to understand
94
+ 3. Performance: Expected O(log n) with low constant factors
95
+ 4. Extensibility: Can support split/merge operations efficiently
96
+ 5. Security: Input validation, random priorities prevent some attacks
97
+
98
+ Industry Best Practices:
99
+ - Follows Seidel and Aragon original paper (1989)
100
+ - Maintains BST invariant: left < node < right (keys)
101
+ - Maintains max-heap invariant: parent.priority > child.priority
102
+ - Uses rotations to restore heap property after modifications
103
+ - Provides split/merge operations for advanced use cases
104
+
105
+ Performance Note:
106
+ Treaps offer EXPECTED O(log n) performance, not worst-case.
107
+ The randomized priorities ensure good balance with high probability.
108
+ For guaranteed O(log n), use AVL_TREE or RED_BLACK_TREE instead.
109
+ Trade-off: Simplicity (Treap) vs Determinism (AVL/Red-Black).
110
+ """
48
111
 
49
112
  # Strategy type classification
50
113
  STRATEGY_TYPE = NodeType.TREE
51
- self-balancing behavior.
52
- """
53
114
 
54
115
  def __init__(self, traits: NodeTrait = NodeTrait.NONE, **options):
55
116
  """Initialize the treap strategy."""
@@ -267,6 +328,14 @@ self-balancing behavior.
267
328
  """Get number of key-value pairs."""
268
329
  return self._size
269
330
 
331
+ def __len__(self) -> int:
332
+ """Get number of key-value pairs."""
333
+ return self._size
334
+
335
+ def to_native(self) -> Dict[str, Any]:
336
+ """Convert to native Python dict."""
337
+ return dict(self.items())
338
+
270
339
  def is_empty(self) -> bool:
271
340
  """Check if tree is empty."""
272
341
  return self._root is None
@@ -1,5 +1,5 @@
1
1
  """
2
- #exonware/xwnode/src/exonware/xwnode/strategies/nodes/node_tree_graph_hybrid.py
2
+ #exonware/xwnode/src/exonware/xwnode/nodes/strategies/tree_graph_hybrid.py
3
3
 
4
4
  Tree Graph Hybrid Strategy Implementation
5
5
 
@@ -15,14 +15,17 @@ from typing import Any, Union, List, Dict, Optional, Iterator, Tuple, Callable
15
15
  from collections import OrderedDict
16
16
 
17
17
  from ...defs import NodeMode, NodeTrait
18
- from ...abc import iNodeStrategy, NodeTrait
19
- from ...errors import xNodePathError
18
+ from ...contracts import iNodeStrategy
19
+ from ...errors import XWNodePathError
20
20
  from exonware.xwsystem import get_logger
21
21
 
22
22
  logger = get_logger(__name__)
23
23
 
24
+ # Import contracts
25
+ from .contracts import NodeType
26
+
24
27
  # Import shared utilities
25
- from ..utils import (
28
+ from ...common.utils import (
26
29
  PathParser, TrieNode, UnionFind, MinHeap,
27
30
  create_path_parser, create_performance_tracker
28
31
  )
@@ -533,10 +536,12 @@ class TreeGraphHybridStrategy(iNodeStrategy):
533
536
  STRATEGY_TYPE = NodeType.HYBRID
534
537
 
535
538
 
536
- def __init__(self):
539
+ def __init__(self, mode=None, traits=None, **options):
537
540
  """Initialize the TreeGraphHybrid strategy."""
541
+ # Accept standard parameters but don't use them (for compatibility)
538
542
  self._root: Optional[TreeGraphNode] = None
539
543
  self._node_count = 0
544
+ self._options = options
540
545
  self._edge_count = 0
541
546
  self._cache = {}
542
547
  self._size = 0
@@ -581,6 +586,9 @@ class TreeGraphHybridStrategy(iNodeStrategy):
581
586
  def _calculate_size(self, node: TreeGraphNode) -> int:
582
587
  """Calculate the size of the tree."""
583
588
  if isinstance(node, TreeGraphValueNode):
589
+ # Treat None as empty (size 0)
590
+ if node._value is None:
591
+ return 0
584
592
  return 1
585
593
  elif isinstance(node, TreeGraphListNode):
586
594
  # For lists, return the number of items
@@ -1107,6 +1115,39 @@ class TreeGraphHybridStrategy(iNodeStrategy):
1107
1115
  return {}
1108
1116
  return self._root._to_native()
1109
1117
 
1118
+ def size(self) -> int:
1119
+ """Get the size/count of items in the tree."""
1120
+ if self._root is None:
1121
+ return 0
1122
+ # For dict root, return number of top-level keys
1123
+ if isinstance(self._root, TreeGraphDictNode):
1124
+ return len(self._root._keys) if hasattr(self._root, '_keys') else len(self._root._children)
1125
+ # For list root, return list length
1126
+ elif isinstance(self._root, TreeGraphListNode):
1127
+ # Check lazy-loaded source data first, then loaded children
1128
+ if hasattr(self._root, '_source_data') and self._root._source_data is not None:
1129
+ return len(self._root._source_data)
1130
+ return len(self._root._children)
1131
+ # For value node, check if it's None (empty)
1132
+ elif isinstance(self._root, TreeGraphValueNode):
1133
+ if hasattr(self._root, '_value') and self._root._value is None:
1134
+ return 0
1135
+ return 1
1136
+ # Default: return 1
1137
+ else:
1138
+ return 1
1139
+
1140
+ def is_empty(self) -> bool:
1141
+ """Check if the structure is empty."""
1142
+ return self.size() == 0
1143
+
1144
+ def find(self, path: str) -> Optional[Any]:
1145
+ """Find a value by path (facade compatibility)."""
1146
+ result = self.get(path, default=None)
1147
+ if result is not None and hasattr(result, 'to_native'):
1148
+ return result.to_native()
1149
+ return result
1150
+
1110
1151
  def get(self, path: str, default: Any = None) -> Optional['TreeGraphHybridStrategy']:
1111
1152
  """Get a child node by path."""
1112
1153
  if self._root is None:
@@ -19,22 +19,63 @@ class TrieNode:
19
19
  self.value: Any = None
20
20
 
21
21
 
22
- class xTrieStrategy(ANodeTreeStrategy):
22
+ class TrieStrategy(ANodeTreeStrategy):
23
+ """
24
+ Trie (Prefix Tree) strategy for efficient prefix-based string operations.
25
+
26
+ WHY Trie:
27
+ - O(k) operations where k = key length (independent of dataset size)
28
+ - Exceptional prefix matching and autocomplete
29
+ - Natural string organization by shared prefixes
30
+ - Memory-efficient for datasets with common prefixes
31
+
32
+ WHY this implementation:
33
+ - Standard trie algorithm with character-by-character nodes
34
+ - Dictionary-based children for flexible character sets
35
+ - End-of-word markers for distinguishing prefixes from complete words
36
+ - Supports full Unicode character set
37
+
38
+ Time Complexity:
39
+ - Insert: O(k) where k = key length
40
+ - Search: O(k) - traverse k characters
41
+ - Delete: O(k) - traverse and cleanup
42
+ - Prefix search: O(k + m) where m = matching words
43
+ - Autocomplete: O(k + m) where m = suggestions
44
+
45
+ Space Complexity: O(ALPHABET_SIZE * N * K) worst case, often much better
46
+
47
+ Trade-offs:
48
+ - Advantage: Time independent of dataset size
49
+ - Advantage: Natural prefix operations
50
+ - Advantage: Memory sharing for common prefixes
51
+ - Limitation: Higher memory than hash for unique keys
52
+ - Compared to Hash Map: Slower exact match, better for prefixes
53
+
54
+ Best for:
55
+ - Autocomplete systems
56
+ - Dictionary/spell check
57
+ - IP routing tables
58
+ - String prefix matching
59
+
60
+ Not recommended for:
61
+ - Non-string keys (use HASH_MAP)
62
+ - Exact match only (use HASH_MAP)
63
+ - Numeric keys (use B_TREE)
64
+
65
+ Following eXonware Priorities:
66
+ 1. Security: Bounded by key length
67
+ 2. Usability: Intuitive for string operations
68
+ 3. Maintainability: Well-known algorithm
69
+ 4. Performance: O(k) guaranteed
70
+ 5. Extensibility: Can add compression (Radix)
23
71
  """
24
- Trie node strategy for efficient string prefix operations.
25
-
26
- Optimized for prefix matching, autocomplet
27
72
 
28
73
  # Strategy type classification
29
74
  STRATEGY_TYPE = NodeType.TREE
30
- e, and string searching.
31
- """
32
75
 
33
76
  def __init__(self, traits: NodeTrait = NodeTrait.NONE, **options):
34
77
  """Initialize the trie strategy."""
35
- super().__init__(data=None, **options)
36
- self._mode = NodeMode.TRIE
37
- self._traits = traits
78
+ super().__init__(NodeMode.TRIE, traits, **options)
38
79
  self._root = TrieNode()
39
80
  self._size = 0
40
81
 
@@ -277,3 +318,106 @@ e, and string searching.
277
318
  if not node.children:
278
319
  return 0
279
320
  return 1 + max(self._height_helper(child) for child in node.children.values())
321
+
322
+ # ============================================================================
323
+ # REQUIRED INTERFACE METHODS (iNodeStrategy)
324
+ # ============================================================================
325
+
326
+ def create_from_data(self, data: Any) -> 'TrieStrategy':
327
+ """Create strategy instance from data."""
328
+ new_strategy = TrieStrategy(self._traits)
329
+ if isinstance(data, dict):
330
+ for key, value in data.items():
331
+ new_strategy.insert(key, value)
332
+ elif isinstance(data, list):
333
+ for item in data:
334
+ new_strategy.insert(item, item)
335
+ return new_strategy
336
+
337
+ def get(self, path: str, default: Any = None) -> Any:
338
+ """Get value by path (trie uses find)."""
339
+ result = self.find(path)
340
+ return result if result is not None else default
341
+
342
+ def has(self, key: Any) -> bool:
343
+ """Check if key exists."""
344
+ return self.find(str(key)) is not None
345
+
346
+ def put(self, path: str, value: Any) -> 'TrieStrategy':
347
+ """Put value at path."""
348
+ self.insert(path, value)
349
+ return self
350
+
351
+ def exists(self, path: str) -> bool:
352
+ """Check if path exists."""
353
+ return self.find(path) is not None
354
+
355
+ # Container protocol
356
+ def __len__(self) -> int:
357
+ """Get length."""
358
+ return self._size
359
+
360
+ def __iter__(self) -> Iterator[Any]:
361
+ """Iterate over values."""
362
+ return self.values()
363
+
364
+ def __getitem__(self, key: Any) -> Any:
365
+ """Get item by key."""
366
+ result = self.find(key)
367
+ if result is None:
368
+ raise KeyError(str(key))
369
+ return result
370
+
371
+ def __setitem__(self, key: Any, value: Any) -> None:
372
+ """Set item by key."""
373
+ self.insert(key, value)
374
+
375
+ def __contains__(self, key: Any) -> bool:
376
+ """Check if key exists."""
377
+ return self.find(key) is not None
378
+
379
+ # Type checking properties
380
+ @property
381
+ def is_leaf(self) -> bool:
382
+ """Check if this is a leaf node."""
383
+ return self._size == 0
384
+
385
+ @property
386
+ def is_list(self) -> bool:
387
+ """Check if this is a list node."""
388
+ return False
389
+
390
+ @property
391
+ def is_dict(self) -> bool:
392
+ """Check if this is a dict node."""
393
+ return True # Trie is dict-like (maps strings to values)
394
+
395
+ @property
396
+ def is_reference(self) -> bool:
397
+ """Check if this is a reference node."""
398
+ return False
399
+
400
+ @property
401
+ def is_object(self) -> bool:
402
+ """Check if this is an object node."""
403
+ return False
404
+
405
+ @property
406
+ def type(self) -> str:
407
+ """Get the type of this node."""
408
+ return "trie"
409
+
410
+ @property
411
+ def value(self) -> Any:
412
+ """Get the value of this node."""
413
+ return self.to_native()
414
+
415
+ @property
416
+ def strategy_name(self) -> str:
417
+ """Get strategy name."""
418
+ return "TRIE"
419
+
420
+ @property
421
+ def supported_traits(self) -> NodeTrait:
422
+ """Get supported traits."""
423
+ return self.get_supported_traits()
@@ -77,7 +77,7 @@ class UnionFind:
77
77
  return len(self.get_set_members(x))
78
78
 
79
79
 
80
- class xUnionFindStrategy(ANodeGraphStrategy):
80
+ class UnionFindStrategy(ANodeGraphStrategy):
81
81
  """
82
82
  Union-Find node strategy for efficient set operations.
83
83
 
@@ -90,15 +90,13 @@ ations on disjoint sets.
90
90
 
91
91
  def __init__(self, traits: NodeTrait = NodeTrait.NONE, **options):
92
92
  """Initialize the union-find strategy."""
93
- super().__init__(data=None, **options)
94
- self._mode = NodeMode.UNION_FIND
95
- self._traits = traits
93
+ super().__init__(NodeMode.UNION_FIND, traits, **options)
96
94
  self._union_find = UnionFind()
97
95
  self._size = 0
98
96
 
99
97
  def get_supported_traits(self) -> NodeTrait:
100
98
  """Get the traits supported by the union-find strategy."""
101
- return (NodeTrait.SET_OPERATIONS | NodeTrait.HIERARCHICAL)
99
+ return (NodeTrait.GRAPH | NodeTrait.HIERARCHICAL | NodeTrait.UNION_FIND)
102
100
 
103
101
  # ============================================================================
104
102
  # CORE OPERATIONS
@@ -122,6 +120,11 @@ ations on disjoint sets.
122
120
  # Union-Find doesn't support deletion efficiently
123
121
  return False
124
122
 
123
+ def clear(self) -> None:
124
+ """Clear all data."""
125
+ self._union_find = UnionFind()
126
+ self._size = 0
127
+
125
128
  def size(self) -> int:
126
129
  """Get the number of elements."""
127
130
  return self._size
@@ -286,3 +289,106 @@ ations on disjoint sets.
286
289
  'sets': self._union_find.get_set_count(),
287
290
  'memory_usage': f"{self._size * 32} bytes (estimated)"
288
291
  }
292
+
293
+ # ============================================================================
294
+ # REQUIRED INTERFACE METHODS (iNodeStrategy)
295
+ # ============================================================================
296
+
297
+ def create_from_data(self, data: Any) -> 'UnionFindStrategy':
298
+ """Create strategy instance from data."""
299
+ new_strategy = UnionFindStrategy(self._traits)
300
+ if isinstance(data, dict):
301
+ for key, value in data.items():
302
+ new_strategy.insert(key, value)
303
+ elif isinstance(data, list):
304
+ for item in data:
305
+ new_strategy.insert(item, item)
306
+ return new_strategy
307
+
308
+ def get(self, path: str, default: Any = None) -> Any:
309
+ """Get value by path."""
310
+ result = self.find(path)
311
+ return result if result is not None else default
312
+
313
+ def has(self, key: Any) -> bool:
314
+ """Check if key exists."""
315
+ return str(key) in self._parent
316
+
317
+ def put(self, path: str, value: Any) -> 'UnionFindStrategy':
318
+ """Put value at path."""
319
+ self.insert(path, value)
320
+ return self
321
+
322
+ def exists(self, path: str) -> bool:
323
+ """Check if path exists."""
324
+ return path in self._union_find.parent
325
+
326
+ # Container protocol
327
+ def __len__(self) -> int:
328
+ """Get length."""
329
+ return self._size
330
+
331
+ def __iter__(self) -> Iterator[Any]:
332
+ """Iterate over elements."""
333
+ return self.keys()
334
+
335
+ def __getitem__(self, key: Any) -> Any:
336
+ """Get item by key."""
337
+ result = self.find(key)
338
+ if result is None:
339
+ raise KeyError(str(key))
340
+ return result
341
+
342
+ def __setitem__(self, key: Any, value: Any) -> None:
343
+ """Set item by key."""
344
+ self.insert(key, value)
345
+
346
+ def __contains__(self, key: Any) -> bool:
347
+ """Check if key exists."""
348
+ return str(key) in self._union_find.parent
349
+
350
+ # Type checking properties
351
+ @property
352
+ def is_leaf(self) -> bool:
353
+ """Check if this is a leaf node."""
354
+ return self._size == 0
355
+
356
+ @property
357
+ def is_list(self) -> bool:
358
+ """Check if this is a list node."""
359
+ return False
360
+
361
+ @property
362
+ def is_dict(self) -> bool:
363
+ """Check if this is a dict node."""
364
+ return True # Union-find is dict-like (maps elements to sets)
365
+
366
+ @property
367
+ def is_reference(self) -> bool:
368
+ """Check if this is a reference node."""
369
+ return False
370
+
371
+ @property
372
+ def is_object(self) -> bool:
373
+ """Check if this is an object node."""
374
+ return False
375
+
376
+ @property
377
+ def type(self) -> str:
378
+ """Get the type of this node."""
379
+ return "union_find"
380
+
381
+ @property
382
+ def value(self) -> Any:
383
+ """Get the value of this node."""
384
+ return self.to_native()
385
+
386
+ @property
387
+ def strategy_name(self) -> str:
388
+ """Get strategy name."""
389
+ return "UNION_FIND"
390
+
391
+ @property
392
+ def supported_traits(self) -> NodeTrait:
393
+ """Get supported traits."""
394
+ return self.get_supported_traits()