exonware-xwnode 0.0.1.21__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 (250) hide show
  1. exonware/__init__.py +8 -1
  2. exonware/xwnode/__init__.py +18 -5
  3. exonware/xwnode/add_strategy_types.py +165 -0
  4. exonware/xwnode/base.py +7 -5
  5. exonware/xwnode/common/__init__.py +1 -1
  6. exonware/xwnode/common/graph/__init__.py +30 -0
  7. exonware/xwnode/common/graph/caching.py +131 -0
  8. exonware/xwnode/common/graph/contracts.py +100 -0
  9. exonware/xwnode/common/graph/errors.py +44 -0
  10. exonware/xwnode/common/graph/indexing.py +260 -0
  11. exonware/xwnode/common/graph/manager.py +568 -0
  12. exonware/xwnode/common/management/__init__.py +3 -5
  13. exonware/xwnode/common/management/manager.py +9 -9
  14. exonware/xwnode/common/management/migration.py +6 -6
  15. exonware/xwnode/common/monitoring/__init__.py +3 -5
  16. exonware/xwnode/common/monitoring/metrics.py +7 -3
  17. exonware/xwnode/common/monitoring/pattern_detector.py +2 -2
  18. exonware/xwnode/common/monitoring/performance_monitor.py +6 -2
  19. exonware/xwnode/common/patterns/__init__.py +3 -5
  20. exonware/xwnode/common/patterns/advisor.py +1 -1
  21. exonware/xwnode/common/patterns/flyweight.py +6 -2
  22. exonware/xwnode/common/patterns/registry.py +203 -184
  23. exonware/xwnode/common/utils/__init__.py +25 -11
  24. exonware/xwnode/common/utils/simple.py +1 -1
  25. exonware/xwnode/config.py +3 -8
  26. exonware/xwnode/contracts.py +4 -105
  27. exonware/xwnode/defs.py +413 -159
  28. exonware/xwnode/edges/strategies/__init__.py +86 -4
  29. exonware/xwnode/edges/strategies/_base_edge.py +2 -2
  30. exonware/xwnode/edges/strategies/adj_list.py +287 -121
  31. exonware/xwnode/edges/strategies/adj_matrix.py +316 -222
  32. exonware/xwnode/edges/strategies/base.py +1 -1
  33. exonware/xwnode/edges/strategies/{edge_bidir_wrapper.py → bidir_wrapper.py} +45 -4
  34. exonware/xwnode/edges/strategies/bitemporal.py +520 -0
  35. exonware/xwnode/edges/strategies/{edge_block_adj_matrix.py → block_adj_matrix.py} +77 -6
  36. exonware/xwnode/edges/strategies/bv_graph.py +664 -0
  37. exonware/xwnode/edges/strategies/compressed_graph.py +217 -0
  38. exonware/xwnode/edges/strategies/{edge_coo.py → coo.py} +46 -4
  39. exonware/xwnode/edges/strategies/{edge_csc.py → csc.py} +45 -4
  40. exonware/xwnode/edges/strategies/{edge_csr.py → csr.py} +94 -12
  41. exonware/xwnode/edges/strategies/{edge_dynamic_adj_list.py → dynamic_adj_list.py} +46 -4
  42. exonware/xwnode/edges/strategies/edge_list.py +168 -0
  43. exonware/xwnode/edges/strategies/edge_property_store.py +2 -2
  44. exonware/xwnode/edges/strategies/euler_tour.py +560 -0
  45. exonware/xwnode/edges/strategies/{edge_flow_network.py → flow_network.py} +2 -2
  46. exonware/xwnode/edges/strategies/graphblas.py +449 -0
  47. exonware/xwnode/edges/strategies/hnsw.py +637 -0
  48. exonware/xwnode/edges/strategies/hop2_labels.py +467 -0
  49. exonware/xwnode/edges/strategies/{edge_hyperedge_set.py → hyperedge_set.py} +2 -2
  50. exonware/xwnode/edges/strategies/incidence_matrix.py +250 -0
  51. exonware/xwnode/edges/strategies/k2_tree.py +613 -0
  52. exonware/xwnode/edges/strategies/link_cut.py +626 -0
  53. exonware/xwnode/edges/strategies/multiplex.py +532 -0
  54. exonware/xwnode/edges/strategies/{edge_neural_graph.py → neural_graph.py} +2 -2
  55. exonware/xwnode/edges/strategies/{edge_octree.py → octree.py} +69 -11
  56. exonware/xwnode/edges/strategies/{edge_quadtree.py → quadtree.py} +66 -10
  57. exonware/xwnode/edges/strategies/roaring_adj.py +438 -0
  58. exonware/xwnode/edges/strategies/{edge_rtree.py → rtree.py} +43 -5
  59. exonware/xwnode/edges/strategies/{edge_temporal_edgeset.py → temporal_edgeset.py} +24 -5
  60. exonware/xwnode/edges/strategies/{edge_tree_graph_basic.py → tree_graph_basic.py} +78 -7
  61. exonware/xwnode/edges/strategies/{edge_weighted_graph.py → weighted_graph.py} +188 -10
  62. exonware/xwnode/errors.py +3 -6
  63. exonware/xwnode/facade.py +20 -20
  64. exonware/xwnode/nodes/strategies/__init__.py +29 -9
  65. exonware/xwnode/nodes/strategies/adjacency_list.py +650 -177
  66. exonware/xwnode/nodes/strategies/aho_corasick.py +358 -183
  67. exonware/xwnode/nodes/strategies/array_list.py +36 -3
  68. exonware/xwnode/nodes/strategies/art.py +581 -0
  69. exonware/xwnode/nodes/strategies/{node_avl_tree.py → avl_tree.py} +77 -6
  70. exonware/xwnode/nodes/strategies/{node_b_plus_tree.py → b_plus_tree.py} +81 -40
  71. exonware/xwnode/nodes/strategies/{node_btree.py → b_tree.py} +79 -9
  72. exonware/xwnode/nodes/strategies/base.py +469 -98
  73. exonware/xwnode/nodes/strategies/{node_bitmap.py → bitmap.py} +12 -12
  74. exonware/xwnode/nodes/strategies/{node_bitset_dynamic.py → bitset_dynamic.py} +11 -11
  75. exonware/xwnode/nodes/strategies/{node_bloom_filter.py → bloom_filter.py} +15 -2
  76. exonware/xwnode/nodes/strategies/bloomier_filter.py +519 -0
  77. exonware/xwnode/nodes/strategies/bw_tree.py +531 -0
  78. exonware/xwnode/nodes/strategies/contracts.py +1 -1
  79. exonware/xwnode/nodes/strategies/{node_count_min_sketch.py → count_min_sketch.py} +3 -2
  80. exonware/xwnode/nodes/strategies/{node_cow_tree.py → cow_tree.py} +135 -13
  81. exonware/xwnode/nodes/strategies/crdt_map.py +629 -0
  82. exonware/xwnode/nodes/strategies/{node_cuckoo_hash.py → cuckoo_hash.py} +2 -2
  83. exonware/xwnode/nodes/strategies/{node_xdata_optimized.py → data_interchange_optimized.py} +21 -4
  84. exonware/xwnode/nodes/strategies/dawg.py +876 -0
  85. exonware/xwnode/nodes/strategies/deque.py +321 -153
  86. exonware/xwnode/nodes/strategies/extendible_hash.py +93 -0
  87. exonware/xwnode/nodes/strategies/{node_fenwick_tree.py → fenwick_tree.py} +111 -19
  88. exonware/xwnode/nodes/strategies/hamt.py +403 -0
  89. exonware/xwnode/nodes/strategies/hash_map.py +354 -67
  90. exonware/xwnode/nodes/strategies/heap.py +105 -5
  91. exonware/xwnode/nodes/strategies/hopscotch_hash.py +525 -0
  92. exonware/xwnode/nodes/strategies/{node_hyperloglog.py → hyperloglog.py} +6 -5
  93. exonware/xwnode/nodes/strategies/interval_tree.py +742 -0
  94. exonware/xwnode/nodes/strategies/kd_tree.py +703 -0
  95. exonware/xwnode/nodes/strategies/learned_index.py +533 -0
  96. exonware/xwnode/nodes/strategies/linear_hash.py +93 -0
  97. exonware/xwnode/nodes/strategies/linked_list.py +316 -119
  98. exonware/xwnode/nodes/strategies/{node_lsm_tree.py → lsm_tree.py} +219 -15
  99. exonware/xwnode/nodes/strategies/masstree.py +130 -0
  100. exonware/xwnode/nodes/strategies/{node_persistent_tree.py → persistent_tree.py} +149 -9
  101. exonware/xwnode/nodes/strategies/priority_queue.py +544 -132
  102. exonware/xwnode/nodes/strategies/queue.py +249 -120
  103. exonware/xwnode/nodes/strategies/{node_red_black_tree.py → red_black_tree.py} +183 -72
  104. exonware/xwnode/nodes/strategies/{node_roaring_bitmap.py → roaring_bitmap.py} +19 -6
  105. exonware/xwnode/nodes/strategies/rope.py +717 -0
  106. exonware/xwnode/nodes/strategies/{node_segment_tree.py → segment_tree.py} +106 -106
  107. exonware/xwnode/nodes/strategies/{node_set_hash.py → set_hash.py} +30 -29
  108. exonware/xwnode/nodes/strategies/{node_skip_list.py → skip_list.py} +74 -6
  109. exonware/xwnode/nodes/strategies/sparse_matrix.py +427 -131
  110. exonware/xwnode/nodes/strategies/{node_splay_tree.py → splay_tree.py} +55 -6
  111. exonware/xwnode/nodes/strategies/stack.py +244 -112
  112. exonware/xwnode/nodes/strategies/{node_suffix_array.py → suffix_array.py} +5 -1
  113. exonware/xwnode/nodes/strategies/t_tree.py +94 -0
  114. exonware/xwnode/nodes/strategies/{node_treap.py → treap.py} +75 -6
  115. exonware/xwnode/nodes/strategies/{node_tree_graph_hybrid.py → tree_graph_hybrid.py} +46 -5
  116. exonware/xwnode/nodes/strategies/trie.py +153 -9
  117. exonware/xwnode/nodes/strategies/union_find.py +111 -5
  118. exonware/xwnode/nodes/strategies/veb_tree.py +856 -0
  119. exonware/xwnode/strategies/__init__.py +5 -51
  120. exonware/xwnode/version.py +3 -3
  121. {exonware_xwnode-0.0.1.21.dist-info → exonware_xwnode-0.0.1.23.dist-info}/METADATA +23 -3
  122. exonware_xwnode-0.0.1.23.dist-info/RECORD +130 -0
  123. exonware/xwnode/edges/strategies/edge_adj_list.py +0 -353
  124. exonware/xwnode/edges/strategies/edge_adj_matrix.py +0 -445
  125. exonware/xwnode/nodes/strategies/_base_node.py +0 -307
  126. exonware/xwnode/nodes/strategies/node_aho_corasick.py +0 -525
  127. exonware/xwnode/nodes/strategies/node_array_list.py +0 -179
  128. exonware/xwnode/nodes/strategies/node_hash_map.py +0 -273
  129. exonware/xwnode/nodes/strategies/node_heap.py +0 -196
  130. exonware/xwnode/nodes/strategies/node_linked_list.py +0 -413
  131. exonware/xwnode/nodes/strategies/node_trie.py +0 -257
  132. exonware/xwnode/nodes/strategies/node_union_find.py +0 -192
  133. exonware/xwnode/queries/executors/__init__.py +0 -47
  134. exonware/xwnode/queries/executors/advanced/__init__.py +0 -37
  135. exonware/xwnode/queries/executors/advanced/aggregate_executor.py +0 -50
  136. exonware/xwnode/queries/executors/advanced/ask_executor.py +0 -50
  137. exonware/xwnode/queries/executors/advanced/construct_executor.py +0 -50
  138. exonware/xwnode/queries/executors/advanced/describe_executor.py +0 -50
  139. exonware/xwnode/queries/executors/advanced/for_loop_executor.py +0 -50
  140. exonware/xwnode/queries/executors/advanced/foreach_executor.py +0 -50
  141. exonware/xwnode/queries/executors/advanced/join_executor.py +0 -50
  142. exonware/xwnode/queries/executors/advanced/let_executor.py +0 -50
  143. exonware/xwnode/queries/executors/advanced/mutation_executor.py +0 -50
  144. exonware/xwnode/queries/executors/advanced/options_executor.py +0 -50
  145. exonware/xwnode/queries/executors/advanced/pipe_executor.py +0 -50
  146. exonware/xwnode/queries/executors/advanced/subscribe_executor.py +0 -50
  147. exonware/xwnode/queries/executors/advanced/subscription_executor.py +0 -50
  148. exonware/xwnode/queries/executors/advanced/union_executor.py +0 -50
  149. exonware/xwnode/queries/executors/advanced/window_executor.py +0 -51
  150. exonware/xwnode/queries/executors/advanced/with_cte_executor.py +0 -50
  151. exonware/xwnode/queries/executors/aggregation/__init__.py +0 -21
  152. exonware/xwnode/queries/executors/aggregation/avg_executor.py +0 -50
  153. exonware/xwnode/queries/executors/aggregation/count_executor.py +0 -38
  154. exonware/xwnode/queries/executors/aggregation/distinct_executor.py +0 -50
  155. exonware/xwnode/queries/executors/aggregation/group_executor.py +0 -50
  156. exonware/xwnode/queries/executors/aggregation/having_executor.py +0 -50
  157. exonware/xwnode/queries/executors/aggregation/max_executor.py +0 -50
  158. exonware/xwnode/queries/executors/aggregation/min_executor.py +0 -50
  159. exonware/xwnode/queries/executors/aggregation/sum_executor.py +0 -50
  160. exonware/xwnode/queries/executors/aggregation/summarize_executor.py +0 -50
  161. exonware/xwnode/queries/executors/array/__init__.py +0 -9
  162. exonware/xwnode/queries/executors/array/indexing_executor.py +0 -51
  163. exonware/xwnode/queries/executors/array/slicing_executor.py +0 -51
  164. exonware/xwnode/queries/executors/base.py +0 -257
  165. exonware/xwnode/queries/executors/capability_checker.py +0 -204
  166. exonware/xwnode/queries/executors/contracts.py +0 -166
  167. exonware/xwnode/queries/executors/core/__init__.py +0 -17
  168. exonware/xwnode/queries/executors/core/create_executor.py +0 -96
  169. exonware/xwnode/queries/executors/core/delete_executor.py +0 -99
  170. exonware/xwnode/queries/executors/core/drop_executor.py +0 -100
  171. exonware/xwnode/queries/executors/core/insert_executor.py +0 -39
  172. exonware/xwnode/queries/executors/core/select_executor.py +0 -152
  173. exonware/xwnode/queries/executors/core/update_executor.py +0 -102
  174. exonware/xwnode/queries/executors/data/__init__.py +0 -13
  175. exonware/xwnode/queries/executors/data/alter_executor.py +0 -50
  176. exonware/xwnode/queries/executors/data/load_executor.py +0 -50
  177. exonware/xwnode/queries/executors/data/merge_executor.py +0 -50
  178. exonware/xwnode/queries/executors/data/store_executor.py +0 -50
  179. exonware/xwnode/queries/executors/defs.py +0 -93
  180. exonware/xwnode/queries/executors/engine.py +0 -221
  181. exonware/xwnode/queries/executors/errors.py +0 -68
  182. exonware/xwnode/queries/executors/filtering/__init__.py +0 -25
  183. exonware/xwnode/queries/executors/filtering/between_executor.py +0 -80
  184. exonware/xwnode/queries/executors/filtering/filter_executor.py +0 -79
  185. exonware/xwnode/queries/executors/filtering/has_executor.py +0 -70
  186. exonware/xwnode/queries/executors/filtering/in_executor.py +0 -70
  187. exonware/xwnode/queries/executors/filtering/like_executor.py +0 -76
  188. exonware/xwnode/queries/executors/filtering/optional_executor.py +0 -76
  189. exonware/xwnode/queries/executors/filtering/range_executor.py +0 -80
  190. exonware/xwnode/queries/executors/filtering/term_executor.py +0 -77
  191. exonware/xwnode/queries/executors/filtering/values_executor.py +0 -71
  192. exonware/xwnode/queries/executors/filtering/where_executor.py +0 -44
  193. exonware/xwnode/queries/executors/graph/__init__.py +0 -15
  194. exonware/xwnode/queries/executors/graph/in_traverse_executor.py +0 -51
  195. exonware/xwnode/queries/executors/graph/match_executor.py +0 -51
  196. exonware/xwnode/queries/executors/graph/out_executor.py +0 -51
  197. exonware/xwnode/queries/executors/graph/path_executor.py +0 -51
  198. exonware/xwnode/queries/executors/graph/return_executor.py +0 -51
  199. exonware/xwnode/queries/executors/ordering/__init__.py +0 -9
  200. exonware/xwnode/queries/executors/ordering/by_executor.py +0 -50
  201. exonware/xwnode/queries/executors/ordering/order_executor.py +0 -51
  202. exonware/xwnode/queries/executors/projection/__init__.py +0 -9
  203. exonware/xwnode/queries/executors/projection/extend_executor.py +0 -50
  204. exonware/xwnode/queries/executors/projection/project_executor.py +0 -50
  205. exonware/xwnode/queries/executors/registry.py +0 -173
  206. exonware/xwnode/queries/parsers/__init__.py +0 -26
  207. exonware/xwnode/queries/parsers/base.py +0 -86
  208. exonware/xwnode/queries/parsers/contracts.py +0 -46
  209. exonware/xwnode/queries/parsers/errors.py +0 -53
  210. exonware/xwnode/queries/parsers/sql_param_extractor.py +0 -318
  211. exonware/xwnode/queries/strategies/__init__.py +0 -24
  212. exonware/xwnode/queries/strategies/base.py +0 -236
  213. exonware/xwnode/queries/strategies/cql.py +0 -201
  214. exonware/xwnode/queries/strategies/cypher.py +0 -181
  215. exonware/xwnode/queries/strategies/datalog.py +0 -70
  216. exonware/xwnode/queries/strategies/elastic_dsl.py +0 -70
  217. exonware/xwnode/queries/strategies/eql.py +0 -70
  218. exonware/xwnode/queries/strategies/flux.py +0 -70
  219. exonware/xwnode/queries/strategies/gql.py +0 -70
  220. exonware/xwnode/queries/strategies/graphql.py +0 -240
  221. exonware/xwnode/queries/strategies/gremlin.py +0 -181
  222. exonware/xwnode/queries/strategies/hiveql.py +0 -214
  223. exonware/xwnode/queries/strategies/hql.py +0 -70
  224. exonware/xwnode/queries/strategies/jmespath.py +0 -219
  225. exonware/xwnode/queries/strategies/jq.py +0 -66
  226. exonware/xwnode/queries/strategies/json_query.py +0 -66
  227. exonware/xwnode/queries/strategies/jsoniq.py +0 -248
  228. exonware/xwnode/queries/strategies/kql.py +0 -70
  229. exonware/xwnode/queries/strategies/linq.py +0 -238
  230. exonware/xwnode/queries/strategies/logql.py +0 -70
  231. exonware/xwnode/queries/strategies/mql.py +0 -68
  232. exonware/xwnode/queries/strategies/n1ql.py +0 -210
  233. exonware/xwnode/queries/strategies/partiql.py +0 -70
  234. exonware/xwnode/queries/strategies/pig.py +0 -215
  235. exonware/xwnode/queries/strategies/promql.py +0 -70
  236. exonware/xwnode/queries/strategies/sparql.py +0 -220
  237. exonware/xwnode/queries/strategies/sql.py +0 -275
  238. exonware/xwnode/queries/strategies/xml_query.py +0 -66
  239. exonware/xwnode/queries/strategies/xpath.py +0 -223
  240. exonware/xwnode/queries/strategies/xquery.py +0 -258
  241. exonware/xwnode/queries/strategies/xwnode_executor.py +0 -332
  242. exonware/xwnode/queries/strategies/xwquery.py +0 -456
  243. exonware_xwnode-0.0.1.21.dist-info/RECORD +0 -214
  244. /exonware/xwnode/nodes/strategies/{node_ordered_map.py → ordered_map.py} +0 -0
  245. /exonware/xwnode/nodes/strategies/{node_ordered_map_balanced.py → ordered_map_balanced.py} +0 -0
  246. /exonware/xwnode/nodes/strategies/{node_patricia.py → patricia.py} +0 -0
  247. /exonware/xwnode/nodes/strategies/{node_radix_trie.py → radix_trie.py} +0 -0
  248. /exonware/xwnode/nodes/strategies/{node_set_tree.py → set_tree.py} +0 -0
  249. {exonware_xwnode-0.0.1.21.dist-info → exonware_xwnode-0.0.1.23.dist-info}/WHEEL +0 -0
  250. {exonware_xwnode-0.0.1.21.dist-info → exonware_xwnode-0.0.1.23.dist-info}/licenses/LICENSE +0 -0
@@ -57,15 +57,80 @@ class RedBlackTreeNode:
57
57
 
58
58
  class RedBlackTreeStrategy(ANodeTreeStrategy):
59
59
  """
60
- Red-black tree node strategy for self-balancing binary search trees.
61
-
62
- Provides guaranteed O(log n) height and operations through color-based
63
- balanc
60
+ Red-Black Tree strategy for self-balancing binary search trees.
61
+
62
+ WHY Red-Black Tree:
63
+ - Guaranteed O(log n) worst-case for insert, search, delete
64
+ - Simpler than AVL trees (less strict balancing = fewer rotations)
65
+ - Industry standard (used in Java TreeMap, C++ std::map, Linux kernel)
66
+ - Better insert/delete performance than AVL (relaxed balancing)
67
+ - Maintains sorted order with efficient range queries
68
+
69
+ WHY this implementation:
70
+ - Color-based balancing rules (simpler than height-based AVL)
71
+ - Parent pointers enable bottom-up fixup after operations
72
+ - Case-based rotation logic handles all red-black violations
73
+ - Tracks rotations and statistics for performance monitoring
74
+ - Preserves BST property while maintaining logarithmic height
75
+
76
+ Time Complexity:
77
+ - Insert: O(log n) guaranteed (at most 2 rotations)
78
+ - Search: O(log n) guaranteed
79
+ - Delete: O(log n) guaranteed (at most 3 rotations)
80
+ - Min/Max: O(log n) - leftmost/rightmost traversal
81
+ - Iteration: O(n) in sorted order
82
+
83
+ Space Complexity: O(n) - one node per key + parent pointers + color bit
84
+
85
+ Trade-offs:
86
+ - Advantage: Fewer rotations than AVL (better insert/delete performance)
87
+ - Advantage: Guaranteed O(log n) worst-case (unlike Skip List)
88
+ - Limitation: Slightly taller than AVL trees (height ≤ 2*log(n+1))
89
+ - Limitation: More complex than simple BST (color rules and rotations)
90
+ - Compared to AVL: Faster inserts/deletes, slightly slower searches
91
+ - Compared to B-Tree: Better for in-memory, worse for disk-based storage
92
+
93
+ Best for:
94
+ - General-purpose sorted collections (maps, sets)
95
+ - When insert/delete and search performance matter equally
96
+ - Implementing associative containers (key-value stores)
97
+ - When guaranteed O(log n) worst-case is required
98
+ - In-memory databases and indices
99
+
100
+ Not recommended for:
101
+ - Read-heavy workloads (AVL Tree is better)
102
+ - Disk-based storage (B-Tree is better)
103
+ - Simple, unsorted data (Hash Map is faster)
104
+ - Memory-constrained environments (overhead for parent pointers + color)
105
+ - When probabilistic guarantees suffice (Skip List is simpler)
106
+
107
+ Following eXonware Priorities:
108
+ 1. Usability: Self-balancing ensures consistent O(log n) performance
109
+ 2. Maintainability: Industry-standard algorithm, well-documented
110
+ 3. Performance: Optimized balance between insert and search operations
111
+ 4. Extensibility: Can be enhanced with augmentation (order statistics, intervals)
112
+ 5. Security: Input validation, bounded height prevents worst-case attacks
113
+
114
+ Industry Best Practices:
115
+ - Follows Cormen CLRS textbook implementation
116
+ - Maintains 5 red-black properties:
117
+ 1. Every node is red or black
118
+ 2. Root is black
119
+ 3. Leaves (NIL) are black
120
+ 4. Red nodes have black children
121
+ 5. All paths have same number of black nodes
122
+ - Uses case-based fixup (standard approach)
123
+ - Tracks performance statistics
124
+
125
+ Performance Note:
126
+ Red-Black Trees provide GUARANTEED O(log n) in worst-case.
127
+ Height is at most 2*log(n+1), ensuring consistent performance
128
+ even with adversarial input patterns. This makes them ideal for
129
+ production systems requiring predictable latency.
130
+ """
64
131
 
65
132
  # Strategy type classification
66
133
  STRATEGY_TYPE = NodeType.TREE
67
- ing rules and rotations.
68
- """
69
134
 
70
135
  def __init__(self, traits: NodeTrait = NodeTrait.NONE, **options):
71
136
  """Initialize the red-black tree strategy."""
@@ -267,98 +332,136 @@ ing rules and rotations.
267
332
  if not node:
268
333
  return False
269
334
 
270
- # Find replacement node
335
+ # Store original color
336
+ original_color = node.color
337
+
338
+ # Case 1: No left child
271
339
  if not node.left:
272
340
  replacement = node.right
341
+ self._transplant(node, node.right)
342
+ # Case 2: No right child
273
343
  elif not node.right:
274
344
  replacement = node.left
345
+ self._transplant(node, node.left)
346
+ # Case 3: Two children
275
347
  else:
276
- replacement = self._find_min(node.right)
277
- node.key = replacement.key
278
- node.value = replacement.value
279
- node = replacement
280
-
281
- # Remove node
282
- if replacement:
283
- replacement.parent = node.parent
284
-
285
- if not node.parent:
286
- self._root = replacement
287
- elif node == node.parent.left:
288
- node.parent.left = replacement
289
- else:
290
- node.parent.right = replacement
348
+ # Find successor (minimum in right subtree)
349
+ successor = self._find_min(node.right)
350
+ original_color = successor.color
351
+ replacement = successor.right
352
+
353
+ if successor.parent == node:
354
+ # Successor is direct right child
355
+ if replacement:
356
+ replacement.parent = successor
357
+ else:
358
+ # Successor is deeper in tree
359
+ self._transplant(successor, successor.right)
360
+ successor.right = node.right
361
+ successor.right.parent = successor
362
+
363
+ # Replace node with successor
364
+ self._transplant(node, successor)
365
+ successor.left = node.left
366
+ successor.left.parent = successor
367
+ successor.color = node.color
291
368
 
292
369
  # Fix red-black tree properties if needed
293
- if node.is_black() and replacement:
370
+ if original_color == 'BLACK' and replacement:
294
371
  self._fix_deletion(replacement)
295
- elif node.is_black():
296
- self._fix_deletion(None)
297
372
 
298
373
  self._size -= 1
299
374
  self._total_deletions += 1
300
375
  return True
301
376
 
302
- def _fix_deletion(self, node: Optional[RedBlackTreeNode]) -> None:
377
+ def _transplant(self, old_node: RedBlackTreeNode, new_node: Optional[RedBlackTreeNode]) -> None:
378
+ """Replace old_node with new_node in the tree."""
379
+ if not old_node.parent:
380
+ self._root = new_node
381
+ elif old_node == old_node.parent.left:
382
+ old_node.parent.left = new_node
383
+ else:
384
+ old_node.parent.right = new_node
385
+
386
+ if new_node:
387
+ new_node.parent = old_node.parent
388
+
389
+ def _fix_deletion(self, node: RedBlackTreeNode) -> None:
303
390
  """Fix red-black tree properties after deletion."""
304
- while node != self._root and (not node or node.is_black()):
305
- if node == node.parent.left:
306
- sibling = node.parent.right
391
+ while node != self._root and node.is_black():
392
+ parent = node.parent
393
+ if not parent:
394
+ break
395
+
396
+ if node == parent.left:
397
+ sibling = parent.right
307
398
  if sibling and sibling.is_red():
308
399
  # Case 1: Sibling is red
309
400
  sibling.set_black()
310
- node.parent.set_red()
311
- self._rotate_left(node.parent)
312
- sibling = node.parent.right
401
+ parent.set_red()
402
+ self._rotate_left(parent)
403
+ sibling = parent.right
313
404
 
314
- if (not sibling.left or sibling.left.is_black()) and \
315
- (not sibling.right or sibling.right.is_black()):
316
- # Case 2: Sibling and its children are black
317
- sibling.set_red()
318
- node = node.parent
319
- else:
320
- if not sibling.right or sibling.right.is_black():
321
- # Case 3: Sibling's right child is black
322
- sibling.left.set_black()
405
+ if sibling:
406
+ if ((not sibling.left or sibling.left.is_black()) and
407
+ (not sibling.right or sibling.right.is_black())):
408
+ # Case 2: Sibling and its children are black
323
409
  sibling.set_red()
324
- self._rotate_right(sibling)
325
- sibling = node.parent.right
326
-
327
- # Case 4: Sibling's right child is red
328
- sibling.color = node.parent.color
329
- node.parent.set_black()
330
- sibling.right.set_black()
331
- self._rotate_left(node.parent)
332
- node = self._root
410
+ node = parent
411
+ else:
412
+ if not sibling.right or sibling.right.is_black():
413
+ # Case 3: Sibling's right child is black
414
+ if sibling.left:
415
+ sibling.left.set_black()
416
+ sibling.set_red()
417
+ self._rotate_right(sibling)
418
+ sibling = parent.right
419
+
420
+ # Case 4: Sibling's right child is red
421
+ if sibling:
422
+ sibling.color = parent.color
423
+ parent.set_black()
424
+ if sibling.right:
425
+ sibling.right.set_black()
426
+ self._rotate_left(parent)
427
+ node = self._root
428
+ else:
429
+ break
333
430
  else:
334
431
  # Mirror cases for right side
335
- sibling = node.parent.left
432
+ sibling = parent.left
336
433
  if sibling and sibling.is_red():
337
434
  # Case 1: Sibling is red
338
435
  sibling.set_black()
339
- node.parent.set_red()
340
- self._rotate_right(node.parent)
341
- sibling = node.parent.left
436
+ parent.set_red()
437
+ self._rotate_right(parent)
438
+ sibling = parent.left
342
439
 
343
- if (not sibling.right or sibling.right.is_black()) and \
344
- (not sibling.left or sibling.left.is_black()):
345
- # Case 2: Sibling and its children are black
346
- sibling.set_red()
347
- node = node.parent
348
- else:
349
- if not sibling.left or sibling.left.is_black():
350
- # Case 3: Sibling's left child is black
351
- sibling.right.set_black()
440
+ if sibling:
441
+ if ((not sibling.right or sibling.right.is_black()) and
442
+ (not sibling.left or sibling.left.is_black())):
443
+ # Case 2: Sibling and its children are black
352
444
  sibling.set_red()
353
- self._rotate_left(sibling)
354
- sibling = node.parent.left
355
-
356
- # Case 4: Sibling's left child is red
357
- sibling.color = node.parent.color
358
- node.parent.set_black()
359
- sibling.left.set_black()
360
- self._rotate_right(node.parent)
361
- node = self._root
445
+ node = parent
446
+ else:
447
+ if not sibling.left or sibling.left.is_black():
448
+ # Case 3: Sibling's left child is black
449
+ if sibling.right:
450
+ sibling.right.set_black()
451
+ sibling.set_red()
452
+ self._rotate_left(sibling)
453
+ sibling = parent.left
454
+
455
+ # Case 4: Sibling's left child is red
456
+ if sibling:
457
+ sibling.color = parent.color
458
+ parent.set_black()
459
+ if sibling.left:
460
+ sibling.left.set_black()
461
+ self._rotate_right(parent)
462
+ node = self._root
463
+ else:
464
+ break
362
465
 
363
466
  if node:
364
467
  node.set_black()
@@ -412,6 +515,14 @@ ing rules and rotations.
412
515
  """Get number of key-value pairs."""
413
516
  return self._size
414
517
 
518
+ def __len__(self) -> int:
519
+ """Get number of key-value pairs."""
520
+ return self._size
521
+
522
+ def to_native(self) -> Dict[str, Any]:
523
+ """Convert to native Python dict."""
524
+ return dict(self.items())
525
+
415
526
  def is_empty(self) -> bool:
416
527
  """Check if tree is empty."""
417
528
  return self._root is None
@@ -1,8 +1,21 @@
1
1
  """
2
+ #exonware/xwnode/src/exonware/xwnode/nodes/strategies/roaring_bitmap.py
3
+
2
4
  Roaring Bitmap Node Strategy Implementation
3
5
 
6
+ Status: Production Ready ✅
7
+ True Purpose: Highly compressed bitmap operations for sparse data
8
+ Complexity: O(log n) arrays, O(1) bitmaps - hybrid approach
9
+ Production Features: ✓ Hybrid Containers, ✓ Auto-conversion, ✓ Set Operations, ✓ Compression
10
+
4
11
  This module implements the ROARING_BITMAP strategy for highly compressed
5
12
  bitmap operations with excellent performance for sparse data.
13
+
14
+ Company: eXonware.com
15
+ Author: Eng. Muhammad AlShehri
16
+ Email: connect@exonware.com
17
+ Version: 0.0.1.23
18
+ Generation Date: October 12, 2025
6
19
  """
7
20
 
8
21
  from typing import Any, Iterator, List, Dict, Optional, Set, Tuple
@@ -394,9 +407,9 @@ ormance characteristics.
394
407
  removed_count += 1
395
408
  return removed_count
396
409
 
397
- def union(self, other: 'xRoaringBitmapStrategy') -> 'xRoaringBitmapStrategy':
410
+ def union(self, other: 'RoaringBitmapStrategy') -> 'RoaringBitmapStrategy':
398
411
  """Union with another roaring bitmap."""
399
- result = xRoaringBitmapStrategy(traits=self._traits)
412
+ result = RoaringBitmapStrategy(traits=self.traits)
400
413
 
401
414
  # Union all containers
402
415
  all_highs = set(self._containers.keys()) | set(other._containers.keys())
@@ -417,9 +430,9 @@ ormance characteristics.
417
430
 
418
431
  return result
419
432
 
420
- def intersection(self, other: 'xRoaringBitmapStrategy') -> 'xRoaringBitmapStrategy':
433
+ def intersection(self, other: 'RoaringBitmapStrategy') -> 'RoaringBitmapStrategy':
421
434
  """Intersection with another roaring bitmap."""
422
- result = xRoaringBitmapStrategy(traits=self._traits)
435
+ result = RoaringBitmapStrategy(traits=self.traits)
423
436
 
424
437
  # Intersect only common containers
425
438
  common_highs = set(self._containers.keys()) & set(other._containers.keys())
@@ -436,9 +449,9 @@ ormance characteristics.
436
449
 
437
450
  return result
438
451
 
439
- def difference(self, other: 'xRoaringBitmapStrategy') -> 'xRoaringBitmapStrategy':
452
+ def difference(self, other: 'RoaringBitmapStrategy') -> 'RoaringBitmapStrategy':
440
453
  """Difference with another roaring bitmap."""
441
- result = xRoaringBitmapStrategy(traits=self._traits)
454
+ result = RoaringBitmapStrategy(traits=self.traits)
442
455
 
443
456
  for high, container in self._containers.items():
444
457
  self_values = set(container.to_array())