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
exonware/__init__.py CHANGED
@@ -4,7 +4,7 @@ exonware package - Enterprise-grade Python framework ecosystem
4
4
  Company: eXonware.com
5
5
  Author: Eng. Muhammad AlShehri
6
6
  Email: connect@exonware.com
7
- Version: 0.0.1.22
7
+ Version: 0.0.1.23
8
8
  Generation Date: 2025-01-03
9
9
 
10
10
  This is a namespace package allowing multiple exonware subpackages
@@ -10,12 +10,11 @@ data handling libraries like xdata.
10
10
  Company: eXonware.com
11
11
  Author: Eng. Muhammad AlShehri
12
12
  Email: connect@exonware.com
13
- Version: 0.0.1.22
13
+ Version: 0.0.1.23
14
14
  Generation Date: 07-Sep-2025
15
15
 
16
16
  Main Classes:
17
17
  XWNode: The primary interface for working with hierarchical data
18
- XWQuery: Query interface for searching and filtering nodes
19
18
  XWFactory: Factory for creating XWNode instances
20
19
 
21
20
  Exceptions:
@@ -57,7 +56,7 @@ Example:
57
56
  # IMPORTS - Standard Python Imports (No Defensive Code!)
58
57
  # =============================================================================
59
58
  from .facade import (
60
- XWNode, XWEdge, XWQuery, XWFactory,
59
+ XWNode, XWEdge, XWFactory,
61
60
  # A+ Usability Presets
62
61
  create_with_preset, list_available_presets,
63
62
  # Performance Modes
@@ -68,9 +67,12 @@ from .errors import (
68
67
  XWNodeSecurityError, XWNodeLimitError, XWNodePathSecurityError
69
68
  )
70
69
  from .config import XWNodeConfig, get_config, set_config
70
+ from .defs import NodeMode, EdgeMode, NodeTrait, EdgeTrait, GraphOptimization
71
+ # Note: QueryMode and QueryTrait are in xwquery.defs module
72
+ from .common.graph import XWGraphManager
71
73
 
72
74
  # xwsystem lazy install functionality
73
- from exonware.xwsystem.utils.lazy_install import xwimport
75
+ from exonware.xwsystem.utils.lazy_package import xwimport
74
76
  from exonware.xwsystem.monitoring import get_metrics as get_xwsystem_metrics, reset_metrics as reset_xwsystem_metrics
75
77
 
76
78
  # Version info
@@ -84,7 +86,6 @@ __all__ = [
84
86
  # Main classes
85
87
  'XWNode',
86
88
  'XWEdge',
87
- 'XWQuery',
88
89
  'XWFactory',
89
90
 
90
91
  # A+ Usability Presets
@@ -102,6 +103,18 @@ __all__ = [
102
103
  'get_config',
103
104
  'set_config',
104
105
 
106
+ # Enums and Types
107
+ 'NodeMode',
108
+ 'EdgeMode',
109
+ 'QueryMode',
110
+ 'NodeTrait',
111
+ 'EdgeTrait',
112
+ 'QueryTrait',
113
+ 'GraphOptimization',
114
+
115
+ # Graph Optimization
116
+ 'XWGraphManager',
117
+
105
118
  # Lazy Install
106
119
  'xwimport',
107
120
 
@@ -0,0 +1,165 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Add STRATEGY_TYPE to All Node Strategies
4
+
5
+ This script automatically adds STRATEGY_TYPE declarations to all node strategy files
6
+ based on the inheritance audit.
7
+
8
+ Company: eXonware.com
9
+ Author: Eng. Muhammad AlShehri
10
+ Email: connect@exonware.com
11
+ Version: 0.0.1.23
12
+ Generation Date: 08-Oct-2025
13
+ """
14
+
15
+ import re
16
+ from pathlib import Path
17
+ from typing import Dict
18
+
19
+ # Map strategy files to their NodeType
20
+ STRATEGY_TYPE_MAP = {
21
+ # LINEAR
22
+ 'array_list.py': 'LINEAR',
23
+ 'linked_list.py': 'LINEAR',
24
+ 'stack.py': 'LINEAR',
25
+ 'queue.py': 'LINEAR',
26
+ 'deque.py': 'LINEAR',
27
+ 'priority_queue.py': 'LINEAR',
28
+
29
+ # TREE
30
+ 'hash_map.py': 'TREE',
31
+ 'heap.py': 'TREE',
32
+ 'trie.py': 'TREE',
33
+ 'aho_corasick.py': 'TREE',
34
+ 'avl_tree.py': 'TREE',
35
+ 'b_plus_tree.py': 'TREE',
36
+ 'btree.py': 'TREE',
37
+ 'cow_tree.py': 'TREE',
38
+ 'fenwick_tree.py': 'TREE',
39
+ 'lsm_tree.py': 'TREE',
40
+ 'ordered_map.py': 'TREE',
41
+ 'ordered_map_balanced.py': 'TREE',
42
+ 'patricia.py': 'TREE',
43
+ 'persistent_tree.py': 'TREE',
44
+ 'radix_trie.py': 'TREE',
45
+ 'red_black_tree.py': 'TREE',
46
+ 'segment_tree.py': 'TREE',
47
+ 'skip_list.py': 'TREE',
48
+ 'splay_tree.py': 'TREE',
49
+ 'suffix_array.py': 'TREE',
50
+ 'treap.py': 'TREE',
51
+ 'art.py': 'TREE',
52
+ 'bw_tree.py': 'TREE',
53
+ 'hamt.py': 'TREE',
54
+ 'masstree.py': 'TREE',
55
+ 'extendible_hash.py': 'TREE',
56
+ 'linear_hash.py': 'TREE',
57
+ 't_tree.py': 'TREE',
58
+ 'learned_index.py': 'TREE',
59
+
60
+ # GRAPH
61
+ 'union_find.py': 'GRAPH',
62
+ 'adjacency_list.py': 'GRAPH',
63
+
64
+ # MATRIX
65
+ 'sparse_matrix.py': 'MATRIX',
66
+ 'bitmap.py': 'MATRIX',
67
+ 'bitset_dynamic.py': 'MATRIX',
68
+ 'roaring_bitmap.py': 'MATRIX',
69
+ 'bloom_filter.py': 'MATRIX',
70
+ 'count_min_sketch.py': 'MATRIX',
71
+ 'hyperloglog.py': 'MATRIX',
72
+ 'set_hash.py': 'MATRIX',
73
+ 'set_tree.py': 'TREE',
74
+ 'cuckoo_hash.py': 'TREE',
75
+
76
+ # HYBRID
77
+ 'tree_graph_hybrid.py': 'HYBRID',
78
+ 'xdata_optimized.py': 'HYBRID',
79
+ }
80
+
81
+
82
+ def add_strategy_type_to_file(file_path: Path, node_type: str) -> bool:
83
+ """Add STRATEGY_TYPE to a strategy file."""
84
+ try:
85
+ with open(file_path, 'r', encoding='utf-8') as f:
86
+ content = f.read()
87
+
88
+ # Check if STRATEGY_TYPE already exists
89
+ if 'STRATEGY_TYPE' in content:
90
+ print(f" ⏭️ Already has STRATEGY_TYPE: {file_path.name}")
91
+ return False
92
+
93
+ # Find class definition
94
+ class_match = re.search(r'(class \w+Strategy\([^)]+\):\s*\n\s*"""[^"]*""")', content, re.MULTILINE)
95
+ if not class_match:
96
+ print(f" ⚠️ Could not find class definition: {file_path.name}")
97
+ return False
98
+
99
+ # Add import if not present
100
+ if 'from .contracts import NodeType' not in content:
101
+ # Find where to add import (after other local imports)
102
+ if 'from .base import' in content:
103
+ content = content.replace(
104
+ 'from .base import',
105
+ 'from .base import'
106
+ )
107
+ # Add after base import
108
+ import_pos = content.find('from .base import')
109
+ line_end = content.find('\n', import_pos)
110
+ content = content[:line_end+1] + 'from .contracts import NodeType\n' + content[line_end+1:]
111
+
112
+ # Add STRATEGY_TYPE after class docstring
113
+ class_end = class_match.end()
114
+
115
+ # Add STRATEGY_TYPE declaration
116
+ strategy_type_line = f'\n \n # Strategy type classification\n STRATEGY_TYPE = NodeType.{node_type}\n'
117
+ content = content[:class_end] + strategy_type_line + content[class_end:]
118
+
119
+ # Write back
120
+ with open(file_path, 'w', encoding='utf-8') as f:
121
+ f.write(content)
122
+
123
+ print(f" ✅ Added STRATEGY_TYPE.{node_type}: {file_path.name}")
124
+ return True
125
+
126
+ except Exception as e:
127
+ print(f" ❌ Error processing {file_path.name}: {e}")
128
+ return False
129
+
130
+
131
+ def main():
132
+ """Main function."""
133
+ print("="*70)
134
+ print("Adding STRATEGY_TYPE to All Node Strategies")
135
+ print("="*70)
136
+
137
+ base_path = Path(__file__).parent / 'src' / 'exonware' / 'xwnode' / 'nodes' / 'strategies'
138
+
139
+ count_added = 0
140
+ count_skipped = 0
141
+ count_errors = 0
142
+
143
+ for filename, node_type in STRATEGY_TYPE_MAP.items():
144
+ file_path = base_path / filename
145
+
146
+ if not file_path.exists():
147
+ print(f" ⚠️ File not found: {filename}")
148
+ count_errors += 1
149
+ continue
150
+
151
+ result = add_strategy_type_to_file(file_path, node_type)
152
+ if result:
153
+ count_added += 1
154
+ elif 'Already has' in str(result):
155
+ count_skipped += 1
156
+ else:
157
+ count_errors += 1
158
+
159
+ print("\n" + "="*70)
160
+ print(f"Summary: {count_added} added, {count_skipped} skipped, {count_errors} errors")
161
+ print("="*70)
162
+
163
+
164
+ if __name__ == '__main__':
165
+ main()
@@ -6,7 +6,7 @@ Common utilities and patterns shared across xwnode.
6
6
  Company: eXonware.com
7
7
  Author: Eng. Muhammad AlShehri
8
8
  Email: connect@exonware.com
9
- Version: 0.0.1.22
9
+ Version: 0.0.1.23
10
10
  """
11
11
 
12
12
  # Export common patterns
@@ -0,0 +1,30 @@
1
+ """
2
+ #exonware/xwnode/src/exonware/xwnode/common/graph/__init__.py
3
+
4
+ Graph optimization module for XWNode.
5
+
6
+ Provides O(1) relationship queries with multi-tenant security isolation.
7
+
8
+ Company: eXonware.com
9
+ Author: Eng. Muhammad AlShehri
10
+ Email: connect@exonware.com
11
+ Version: 0.0.1.23
12
+ Generation Date: 11-Oct-2025
13
+ """
14
+
15
+ from .manager import XWGraphManager
16
+ from .errors import (
17
+ XWGraphError,
18
+ XWGraphSecurityError,
19
+ XWGraphEntityNotFoundError,
20
+ XWGraphRelationshipNotFoundError
21
+ )
22
+
23
+ __all__ = [
24
+ 'XWGraphManager',
25
+ 'XWGraphError',
26
+ 'XWGraphSecurityError',
27
+ 'XWGraphEntityNotFoundError',
28
+ 'XWGraphRelationshipNotFoundError'
29
+ ]
30
+
@@ -0,0 +1,131 @@
1
+ """
2
+ #exonware/xwnode/src/exonware/xwnode/common/graph/caching.py
3
+
4
+ LRU cache manager for frequent relationship queries.
5
+
6
+ Company: eXonware.com
7
+ Author: Eng. Muhammad AlShehri
8
+ Email: connect@exonware.com
9
+ Version: 0.0.1.23
10
+ Generation Date: 11-Oct-2025
11
+ """
12
+
13
+ import threading
14
+ from typing import Any, Optional, List
15
+ from collections import OrderedDict
16
+
17
+
18
+ class CacheManager:
19
+ """
20
+ Thread-safe LRU cache for query results.
21
+
22
+ Provides O(1) cache operations with automatic eviction
23
+ of least recently used entries.
24
+ """
25
+
26
+ def __init__(self, max_size: int = 1000):
27
+ """
28
+ Initialize cache manager.
29
+
30
+ Args:
31
+ max_size: Maximum number of cached entries
32
+ """
33
+ self._cache: OrderedDict[str, Any] = OrderedDict()
34
+ self._max_size = max_size
35
+ self._hits = 0
36
+ self._misses = 0
37
+ self._lock = threading.RLock()
38
+
39
+ def get(self, key: str) -> Optional[Any]:
40
+ """
41
+ Get cached result.
42
+
43
+ Args:
44
+ key: Cache key
45
+
46
+ Returns:
47
+ Cached value or None if not found
48
+
49
+ Time Complexity: O(1)
50
+ """
51
+ with self._lock:
52
+ if key in self._cache:
53
+ self._hits += 1
54
+ # Move to end (most recently used)
55
+ self._cache.move_to_end(key)
56
+ return self._cache[key]
57
+
58
+ self._misses += 1
59
+ return None
60
+
61
+ def put(self, key: str, value: Any) -> None:
62
+ """
63
+ Cache a query result.
64
+
65
+ Args:
66
+ key: Cache key
67
+ value: Value to cache
68
+
69
+ Time Complexity: O(1)
70
+ """
71
+ with self._lock:
72
+ if key in self._cache:
73
+ # Update existing entry
74
+ self._cache.move_to_end(key)
75
+ self._cache[key] = value
76
+ else:
77
+ # Add new entry
78
+ if len(self._cache) >= self._max_size:
79
+ # Remove least recently used (first item)
80
+ self._cache.popitem(last=False)
81
+ self._cache[key] = value
82
+
83
+ def invalidate(self, entity_id: str) -> None:
84
+ """
85
+ Invalidate cache entries for entity.
86
+
87
+ Removes all cached queries that involve the specified entity.
88
+
89
+ Args:
90
+ entity_id: Entity whose cache entries should be invalidated
91
+ """
92
+ with self._lock:
93
+ # Find all cache keys containing this entity
94
+ keys_to_remove = [k for k in self._cache.keys() if entity_id in k]
95
+
96
+ # Remove them
97
+ for key in keys_to_remove:
98
+ del self._cache[key]
99
+
100
+ def clear(self) -> None:
101
+ """Clear all cached entries."""
102
+ with self._lock:
103
+ self._cache.clear()
104
+
105
+ def get_hit_rate(self) -> float:
106
+ """
107
+ Get cache hit rate.
108
+
109
+ Returns:
110
+ Hit rate as float between 0.0 and 1.0
111
+ """
112
+ with self._lock:
113
+ total = self._hits + self._misses
114
+ return self._hits / total if total > 0 else 0.0
115
+
116
+ def get_stats(self) -> dict:
117
+ """
118
+ Get cache statistics.
119
+
120
+ Returns:
121
+ Dictionary with cache metrics
122
+ """
123
+ with self._lock:
124
+ return {
125
+ 'size': len(self._cache),
126
+ 'max_size': self._max_size,
127
+ 'hits': self._hits,
128
+ 'misses': self._misses,
129
+ 'hit_rate': self.get_hit_rate()
130
+ }
131
+
@@ -0,0 +1,100 @@
1
+ """
2
+ #exonware/xwnode/src/exonware/xwnode/common/graph/contracts.py
3
+
4
+ Graph manager contracts and enums.
5
+
6
+ Company: eXonware.com
7
+ Author: Eng. Muhammad AlShehri
8
+ Email: connect@exonware.com
9
+ Version: 0.0.1.23
10
+ Generation Date: 11-Oct-2025
11
+ """
12
+
13
+ from enum import Enum
14
+ from abc import ABC, abstractmethod
15
+ from typing import Dict, List, Optional, Any
16
+
17
+
18
+ class GraphOptimization(Enum):
19
+ """
20
+ Graph optimization levels for XWGraphManager.
21
+
22
+ Controls indexing and caching behavior for performance tuning.
23
+ """
24
+
25
+ OFF = 0 # No optimization - fallback to O(n) iteration
26
+ INDEX_ONLY = 1 # Only indexing - O(1) lookups, no caching
27
+ CACHE_ONLY = 2 # Only caching - benefits from repeated queries
28
+ FULL = 3 # Both indexing + caching - maximum performance
29
+
30
+ # Aliases for clarity
31
+ DISABLED = 0
32
+ MINIMAL = 1
33
+ MODERATE = 2
34
+ MAXIMUM = 3
35
+
36
+
37
+ class IGraphManager(ABC):
38
+ """Interface for graph manager implementations."""
39
+
40
+ @abstractmethod
41
+ def add_relationship(
42
+ self,
43
+ source: str,
44
+ target: str,
45
+ relationship_type: str,
46
+ **properties
47
+ ) -> str:
48
+ """Add a relationship between entities."""
49
+ pass
50
+
51
+ @abstractmethod
52
+ def remove_relationship(
53
+ self,
54
+ source: str,
55
+ target: str,
56
+ relationship_type: Optional[str] = None
57
+ ) -> bool:
58
+ """Remove relationship(s) between entities."""
59
+ pass
60
+
61
+ @abstractmethod
62
+ def get_outgoing(
63
+ self,
64
+ entity_id: str,
65
+ relationship_type: Optional[str] = None,
66
+ limit: Optional[int] = None
67
+ ) -> List[Dict[str, Any]]:
68
+ """Get outgoing relationships for entity."""
69
+ pass
70
+
71
+ @abstractmethod
72
+ def get_incoming(
73
+ self,
74
+ entity_id: str,
75
+ relationship_type: Optional[str] = None,
76
+ limit: Optional[int] = None
77
+ ) -> List[Dict[str, Any]]:
78
+ """Get incoming relationships for entity."""
79
+ pass
80
+
81
+ @abstractmethod
82
+ def has_relationship(
83
+ self,
84
+ source: str,
85
+ target: str,
86
+ relationship_type: Optional[str] = None
87
+ ) -> bool:
88
+ """Check if relationship exists."""
89
+ pass
90
+
91
+ @abstractmethod
92
+ def get_stats(self) -> Dict[str, Any]:
93
+ """Get graph statistics."""
94
+ pass
95
+
96
+ @abstractmethod
97
+ def clear_cache(self) -> None:
98
+ """Clear query cache."""
99
+ pass
100
+
@@ -0,0 +1,44 @@
1
+ """
2
+ #exonware/xwnode/src/exonware/xwnode/common/graph/errors.py
3
+
4
+ Graph-specific error classes.
5
+
6
+ Company: eXonware.com
7
+ Author: Eng. Muhammad AlShehri
8
+ Email: connect@exonware.com
9
+ Version: 0.0.1.23
10
+ Generation Date: 11-Oct-2025
11
+ """
12
+
13
+ from ...errors import XWNodeError
14
+
15
+
16
+ class XWGraphError(XWNodeError):
17
+ """Base error for graph operations."""
18
+ pass
19
+
20
+
21
+ class XWGraphSecurityError(XWGraphError):
22
+ """Security violation in graph operations."""
23
+ pass
24
+
25
+
26
+ class XWGraphEntityNotFoundError(XWGraphError):
27
+ """Entity not found in graph."""
28
+ pass
29
+
30
+
31
+ class XWGraphRelationshipNotFoundError(XWGraphError):
32
+ """Relationship not found in graph."""
33
+ pass
34
+
35
+
36
+ class XWGraphCycleDetectedError(XWGraphError):
37
+ """Cycle detected in graph traversal."""
38
+ pass
39
+
40
+
41
+ class XWGraphInvalidOperationError(XWGraphError):
42
+ """Invalid graph operation."""
43
+ pass
44
+