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
@@ -0,0 +1,130 @@
1
+ exonware/__init__.py,sha256=OLPn37Tlk7pXfSLGOQkrheQjg_M6V9ecIDbAR1BhYeo,624
2
+ exonware/xwnode/__init__.py,sha256=eZeiAWLQopVse7trEEt2s8ixLAUcZbp2KKVSLw1kna8,4175
3
+ exonware/xwnode/add_strategy_types.py,sha256=NGgzbLKZTZdFaC326TFp7NwHtEvBVwIhTZokIzNY68A,4977
4
+ exonware/xwnode/base.py,sha256=zM2vE55RziwBz_-x0B5GYGOyM0Coi_kEo-meMM59u-A,23895
5
+ exonware/xwnode/config.py,sha256=cJGwxc2FiNH9lw1vslLHOQJ3Xl2DfekKF4h_lnUD-pc,5519
6
+ exonware/xwnode/contracts.py,sha256=s3nMO7hdSvDbonABbQAHgmWsDi_H_P7JdyU6WqYnRWM,17925
7
+ exonware/xwnode/defs.py,sha256=eWjFb0UOCltv90VXwW0e-ijGTHYkdhXmX6yyq17-QXA,47068
8
+ exonware/xwnode/errors.py,sha256=JVS1AgK7wtR_c170UWRPaIqGqVWylc9qpu3JPyT8pNU,18285
9
+ exonware/xwnode/facade.py,sha256=MxglZnKG9TE1N6X3F9O4HwIF5-jSQjL_oiG_c5-1PLY,16263
10
+ exonware/xwnode/version.py,sha256=1bAacoFMdjL8dzJB0mydgRNkGu6vzCouU_SuL4W-nsQ,2379
11
+ exonware/xwnode/common/__init__.py,sha256=ayCJdi2CxbI5W-m-sRbmIdKaqIcYY35SIJiU-ALqsB4,387
12
+ exonware/xwnode/common/graph/__init__.py,sha256=SR1bJ3uEvupWNMvIKv9Z7_LXTNLxplnb74uo6oCQyzk,645
13
+ exonware/xwnode/common/graph/caching.py,sha256=7epURZDo_ma5jXWAkTVEP4fzLeOM4EFSYaYhYnd-2vI,3575
14
+ exonware/xwnode/common/graph/contracts.py,sha256=Rxsp7kVaZJRqb5pz3nhf_hVouR9LTUxba4T3Zr7ZYP4,2434
15
+ exonware/xwnode/common/graph/errors.py,sha256=kas54Z_kTbcD8vP3n-8fikAIzeffogdhIcEh_MSgMcQ,857
16
+ exonware/xwnode/common/graph/indexing.py,sha256=5cvaulHAO-tR0zn4VDxnDSZ0soN0mBa3WyhJxWgEFQY,8306
17
+ exonware/xwnode/common/graph/manager.py,sha256=R_4IYusKj0sdZUV2wnzFZFnAVvKRfHqILbhKIcrIrBo,19875
18
+ exonware/xwnode/common/management/__init__.py,sha256=7hl5F4roCxtQBNUsHJ8pLiCBLNpvFNceBv1Xnegv8WU,663
19
+ exonware/xwnode/common/management/manager.py,sha256=xi0KqWQZIieYl8r7v2H3Bq8k9fJ-aKs3u59raXEI5AI,33972
20
+ exonware/xwnode/common/management/migration.py,sha256=lXjg27SuHSF36dRxhL7zq-o0atB0ODdz7Bl3PHvSQDc,20191
21
+ exonware/xwnode/common/monitoring/__init__.py,sha256=MdvdB7NC9k8hLIPKqrozonv9Znb8FUKMGGhzSbwZLwQ,663
22
+ exonware/xwnode/common/monitoring/metrics.py,sha256=wCIpnpleLGAFdFRbcSIZcoPTRABuJjadOCXys1r3wwc,19556
23
+ exonware/xwnode/common/monitoring/pattern_detector.py,sha256=fSDt_nZ_ZBA8CjQXH1kph1AhpdhOKCzI5GOTl0Up3mQ,21668
24
+ exonware/xwnode/common/monitoring/performance_monitor.py,sha256=QVO9NeOwhoIrjaBbcTwhrOxxT1OnVYwHrIuuViwo7dc,17579
25
+ exonware/xwnode/common/patterns/__init__.py,sha256=HLjCSSit0K269_l1ib5DhN4WmbF2C4k6KWtPpuX1T1o,659
26
+ exonware/xwnode/common/patterns/advisor.py,sha256=RrHRKARK25dwK6dSrOkJeNkMssnJRGW0CMh6KCpGaGQ,18189
27
+ exonware/xwnode/common/patterns/flyweight.py,sha256=pXcJLJtyEbbEvWaFU85jbGJBN9e4Lvk4LG6FCTC51FA,11434
28
+ exonware/xwnode/common/patterns/registry.py,sha256=fi5dZkCTJKqz2KCW16am5WjGEyQefvwYerWLc6wo2b4,29822
29
+ exonware/xwnode/common/utils/__init__.py,sha256=K2RQIjUdZxJCZ5AHOSTD7qe3wFZeyi7nYpcy1Xl6u8s,1464
30
+ exonware/xwnode/common/utils/simple.py,sha256=QN7-kpk73nwPN6vS0Xw54DYKWmcEGPfB9FqTIu2nuRE,9080
31
+ exonware/xwnode/common/utils/utils.py,sha256=ma_C5Xpgpo0053jEWqzco4-KNyBOWanJhKvQ3Masq84,17554
32
+ exonware/xwnode/edges/strategies/__init__.py,sha256=g75QvFSl8BuFV_XSY41Wj5awNd81wFdG3u9wSD3a3ZU,3249
33
+ exonware/xwnode/edges/strategies/_base_edge.py,sha256=9cgyolEGwmteUJDRltlIvHugDco1_iS1_z5_fadGCYg,13647
34
+ exonware/xwnode/edges/strategies/adj_list.py,sha256=91pzpi1pNxsOAUTRNkFeZ2v-WGvyVaF9_W0tctEJ51k,15676
35
+ exonware/xwnode/edges/strategies/adj_matrix.py,sha256=D8RNDUE_eQvRJ5nLMq-rXgQr6y50Nqdwk0-MHbfO5ts,19247
36
+ exonware/xwnode/edges/strategies/base.py,sha256=ks69Fu6mKhnPPV_W2_XyLu3pGEPnX08b2ErCWg7lbQY,6251
37
+ exonware/xwnode/edges/strategies/bidir_wrapper.py,sha256=u5Hi6_K79UncTI7oWR5d_JT_7-yuk6NcJ07PhwCNdwE,19824
38
+ exonware/xwnode/edges/strategies/bitemporal.py,sha256=iPGpfSF_7xisC-qvn5L53O_jzqQR7QopaIeo3gTBd-I,18460
39
+ exonware/xwnode/edges/strategies/block_adj_matrix.py,sha256=nf64WsXxiqi5t7Bf0wYzrECWuLwIvKe2MG5qrxDSa6s,23778
40
+ exonware/xwnode/edges/strategies/bv_graph.py,sha256=4MZQf3n3oe7GBC7QasR083iBmiju_YwsfU_by0IIvQE,22598
41
+ exonware/xwnode/edges/strategies/compressed_graph.py,sha256=CZTTbyXkEhcj8Jp2Sj9LBo8NpT82AI-2YIoiDLfLcYQ,7838
42
+ exonware/xwnode/edges/strategies/coo.py,sha256=8Srn6QgsCOuErRns94kpkmIkWdVMQhsBu7v6vN2TZKE,21605
43
+ exonware/xwnode/edges/strategies/csc.py,sha256=Nt-7Rsh4Dk6M6AOLbRa9rO-6yYYhOaeFfmpMA6NrV44,18435
44
+ exonware/xwnode/edges/strategies/csr.py,sha256=XJOQXsVk2DObdQIdu-VYUq8kBrjB1_excwQA9zwbL8A,22336
45
+ exonware/xwnode/edges/strategies/dynamic_adj_list.py,sha256=mePzSVARy5OdCvWEKGW1W314fDKXHW2tlJz1j1COTB0,21408
46
+ exonware/xwnode/edges/strategies/edge_list.py,sha256=ixIiO8ta4JXOBrn6JeVWQhDW0Z4ajFrchlpXI3mFg40,5832
47
+ exonware/xwnode/edges/strategies/edge_property_store.py,sha256=oCKthsTZLVkx1TnaCWMnh7uLV14j2TxlN1EMWWW1qIM,25628
48
+ exonware/xwnode/edges/strategies/euler_tour.py,sha256=2OwJWVMJajKFS8Gvy-B8Sso9gh8DyBNCp2p69qzptes,18116
49
+ exonware/xwnode/edges/strategies/flow_network.py,sha256=GzaEKc98QTYAa7k7QnXRAPoHCPWkjAQUMziIfxyTvJk,21471
50
+ exonware/xwnode/edges/strategies/graphblas.py,sha256=35LLLCFcU7TeSBKQnnmbPJAkBU769rpcCtHQO_grJes,15472
51
+ exonware/xwnode/edges/strategies/hnsw.py,sha256=WYlP4W40frMYZPL_C0B7cK0hLb9k1vDh2r4nc3khuvE,23480
52
+ exonware/xwnode/edges/strategies/hop2_labels.py,sha256=OxtebruLCMZ8UvoJIveURJ3RfuupFhHhWb_ZDGSFTBY,16994
53
+ exonware/xwnode/edges/strategies/hyperedge_set.py,sha256=iLHDhEXEKIzFaFOBXsutIyQ49Bzzvb4urqiYqmhsuSY,20762
54
+ exonware/xwnode/edges/strategies/incidence_matrix.py,sha256=X5NsbISJf3sFk1xC5ts-xiF1ARk8F3XnFx9VUBbkGBA,9320
55
+ exonware/xwnode/edges/strategies/k2_tree.py,sha256=DVeIeGWVW8LhCVT7bVtcWcXlfWbWwIhCk6vHr2vMhAs,21652
56
+ exonware/xwnode/edges/strategies/link_cut.py,sha256=F09mBYfPrvGOcDppeb7XDx1dhd4VNC83pjv1lXNtshw,20343
57
+ exonware/xwnode/edges/strategies/multiplex.py,sha256=5lLgVF6sYjkgSWztFmxcdh9M8FTIPDD8O_pxanOhQBo,18641
58
+ exonware/xwnode/edges/strategies/neural_graph.py,sha256=M3tlCOgRH9AnSmz4cuT722FNl2YaBYnlAzmGTHN85kw,25115
59
+ exonware/xwnode/edges/strategies/octree.py,sha256=whjjTOAleqHICjlBsVx6YU6PQbnS2t1rnzukmMHfxxM,25451
60
+ exonware/xwnode/edges/strategies/quadtree.py,sha256=Gb-3a4KIiv7wnwGQwAVdZ2L9dkrCiv_WTVWvzOobO98,22569
61
+ exonware/xwnode/edges/strategies/roaring_adj.py,sha256=dpLBZtteJ9CNDi49oebSy9WsIQ4N0IQQGWEGZEFIgbU,15786
62
+ exonware/xwnode/edges/strategies/rtree.py,sha256=RiLsJ2ojQjiO9zm9VmCfpzziKbUjcRvZSPqOG6-CDyk,33130
63
+ exonware/xwnode/edges/strategies/temporal_edgeset.py,sha256=JPgpGDZ9J1-9aRnMWtUs8CJpI4pZ0qZ3tntZm2-Gymw,22876
64
+ exonware/xwnode/edges/strategies/tree_graph_basic.py,sha256=izAYfY5M0NKwP5PprVuiqnZMYFzFbbCiKG43MeB2j3Q,12339
65
+ exonware/xwnode/edges/strategies/weighted_graph.py,sha256=CHcQ3pDDIg6SGYXsJ4Cj8hkZyNaXbNJlY4nqGwWLSOc,23334
66
+ exonware/xwnode/nodes/strategies/__init__.py,sha256=skancc02CcAVdaTyX3YBeTK5xKMMrbEhLY-0LTnnJGA,1787
67
+ exonware/xwnode/nodes/strategies/adjacency_list.py,sha256=HffWnZgMOhH2fI67_7H8wK7-h4DTt08slKlhgtfeCb8,25245
68
+ exonware/xwnode/nodes/strategies/aho_corasick.py,sha256=nB8WYJvWPX3YUbB2gBfL7YO1evM2LS2zVszC17eWSbk,18673
69
+ exonware/xwnode/nodes/strategies/array_list.py,sha256=rHvj5HfegNDY81oodUYUjWsymey-VNYtIelJb-dd7Eg,8253
70
+ exonware/xwnode/nodes/strategies/art.py,sha256=WZ2Z-I0Dx_4Jpy_AL9E_E2WCJJOCACWXX4ogkIGq8SY,20637
71
+ exonware/xwnode/nodes/strategies/avl_tree.py,sha256=I1bL6PR5u3qnqUhm-S3JVi-HPdYHWQpAHmjB4dKNqKQ,16261
72
+ exonware/xwnode/nodes/strategies/b_plus_tree.py,sha256=5CntWSprQB61w-dvxeyI592An0xlZE0lI2-J585y6lg,20702
73
+ exonware/xwnode/nodes/strategies/b_tree.py,sha256=_YJ1KzdnL8HcR8bLzKB3aYJapNgDozrraiA4JECMZU0,15154
74
+ exonware/xwnode/nodes/strategies/base.py,sha256=dDYBdfJZzke9wlfmZSJSVhyqvCC_xLXPeGaXDEOqc4M,22549
75
+ exonware/xwnode/nodes/strategies/bitmap.py,sha256=b-fcsHVXm35ouqbI0RyWZg5zSjPK8DHLMlqgXAtPNbg,15153
76
+ exonware/xwnode/nodes/strategies/bitset_dynamic.py,sha256=t1sIy0yiV81ifAAbJ5LY6jBhwnrAcGjD4JVyUAt5Ye0,18937
77
+ exonware/xwnode/nodes/strategies/bloom_filter.py,sha256=tZWuOH5DrmOkYPKq4CPzh11GEvnZdSIshaMCv6qiZPI,13749
78
+ exonware/xwnode/nodes/strategies/bloomier_filter.py,sha256=SrnyNe2U4ONULmUUfs1d7UGKHEG6PTBj3ZSzRqmjnP8,17808
79
+ exonware/xwnode/nodes/strategies/bw_tree.py,sha256=zvD5U1NHJ-HqUsYUGJ6LdSn2AvaSjJn6Yduosx4q9wc,19576
80
+ exonware/xwnode/nodes/strategies/contracts.py,sha256=Q0F041lPyigbjrW35JygtylCQHE7lwhh03YQUqAfSRU,3225
81
+ exonware/xwnode/nodes/strategies/count_min_sketch.py,sha256=WHjaVOVOOu8ELMvbqKCLGNkjqDvpAU7IoVhVL-0bqa0,18017
82
+ exonware/xwnode/nodes/strategies/cow_tree.py,sha256=aOwszgEU734RIEQJiDDCSMplii4OE0NRKt1idC4v1xg,21643
83
+ exonware/xwnode/nodes/strategies/crdt_map.py,sha256=LKDh4RF7_AOAO_USwze4Ckcp3A0CP0AQI7EyJu-4vnA,21035
84
+ exonware/xwnode/nodes/strategies/cuckoo_hash.py,sha256=EGBnOH1lPrqUsSZGt3c7gRVzTgxsx-ov1lFitYfWMOI,14950
85
+ exonware/xwnode/nodes/strategies/data_interchange_optimized.py,sha256=-ewKP2WnS3YTkdWi694Jn4tM5kpK2XnpqjoVBYoZObU,15049
86
+ exonware/xwnode/nodes/strategies/dawg.py,sha256=dz9IEZQhBY1HQT5QYLTTpOtxbeQAJYUF9AoR9b9QrsY,28126
87
+ exonware/xwnode/nodes/strategies/deque.py,sha256=89EJcjrSGDXzt_axMVOnTjItfACm5dwfldYK_QWit-k,11866
88
+ exonware/xwnode/nodes/strategies/extendible_hash.py,sha256=IAk5nOGplK2jJv25PQ-22ZvR3awwpSD4snGeDad4nY4,2858
89
+ exonware/xwnode/nodes/strategies/fenwick_tree.py,sha256=Y7LpZsbxYAJ6f08QpmfHafk5Rrah4pzHcPrQR7muyOo,14520
90
+ exonware/xwnode/nodes/strategies/hamt.py,sha256=aw3ohKJfJNs8bk_C7RPCJO49mAouSJg17u9fF6o7TJk,14052
91
+ exonware/xwnode/nodes/strategies/hash_map.py,sha256=SCPKsy4vqu9irZpUe1NKFi-ipg2nGwu07uv62Ozavw0,13408
92
+ exonware/xwnode/nodes/strategies/heap.py,sha256=Id3339pnmYUn_Dh_VWtr9hP251AXoZGQY59mFer1SQc,13567
93
+ exonware/xwnode/nodes/strategies/hopscotch_hash.py,sha256=49SS3c766PcmsdNNxcg1V5Dx681uf89WUU-ku5XShG4,17650
94
+ exonware/xwnode/nodes/strategies/hyperloglog.py,sha256=cosjsuDEjeXmprnUXhaYwYET2p5WtGPvnH2teJO-984,14997
95
+ exonware/xwnode/nodes/strategies/interval_tree.py,sha256=yl2A55QctiYcxMOo2WFK5eBqK6mGRD-47VWA_svkhTc,25276
96
+ exonware/xwnode/nodes/strategies/kd_tree.py,sha256=4PDWVcV-c6Q_WaO-_2_BXnNfYwRfxgDs7Ig0tMDyzNY,23949
97
+ exonware/xwnode/nodes/strategies/learned_index.py,sha256=PEw8_3Nd9Ki8uu4gXZbNFey6y--LZLMRQyimhdvMBuo,19199
98
+ exonware/xwnode/nodes/strategies/linear_hash.py,sha256=xAEoW8PNJIAtrm0TbUEIbO3tEip6wyh8BDjcPF1uKx0,2824
99
+ exonware/xwnode/nodes/strategies/linked_list.py,sha256=yrJx_lo5S6EmZmOxM9fythjou_T9gELC-BE9gYlmRmA,14141
100
+ exonware/xwnode/nodes/strategies/lsm_tree.py,sha256=1kkpGZ4kP7odHtz-hBBVVwGYL1fkM4sIs5ktMEorzIY,22688
101
+ exonware/xwnode/nodes/strategies/masstree.py,sha256=I5khCJIIQSDX9ZETTiUvQAqa1_VEbAw_WAda3pyXI4g,4078
102
+ exonware/xwnode/nodes/strategies/ordered_map.py,sha256=XCEx_9C1S7OtIaoM_CqAlDqBNMOGRCg_RMJ1cAmjBz4,14619
103
+ exonware/xwnode/nodes/strategies/ordered_map_balanced.py,sha256=iSS70TiIMapBz3pJxldLwVsfPe5DyDEwxhZJky_2Bps,20601
104
+ exonware/xwnode/nodes/strategies/patricia.py,sha256=0y829h7INJ6J-LmeW3W2pXA88RFq9V1Dae0Z7ct9sDw,18789
105
+ exonware/xwnode/nodes/strategies/persistent_tree.py,sha256=XwMQk8MB0KtBur5NE3uD3MQ24Xri61Kye75gYMg58bQ,19471
106
+ exonware/xwnode/nodes/strategies/priority_queue.py,sha256=YWEiWTb8yvmUiQLEH-erjlZMTOsyfE12F3PyZl7YrR8,22818
107
+ exonware/xwnode/nodes/strategies/queue.py,sha256=knMVblGwgTE8Yj7bW0z_FALyqKDV65OKQlUezXqd0vI,9684
108
+ exonware/xwnode/nodes/strategies/radix_trie.py,sha256=MXTshSaRFC1vQN-ik9ohzCUVU_q5v5CBJnyO03M_M6g,17235
109
+ exonware/xwnode/nodes/strategies/red_black_tree.py,sha256=Pbo4Au3A35Beg4uXlo4p0_Z6xlolnc_PiLwrSEo3mdc,22705
110
+ exonware/xwnode/nodes/strategies/roaring_bitmap.py,sha256=7HHRZOu76skDi0MldyX7JxEErBjvMokEdn-TdHB2K04,20992
111
+ exonware/xwnode/nodes/strategies/rope.py,sha256=hk-I_5RHKdWY0T8R5dAJeyCHpBbdPk87zFYb58cKlYM,22886
112
+ exonware/xwnode/nodes/strategies/segment_tree.py,sha256=vg0MGCkK6rvTZZN2seZnTE20RSn5bMioljvnA1CjLKk,10553
113
+ exonware/xwnode/nodes/strategies/set_hash.py,sha256=QtEngD-nOBA8kTiaJ1dJshj7YUtNNiyTYHdN9dPokJU,13402
114
+ exonware/xwnode/nodes/strategies/set_tree.py,sha256=ph6D8jbIlYoCNh_7l8tSHHq_lG8X4hNcYVgP4RfDKbI,15957
115
+ exonware/xwnode/nodes/strategies/skip_list.py,sha256=cH_WK91z3fHWRkUa87fkepjxHxoJFfRBVRj1y4cXpAo,14737
116
+ exonware/xwnode/nodes/strategies/sparse_matrix.py,sha256=mxV-4usMb9zIx7LHCrqrLdESq-F8DGWkD71n9SJ_Ymk,17468
117
+ exonware/xwnode/nodes/strategies/splay_tree.py,sha256=09XL2_Mw9oB3EikpQHGvfcEvdM3RCf3ZqRel-O6ZA8E,15158
118
+ exonware/xwnode/nodes/strategies/stack.py,sha256=8D-2JO7INb54bo6A3E-KqLTc6_0Yl2VhX2xe7DkRqys,9789
119
+ exonware/xwnode/nodes/strategies/suffix_array.py,sha256=OOR-tKHfupLpJV8whW3jvLHGzD-swEADXXHaTvKt9So,17139
120
+ exonware/xwnode/nodes/strategies/t_tree.py,sha256=6iE7pf943JCVQoGNQrvnozvAWiVh0JCmTX2IhVbA3Q0,2863
121
+ exonware/xwnode/nodes/strategies/treap.py,sha256=8jcrzwYn87rS850UcofWq6mmeeS9DpZwvVq9nlbJAc4,17252
122
+ exonware/xwnode/nodes/strategies/tree_graph_hybrid.py,sha256=hzwt3XXSW3HR8qQE6LgOSCaai5YBiLlOxS2CAGkE7r0,55462
123
+ exonware/xwnode/nodes/strategies/trie.py,sha256=5SxaV9rHylqUG_HPu5tTrEo_ysftntZl2DSDChmwcNA,13752
124
+ exonware/xwnode/nodes/strategies/union_find.py,sha256=V0QNfVNMf20-F3ylTmMyoMEYw8ZKUiuUFA_P_Fxk_7E,13583
125
+ exonware/xwnode/nodes/strategies/veb_tree.py,sha256=LVankfrVaMFmO5wzcSxbQysRtk3zc2VdHUTiouuappY,27014
126
+ exonware/xwnode/strategies/__init__.py,sha256=9_OmgETRBSn6-D2hQb9wlBe03QcKMRlJ0hnZLTyVtYw,5521
127
+ exonware_xwnode-0.0.1.24.dist-info/METADATA,sha256=kG8p7K0R1e0lihO2n1zwxmzSb74PvFWK2bCM-xiY5Qs,28317
128
+ exonware_xwnode-0.0.1.24.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
129
+ exonware_xwnode-0.0.1.24.dist-info/licenses/LICENSE,sha256=w42ohoEUfhyT0NgiivAL4fWg2AMRLGnfXPMAR4EO-MU,1094
130
+ exonware_xwnode-0.0.1.24.dist-info/RECORD,,
@@ -1,353 +0,0 @@
1
- """
2
- Adjacency List Edge Strategy Implementation
3
-
4
- This module implements the ADJ_LIST strategy for sparse graph representation
5
- with efficient edge addition and neighbor queries.
6
- """
7
-
8
- from typing import Any, Iterator, Dict, List, Set, Optional, Tuple
9
- from collections import defaultdict
10
- from ._base_edge import aEdgeStrategy
11
- from ...defs import EdgeMode, EdgeTrait
12
-
13
-
14
- class xAdjListStrategy(aEdgeStrategy):
15
- """
16
- Adjacency List edge strategy for sparse graph representation.
17
-
18
- Provides O(1) edge addition and O(degree) neighbor queries,
19
- ideal for sparse graphs where most vertices have few connections.
20
- """
21
-
22
- def __init__(self, traits: EdgeTrait = EdgeTrait.NONE, **options):
23
- """Initialize the Adjacency List strategy."""
24
- super().__init__(EdgeMode.ADJ_LIST, traits, **options)
25
-
26
- self.is_directed = options.get('directed', True)
27
- self.allow_self_loops = options.get('self_loops', True)
28
- self.allow_multi_edges = options.get('multi_edges', False)
29
-
30
- # Core storage: vertex -> list of (neighbor, edge_data)
31
- self._outgoing: Dict[str, List[Tuple[str, Dict[str, Any]]]] = defaultdict(list)
32
- self._incoming: Dict[str, List[Tuple[str, Dict[str, Any]]]] = defaultdict(list) if self.is_directed else None
33
-
34
- # Vertex set for fast membership testing
35
- self._vertices: Set[str] = set()
36
-
37
- # Edge properties storage
38
- self._edge_count = 0
39
- self._edge_id_counter = 0
40
-
41
- def get_supported_traits(self) -> EdgeTrait:
42
- """Get the traits supported by the adjacency list strategy."""
43
- return (EdgeTrait.SPARSE | EdgeTrait.DIRECTED | EdgeTrait.WEIGHTED | EdgeTrait.MULTI)
44
-
45
- # ============================================================================
46
- # CORE EDGE OPERATIONS
47
- # ============================================================================
48
-
49
- def add_edge(self, source: str, target: str, **properties) -> str:
50
- """Add an edge between source and target vertices."""
51
- # Validate self-loops
52
- if source == target and not self.allow_self_loops:
53
- raise ValueError(f"Self-loops not allowed: {source} -> {target}")
54
-
55
- # Check for existing edge if multi-edges not allowed
56
- if not self.allow_multi_edges and self.has_edge(source, target):
57
- raise ValueError(f"Multi-edges not allowed: {source} -> {target}")
58
-
59
- # Generate edge ID
60
- edge_id = f"edge_{self._edge_id_counter}"
61
- self._edge_id_counter += 1
62
-
63
- # Create edge data
64
- edge_data = {
65
- 'id': edge_id,
66
- 'source': source,
67
- 'target': target,
68
- 'properties': properties.copy()
69
- }
70
-
71
- # Add vertices to vertex set
72
- self._vertices.add(source)
73
- self._vertices.add(target)
74
-
75
- # Add to outgoing adjacency list
76
- self._outgoing[source].append((target, edge_data))
77
-
78
- # Add to incoming adjacency list (if directed)
79
- if self.is_directed and self._incoming is not None:
80
- self._incoming[target].append((source, edge_data))
81
- elif not self.is_directed:
82
- # For undirected graphs, add reverse edge (unless it's a self-loop)
83
- if source != target:
84
- self._outgoing[target].append((source, edge_data))
85
-
86
- self._edge_count += 1
87
- return edge_id
88
-
89
- def remove_edge(self, source: str, target: str, edge_id: Optional[str] = None) -> bool:
90
- """Remove edge(s) between source and target."""
91
- if source not in self._outgoing:
92
- return False
93
-
94
- removed = False
95
-
96
- # Remove from outgoing list
97
- original_length = len(self._outgoing[source])
98
- if edge_id:
99
- # Remove specific edge by ID
100
- self._outgoing[source] = [
101
- (neighbor, data) for neighbor, data in self._outgoing[source]
102
- if not (neighbor == target and data['id'] == edge_id)
103
- ]
104
- else:
105
- # Remove all edges to target
106
- self._outgoing[source] = [
107
- (neighbor, data) for neighbor, data in self._outgoing[source]
108
- if neighbor != target
109
- ]
110
-
111
- removed = len(self._outgoing[source]) < original_length
112
-
113
- if removed:
114
- self._edge_count -= (original_length - len(self._outgoing[source]))
115
-
116
- # Remove from incoming list (if directed)
117
- if self.is_directed and self._incoming is not None and target in self._incoming:
118
- if edge_id:
119
- self._incoming[target] = [
120
- (neighbor, data) for neighbor, data in self._incoming[target]
121
- if not (neighbor == source and data['id'] == edge_id)
122
- ]
123
- else:
124
- self._incoming[target] = [
125
- (neighbor, data) for neighbor, data in self._incoming[target]
126
- if neighbor != source
127
- ]
128
- elif not self.is_directed and source != target:
129
- # For undirected graphs, remove reverse edge
130
- if target in self._outgoing:
131
- if edge_id:
132
- self._outgoing[target] = [
133
- (neighbor, data) for neighbor, data in self._outgoing[target]
134
- if not (neighbor == source and data['id'] == edge_id)
135
- ]
136
- else:
137
- self._outgoing[target] = [
138
- (neighbor, data) for neighbor, data in self._outgoing[target]
139
- if neighbor != source
140
- ]
141
-
142
- return removed
143
-
144
- def has_edge(self, source: str, target: str) -> bool:
145
- """Check if edge exists between source and target."""
146
- if source not in self._outgoing:
147
- return False
148
-
149
- return any(neighbor == target for neighbor, _ in self._outgoing[source])
150
-
151
- def get_edge_data(self, source: str, target: str) -> Optional[Dict[str, Any]]:
152
- """Get edge data between source and target."""
153
- if source not in self._outgoing:
154
- return None
155
-
156
- for neighbor, data in self._outgoing[source]:
157
- if neighbor == target:
158
- return data
159
-
160
- return None
161
-
162
- def neighbors(self, vertex: str, direction: str = 'out') -> Iterator[str]:
163
- """Get neighbors of a vertex."""
164
- if direction == 'out':
165
- if vertex in self._outgoing:
166
- for neighbor, _ in self._outgoing[vertex]:
167
- yield neighbor
168
- elif direction == 'in':
169
- if self.is_directed and self._incoming is not None and vertex in self._incoming:
170
- for neighbor, _ in self._incoming[vertex]:
171
- yield neighbor
172
- elif not self.is_directed:
173
- # For undirected graphs, incoming = outgoing
174
- if vertex in self._outgoing:
175
- for neighbor, _ in self._outgoing[vertex]:
176
- yield neighbor
177
- elif direction == 'both':
178
- # Get all neighbors (both in and out)
179
- seen = set()
180
- for neighbor in self.neighbors(vertex, 'out'):
181
- if neighbor not in seen:
182
- seen.add(neighbor)
183
- yield neighbor
184
- for neighbor in self.neighbors(vertex, 'in'):
185
- if neighbor not in seen:
186
- seen.add(neighbor)
187
- yield neighbor
188
-
189
- def degree(self, vertex: str, direction: str = 'out') -> int:
190
- """Get degree of a vertex."""
191
- if direction == 'out':
192
- return len(self._outgoing.get(vertex, []))
193
- elif direction == 'in':
194
- if self.is_directed and self._incoming is not None:
195
- return len(self._incoming.get(vertex, []))
196
- elif not self.is_directed:
197
- return len(self._outgoing.get(vertex, []))
198
- else:
199
- return 0
200
- elif direction == 'both':
201
- out_degree = self.degree(vertex, 'out')
202
- in_degree = self.degree(vertex, 'in')
203
- # For undirected graphs, avoid double counting
204
- return out_degree if not self.is_directed else out_degree + in_degree
205
-
206
- def edges(self, data: bool = False) -> Iterator[tuple]:
207
- """Get all edges in the graph."""
208
- seen_edges = set()
209
-
210
- for source, adj_list in self._outgoing.items():
211
- for target, edge_data in adj_list:
212
- edge_key = (source, target, edge_data['id'])
213
-
214
- if edge_key not in seen_edges:
215
- seen_edges.add(edge_key)
216
-
217
- if data:
218
- yield (source, target, edge_data)
219
- else:
220
- yield (source, target)
221
-
222
- def vertices(self) -> Iterator[str]:
223
- """Get all vertices in the graph."""
224
- return iter(self._vertices)
225
-
226
- def __len__(self) -> int:
227
- """Get the number of edges."""
228
- return self._edge_count
229
-
230
- def vertex_count(self) -> int:
231
- """Get the number of vertices."""
232
- return len(self._vertices)
233
-
234
- def clear(self) -> None:
235
- """Clear all edges and vertices."""
236
- self._outgoing.clear()
237
- if self._incoming is not None:
238
- self._incoming.clear()
239
- self._vertices.clear()
240
- self._edge_count = 0
241
- self._edge_id_counter = 0
242
-
243
- def add_vertex(self, vertex: str) -> None:
244
- """Add a vertex to the graph."""
245
- self._vertices.add(vertex)
246
- # Initialize adjacency lists if not present
247
- if vertex not in self._outgoing:
248
- self._outgoing[vertex] = []
249
- if self.is_directed and self._incoming is not None and vertex not in self._incoming:
250
- self._incoming[vertex] = []
251
-
252
- def remove_vertex(self, vertex: str) -> bool:
253
- """Remove a vertex and all its edges."""
254
- if vertex not in self._vertices:
255
- return False
256
-
257
- # Remove all outgoing edges
258
- edges_removed = len(self._outgoing.get(vertex, []))
259
- self._edge_count -= edges_removed
260
-
261
- # Remove all incoming edges
262
- for source in list(self._outgoing.keys()):
263
- if source != vertex:
264
- original_length = len(self._outgoing[source])
265
- self._outgoing[source] = [
266
- (neighbor, data) for neighbor, data in self._outgoing[source]
267
- if neighbor != vertex
268
- ]
269
- self._edge_count -= (original_length - len(self._outgoing[source]))
270
-
271
- # Clean up adjacency lists
272
- if vertex in self._outgoing:
273
- del self._outgoing[vertex]
274
- if self._incoming is not None and vertex in self._incoming:
275
- del self._incoming[vertex]
276
-
277
- # Remove from vertex set
278
- self._vertices.remove(vertex)
279
-
280
- return True
281
-
282
- # ============================================================================
283
- # ADVANCED OPERATIONS
284
- # ============================================================================
285
-
286
- def get_subgraph(self, vertices: Set[str]) -> 'xAdjListStrategy':
287
- """Extract subgraph containing only specified vertices."""
288
- subgraph = xAdjListStrategy(
289
- traits=self._traits,
290
- directed=self.is_directed,
291
- self_loops=self.allow_self_loops,
292
- multi_edges=self.allow_multi_edges
293
- )
294
-
295
- # Add vertices
296
- for vertex in vertices:
297
- if vertex in self._vertices:
298
- subgraph.add_vertex(vertex)
299
-
300
- # Add edges
301
- for source, target, edge_data in self.edges(data=True):
302
- if source in vertices and target in vertices:
303
- subgraph.add_edge(source, target, **edge_data['properties'])
304
-
305
- return subgraph
306
-
307
- def get_edge_list(self) -> List[Tuple[str, str, Dict[str, Any]]]:
308
- """Get all edges as a list."""
309
- return list(self.edges(data=True))
310
-
311
- def get_adjacency_dict(self) -> Dict[str, List[str]]:
312
- """Get adjacency representation as a dictionary."""
313
- return {
314
- vertex: [neighbor for neighbor, _ in adj_list]
315
- for vertex, adj_list in self._outgoing.items()
316
- }
317
-
318
- # ============================================================================
319
- # PERFORMANCE CHARACTERISTICS
320
- # ============================================================================
321
-
322
- @property
323
- def backend_info(self) -> Dict[str, Any]:
324
- """Get backend implementation info."""
325
- return {
326
- 'strategy': 'adjacency_list',
327
- 'backend': 'Python defaultdict + lists',
328
- 'directed': self.is_directed,
329
- 'multi_edges': self.allow_multi_edges,
330
- 'self_loops': self.allow_self_loops,
331
- 'complexity': {
332
- 'add_edge': 'O(1)',
333
- 'remove_edge': 'O(degree)',
334
- 'has_edge': 'O(degree)',
335
- 'neighbors': 'O(degree)',
336
- 'space': 'O(V + E)'
337
- }
338
- }
339
-
340
- @property
341
- def metrics(self) -> Dict[str, Any]:
342
- """Get performance metrics."""
343
- avg_degree = self._edge_count / max(1, len(self._vertices)) if self._vertices else 0
344
- density = self._edge_count / max(1, len(self._vertices) * (len(self._vertices) - 1)) if len(self._vertices) > 1 else 0
345
-
346
- return {
347
- 'vertices': len(self._vertices),
348
- 'edges': self._edge_count,
349
- 'average_degree': round(avg_degree, 2),
350
- 'density': round(density, 4),
351
- 'memory_usage': f"{len(self._vertices) * 48 + self._edge_count * 32} bytes (estimated)",
352
- 'sparsity': f"{(1 - density) * 100:.1f}%"
353
- }