exonware-xwnode 0.0.1.22__py3-none-any.whl → 0.0.1.24__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 (249) 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.24.dist-info/METADATA +900 -0
  120. exonware_xwnode-0.0.1.24.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/METADATA +0 -168
  242. exonware_xwnode-0.0.1.22.dist-info/RECORD +0 -214
  243. /exonware/xwnode/nodes/strategies/{node_ordered_map.py → ordered_map.py} +0 -0
  244. /exonware/xwnode/nodes/strategies/{node_ordered_map_balanced.py → ordered_map_balanced.py} +0 -0
  245. /exonware/xwnode/nodes/strategies/{node_patricia.py → patricia.py} +0 -0
  246. /exonware/xwnode/nodes/strategies/{node_radix_trie.py → radix_trie.py} +0 -0
  247. /exonware/xwnode/nodes/strategies/{node_set_tree.py → set_tree.py} +0 -0
  248. {exonware_xwnode-0.0.1.22.dist-info → exonware_xwnode-0.0.1.24.dist-info}/WHEEL +0 -0
  249. {exonware_xwnode-0.0.1.22.dist-info → exonware_xwnode-0.0.1.24.dist-info}/licenses/LICENSE +0 -0
@@ -40,15 +40,78 @@ class AVLTreeNode:
40
40
 
41
41
  class AVLTreeStrategy(ANodeTreeStrategy):
42
42
  """
43
- AVL tree node strategy for strictly balanced binary search trees.
44
-
45
- Provides guaranteed O(log n) height and operations through height-based
46
- balanc
43
+ AVL Tree strategy for strictly balanced binary search trees.
44
+
45
+ WHY AVL Tree:
46
+ - Strictest height guarantee: height ≤ 1.44 * log₂(n)
47
+ - Fastest searches among all balanced trees
48
+ - Guaranteed O(log n) worst-case for all operations
49
+ - Height-based balancing (simpler than weight-based)
50
+ - Maintains sorted order with optimal search performance
51
+
52
+ WHY this implementation:
53
+ - Height-based balance factor (simpler than red-black color rules)
54
+ - Balance factor ∈ {-1, 0, 1} maintained after every operation
55
+ - Four rotation types (LL, LR, RR, RL) handle all imbalances
56
+ - Height stored in each node for O(1) balance computation
57
+ - Parent-free implementation (simpler, less memory overhead)
58
+
59
+ Time Complexity:
60
+ - Insert: O(log n) guaranteed (at most 2 rotations, O(log n) retracing)
61
+ - Search: O(log n) guaranteed (strictly balanced tree)
62
+ - Delete: O(log n) guaranteed (at most log n rotations)
63
+ - Min/Max: O(log n) - leftmost/rightmost traversal
64
+ - Iteration: O(n) in sorted order
65
+
66
+ Space Complexity: O(n) - one node per key + height field
67
+
68
+ Trade-offs:
69
+ - Advantage: Fastest searches (stricter height balance than RB-tree)
70
+ - Advantage: Simpler than Red-Black (only heights, no colors)
71
+ - Limitation: More rotations on insert/delete than Red-Black Tree
72
+ - Limitation: Delete can trigger O(log n) rotations (RB-tree has O(1))
73
+ - Compared to Red-Black: Better searches, slower writes
74
+ - Compared to Skip List: Deterministic (no randomness), but more complex
75
+
76
+ Best for:
77
+ - Read-heavy workloads (95%+ reads)
78
+ - When search performance is critical
79
+ - Sorted data structures requiring fast lookups
80
+ - Databases and indices optimized for queries
81
+ - When strict height guarantees are needed
82
+
83
+ Not recommended for:
84
+ - Write-heavy workloads (Red-Black Tree is better)
85
+ - Disk-based storage (B-Tree is better)
86
+ - Simple, unsorted data (Hash Map is faster)
87
+ - When insert/delete performance matters more than search
88
+ - Memory-constrained environments (height overhead)
89
+
90
+ Following eXonware Priorities:
91
+ 1. Usability: Strictest balancing ensures predictable O(log n) performance
92
+ 2. Maintainability: Height-based balancing is easier to understand than colors
93
+ 3. Performance: Optimal search performance among all balanced trees
94
+ 4. Extensibility: Can be enhanced with augmentation (order statistics, intervals)
95
+ 5. Security: Input validation, bounded height prevents worst-case attacks
96
+
97
+ Industry Best Practices:
98
+ - Follows Adelson-Velsky and Landis original paper (1962)
99
+ - Maintains balance factor invariant: |bf| ≤ 1
100
+ - Uses four rotation types: LL (single right), RR (single left),
101
+ LR (left-right double), RL (right-left double)
102
+ - Height updated after every structural change
103
+ - Tracks performance statistics
104
+
105
+ Performance Note:
106
+ AVL Trees provide the STRICTEST height guarantee (≤ 1.44 * log₂(n))
107
+ among all balanced binary search trees. This makes them ideal for
108
+ read-heavy workloads where search performance is paramount.
109
+ For write-heavy workloads, Red-Black Trees are preferred due to
110
+ fewer rotations (at most 2 for insert vs O(log n) for AVL delete).
111
+ """
47
112
 
48
113
  # Strategy type classification
49
114
  STRATEGY_TYPE = NodeType.TREE
50
- ing rules and rotations.
51
- """
52
115
 
53
116
  def __init__(self, traits: NodeTrait = NodeTrait.NONE, **options):
54
117
  """Initialize the AVL tree strategy."""
@@ -291,6 +354,14 @@ ing rules and rotations.
291
354
  """Get number of key-value pairs."""
292
355
  return self._size
293
356
 
357
+ def __len__(self) -> int:
358
+ """Get number of key-value pairs."""
359
+ return self._size
360
+
361
+ def to_native(self) -> Dict[str, Any]:
362
+ """Convert to native Python dict."""
363
+ return dict(self.items())
364
+
294
365
  def is_empty(self) -> bool:
295
366
  """Check if tree is empty."""
296
367
  return self._root is None
@@ -42,15 +42,70 @@ class BPlusTreeNode:
42
42
 
43
43
  class BPlusTreeStrategy(ANodeTreeStrategy):
44
44
  """
45
- B+ Tree node strategy for database-friendly operations.
46
-
47
- Provides efficient range queries, sequential access, and balanced
48
- tree operations optimized for dis
45
+ B+ Tree strategy for database-friendly operations and range queries.
46
+
47
+ WHY B+ Tree:
48
+ - All data stored in leaves (efficient sequential scans)
49
+ - Leaf nodes linked for O(k) range queries after O(log n) seek
50
+ - Higher fanout than B-Tree (more keys per internal node)
51
+ - Optimal for disk-based databases (fewer disk reads)
52
+
53
+ WHY this implementation:
54
+ - Maintains linked list of leaves for fast range scans
55
+ - Internal nodes store only keys (no values)
56
+ - All values at leaf level for consistent access
57
+ - Standard B+ Tree algorithm used in most databases
58
+
59
+ Time Complexity:
60
+ - Insert: O(log n) - Tree traversal to leaf
61
+ - Search: O(log n) - Guaranteed by tree height
62
+ - Delete: O(log n) - May require merging
63
+ - Range query: O(log n + k) where k = results (B+ Tree strength)
64
+ - Sequential scan: O(n) via linked leaves (very fast)
65
+
66
+ Space Complexity: O(n)
67
+
68
+ WHY O(log n) and not O(1):
69
+ - Sorted order maintenance requires tree traversal
70
+ - Balanced structure is essential for consistency
71
+ - Trade-off enables extremely fast range queries
72
+
73
+ Trade-offs:
74
+ - Advantage: Exceptional range query performance
75
+ - Advantage: Sequential access via linked leaves
76
+ - Advantage: Higher fanout = shorter tree
77
+ - Limitation: O(log n) for single-key operations
78
+ - Compared to B-Tree: Better for range scans, similar point queries
79
+ - Compared to Hash Map: Slower lookups, but supports ranges
80
+
81
+ Best for:
82
+ - Database indexes (PostgreSQL, MySQL use B+ Trees)
83
+ - File system indexes
84
+ - Range queries and interval lookups
85
+ - Sequential scans of large datasets
86
+ - Disk-based storage systems
87
+
88
+ Not recommended for:
89
+ - Random single-key lookups only (use HASH_MAP)
90
+ - Small datasets (< 100 items)
91
+ - Write-heavy workloads (use LSM_TREE)
92
+ - In-memory with no range queries (use HASH_MAP)
93
+
94
+ Following eXonware Priorities:
95
+ 1. Security: Predictable O(log n) performance
96
+ 2. Usability: Sorted iteration, range queries
97
+ 3. Maintainability: Well-known database algorithm
98
+ 4. Performance: Optimal for range queries and scans
99
+ 5. Extensibility: Can add bulk loading, concurrent access
100
+
101
+ Performance Note:
102
+ B+ Tree O(log n) is CORRECT and NECESSARY for sorted order.
103
+ The algorithm's strength is range queries, not point lookups.
104
+ For O(1) operations, use HASH_MAP.
105
+ """
49
106
 
50
107
  # Strategy type classification
51
108
  STRATEGY_TYPE = NodeType.TREE
52
- k-based storage systems.
53
- """
54
109
 
55
110
  def __init__(self, traits: NodeTrait = NodeTrait.NONE, **options):
56
111
  """Initialize the B+ Tree strategy."""
@@ -97,7 +152,17 @@ k-based storage systems.
97
152
 
98
153
  current = self._root
99
154
  while not current.is_leaf:
100
- child_index = current.find_child_index(key)
155
+ child_index = 0
156
+ # Find correct child to traverse
157
+ for i, k in enumerate(current.keys):
158
+ if key < k:
159
+ break
160
+ child_index = i + 1
161
+
162
+ # Bounds check
163
+ if child_index >= len(current.children):
164
+ child_index = len(current.children) - 1
165
+
101
166
  current = current.children[child_index]
102
167
 
103
168
  return current
@@ -230,50 +295,26 @@ k-based storage systems.
230
295
  # CORE OPERATIONS
231
296
  # ============================================================================
232
297
 
298
+ def find(self, key: Any) -> Optional[Any]:
299
+ """Find value by key (implements base class abstract method)."""
300
+ key_str = str(key)
301
+ return self._search_key(key_str)
302
+
233
303
  def put(self, key: Any, value: Any = None) -> None:
234
304
  """Add key-value pair to B+ tree."""
235
305
  key_str = str(key)
236
- normalized_key = self._normalize_key(key_str)
237
- self._insert_key(normalized_key, value)
306
+ # Store original key, not normalized (for case-sensitive mode)
307
+ self._insert_key(key_str, value)
238
308
 
239
309
  def get(self, key: Any, default: Any = None) -> Any:
240
310
  """Get value by key."""
241
311
  key_str = str(key)
242
-
243
- if key_str == "tree_info":
244
- return {
245
- 'size': self._size,
246
- 'height': self._height,
247
- 'total_nodes': self._total_nodes,
248
- 'order': self.order,
249
- 'case_sensitive': self.case_sensitive,
250
- 'total_splits': self._total_splits
251
- }
252
- elif key_str == "first_key":
253
- return self.first_key()
254
- elif key_str == "last_key":
255
- return self.last_key()
256
- elif key_str.isdigit():
257
- # Access by index
258
- index = int(key_str)
259
- return self.get_at_index(index)
260
-
261
- normalized_key = self._normalize_key(key_str)
262
- result = self._search_key(normalized_key)
312
+ result = self.find(key_str)
263
313
  return result if result is not None else default
264
314
 
265
315
  def has(self, key: Any) -> bool:
266
316
  """Check if key exists."""
267
- key_str = str(key)
268
-
269
- if key_str in ["tree_info", "first_key", "last_key"]:
270
- return True
271
- elif key_str.isdigit():
272
- index = int(key_str)
273
- return 0 <= index < self._size
274
-
275
- normalized_key = self._normalize_key(key_str)
276
- return self._search_key(normalized_key) is not None
317
+ return self.find(str(key)) is not None
277
318
 
278
319
  def remove(self, key: Any) -> bool:
279
320
  """Remove key from tree (simplified implementation)."""
@@ -71,10 +71,18 @@ class BTreeNode:
71
71
  full_child = self.children[i]
72
72
  new_child = BTreeNode(full_child.degree, full_child.is_leaf)
73
73
 
74
- # Move half of the keys/values to new child
74
+ # Calculate middle index
75
75
  mid = self.degree - 1
76
+
77
+ # Store middle key and value to promote
78
+ mid_key = full_child.keys[mid]
79
+ mid_value = full_child.values[mid]
80
+
81
+ # Move right half to new child (excluding middle)
76
82
  new_child.keys = full_child.keys[mid + 1:]
77
83
  new_child.values = full_child.values[mid + 1:]
84
+
85
+ # Keep left half in full_child (excluding middle)
78
86
  full_child.keys = full_child.keys[:mid]
79
87
  full_child.values = full_child.values[:mid]
80
88
 
@@ -85,21 +93,77 @@ class BTreeNode:
85
93
 
86
94
  # Insert new child and promote middle key
87
95
  self.children.insert(i + 1, new_child)
88
- self.keys.insert(i, full_child.keys[mid])
89
- self.values.insert(i, full_child.values[mid])
96
+ self.keys.insert(i, mid_key)
97
+ self.values.insert(i, mid_value)
90
98
 
91
99
 
92
100
  class BTreeStrategy(ANodeTreeStrategy):
93
101
  """
94
- B-Tree node strategy for efficient sorted operations and range queries.
95
-
96
- Provides O(log n) search, insert, and delete operations with excellent
97
- cache perfor
102
+ B-Tree strategy for efficient sorted operations and range queries.
103
+
104
+ WHY B-Tree:
105
+ - Self-balancing ensures consistent O(log n) performance
106
+ - High branching factor reduces tree height (better than binary trees)
107
+ - Minimizes disk I/O by grouping keys in pages/blocks
108
+ - Excellent for range queries and sequential scans
109
+
110
+ WHY this implementation:
111
+ - Uses standard B-Tree algorithm (Knuth, TAOCP Vol 3)
112
+ - Proactive node splitting (split-on-insert strategy)
113
+ - Maintains 2t-1 max keys per node (t = degree)
114
+ - Keeps all leaves at same depth (perfect balance)
115
+
116
+ Time Complexity:
117
+ - Insert: O(log n) - REQUIRED for maintaining sorted order
118
+ - Search: O(log n) - Tree height determines this
119
+ - Delete: O(log n) - May require merging/borrowing
120
+ - Range query: O(k + log n) where k = results
121
+ - Iteration: O(n) sorted order guaranteed
122
+
123
+ Space Complexity: O(n)
124
+
125
+ WHY O(log n) and not O(1):
126
+ - Maintaining sorted order requires tree traversal
127
+ - Balancing operations are essential to B-Tree correctness
128
+ - This trade-off enables efficient range queries
129
+ - Self-balancing prevents degradation to O(n)
130
+
131
+ Trade-offs:
132
+ - Advantage: Excellent for range queries (k + log n)
133
+ - Advantage: Guaranteed balanced (no worst-case degradation)
134
+ - Limitation: Higher memory per node vs binary trees
135
+ - Limitation: More complex insertion/deletion logic
136
+ - Compared to Hash Map: Slower single lookups, but supports ranges
137
+ - Compared to Binary Tree: Better cache performance, lower height
138
+
139
+ Best for:
140
+ - Database indexes (primary use case)
141
+ - File systems (directory structures)
142
+ - Range queries and sorted iteration
143
+ - Disk-based storage (page-oriented)
144
+ - Large datasets with sorted access
145
+
146
+ Not recommended for:
147
+ - Random single-key lookups only (use HASH_MAP)
148
+ - Small datasets (< 100 items, overhead not worth it)
149
+ - Write-heavy workloads (use LSM_TREE)
150
+ - In-memory only with no range queries (use HASH_MAP)
151
+
152
+ Following eXonware Priorities:
153
+ 1. Security: Predictable performance (no worst-case degradation)
154
+ 2. Usability: Sorted iteration, range queries, familiar tree semantics
155
+ 3. Maintainability: Well-established algorithm, clear split/merge logic
156
+ 4. Performance: O(log n) guaranteed, optimal for disk I/O
157
+ 5. Extensibility: Can add concurrent access, bulk loading
158
+
159
+ Performance Note:
160
+ This is the CORRECT complexity for a B-Tree. The O(log n) overhead
161
+ enables sorted order and range queries. If you need O(1) operations
162
+ without ordering, use HASH_MAP instead.
163
+ """
98
164
 
99
165
  # Strategy type classification
100
166
  STRATEGY_TYPE = NodeType.TREE
101
- mance for range queries.
102
- """
103
167
 
104
168
  def __init__(self, traits: NodeTrait = NodeTrait.NONE, **options):
105
169
  """Initialize the B-tree strategy."""
@@ -241,6 +305,11 @@ mance for range queries.
241
305
  """Get the number of items."""
242
306
  return self._size
243
307
 
308
+ @property
309
+ def is_empty(self) -> bool:
310
+ """Check if B-Tree is empty."""
311
+ return self._size == 0
312
+
244
313
  def to_native(self) -> Dict[str, Any]:
245
314
  """Convert to native Python dict."""
246
315
  return dict(self.items())
@@ -360,3 +429,4 @@ mance for range queries.
360
429
  'memory_usage': f"{self._size * (24 + 16)} bytes (estimated)",
361
430
  'is_sorted': True
362
431
  }
432
+