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.
- exonware/__init__.py +1 -1
- exonware/xwnode/__init__.py +18 -5
- exonware/xwnode/add_strategy_types.py +165 -0
- exonware/xwnode/common/__init__.py +1 -1
- exonware/xwnode/common/graph/__init__.py +30 -0
- exonware/xwnode/common/graph/caching.py +131 -0
- exonware/xwnode/common/graph/contracts.py +100 -0
- exonware/xwnode/common/graph/errors.py +44 -0
- exonware/xwnode/common/graph/indexing.py +260 -0
- exonware/xwnode/common/graph/manager.py +568 -0
- exonware/xwnode/common/management/__init__.py +3 -5
- exonware/xwnode/common/management/manager.py +2 -2
- exonware/xwnode/common/management/migration.py +3 -3
- exonware/xwnode/common/monitoring/__init__.py +3 -5
- exonware/xwnode/common/monitoring/metrics.py +6 -2
- exonware/xwnode/common/monitoring/pattern_detector.py +1 -1
- exonware/xwnode/common/monitoring/performance_monitor.py +5 -1
- exonware/xwnode/common/patterns/__init__.py +3 -5
- exonware/xwnode/common/patterns/flyweight.py +5 -1
- exonware/xwnode/common/patterns/registry.py +202 -183
- exonware/xwnode/common/utils/__init__.py +25 -11
- exonware/xwnode/common/utils/simple.py +1 -1
- exonware/xwnode/config.py +3 -8
- exonware/xwnode/contracts.py +4 -105
- exonware/xwnode/defs.py +413 -159
- exonware/xwnode/edges/strategies/__init__.py +86 -4
- exonware/xwnode/edges/strategies/_base_edge.py +2 -2
- exonware/xwnode/edges/strategies/adj_list.py +287 -121
- exonware/xwnode/edges/strategies/adj_matrix.py +316 -222
- exonware/xwnode/edges/strategies/base.py +1 -1
- exonware/xwnode/edges/strategies/{edge_bidir_wrapper.py → bidir_wrapper.py} +45 -4
- exonware/xwnode/edges/strategies/bitemporal.py +520 -0
- exonware/xwnode/edges/strategies/{edge_block_adj_matrix.py → block_adj_matrix.py} +77 -6
- exonware/xwnode/edges/strategies/bv_graph.py +664 -0
- exonware/xwnode/edges/strategies/compressed_graph.py +217 -0
- exonware/xwnode/edges/strategies/{edge_coo.py → coo.py} +46 -4
- exonware/xwnode/edges/strategies/{edge_csc.py → csc.py} +45 -4
- exonware/xwnode/edges/strategies/{edge_csr.py → csr.py} +94 -12
- exonware/xwnode/edges/strategies/{edge_dynamic_adj_list.py → dynamic_adj_list.py} +46 -4
- exonware/xwnode/edges/strategies/edge_list.py +168 -0
- exonware/xwnode/edges/strategies/edge_property_store.py +2 -2
- exonware/xwnode/edges/strategies/euler_tour.py +560 -0
- exonware/xwnode/edges/strategies/{edge_flow_network.py → flow_network.py} +2 -2
- exonware/xwnode/edges/strategies/graphblas.py +449 -0
- exonware/xwnode/edges/strategies/hnsw.py +637 -0
- exonware/xwnode/edges/strategies/hop2_labels.py +467 -0
- exonware/xwnode/edges/strategies/{edge_hyperedge_set.py → hyperedge_set.py} +2 -2
- exonware/xwnode/edges/strategies/incidence_matrix.py +250 -0
- exonware/xwnode/edges/strategies/k2_tree.py +613 -0
- exonware/xwnode/edges/strategies/link_cut.py +626 -0
- exonware/xwnode/edges/strategies/multiplex.py +532 -0
- exonware/xwnode/edges/strategies/{edge_neural_graph.py → neural_graph.py} +2 -2
- exonware/xwnode/edges/strategies/{edge_octree.py → octree.py} +69 -11
- exonware/xwnode/edges/strategies/{edge_quadtree.py → quadtree.py} +66 -10
- exonware/xwnode/edges/strategies/roaring_adj.py +438 -0
- exonware/xwnode/edges/strategies/{edge_rtree.py → rtree.py} +43 -5
- exonware/xwnode/edges/strategies/{edge_temporal_edgeset.py → temporal_edgeset.py} +24 -5
- exonware/xwnode/edges/strategies/{edge_tree_graph_basic.py → tree_graph_basic.py} +78 -7
- exonware/xwnode/edges/strategies/{edge_weighted_graph.py → weighted_graph.py} +188 -10
- exonware/xwnode/errors.py +3 -6
- exonware/xwnode/facade.py +20 -20
- exonware/xwnode/nodes/strategies/__init__.py +29 -9
- exonware/xwnode/nodes/strategies/adjacency_list.py +650 -177
- exonware/xwnode/nodes/strategies/aho_corasick.py +358 -183
- exonware/xwnode/nodes/strategies/array_list.py +36 -3
- exonware/xwnode/nodes/strategies/art.py +581 -0
- exonware/xwnode/nodes/strategies/{node_avl_tree.py → avl_tree.py} +77 -6
- exonware/xwnode/nodes/strategies/{node_b_plus_tree.py → b_plus_tree.py} +81 -40
- exonware/xwnode/nodes/strategies/{node_btree.py → b_tree.py} +79 -9
- exonware/xwnode/nodes/strategies/base.py +469 -98
- exonware/xwnode/nodes/strategies/{node_bitmap.py → bitmap.py} +12 -12
- exonware/xwnode/nodes/strategies/{node_bitset_dynamic.py → bitset_dynamic.py} +11 -11
- exonware/xwnode/nodes/strategies/{node_bloom_filter.py → bloom_filter.py} +15 -2
- exonware/xwnode/nodes/strategies/bloomier_filter.py +519 -0
- exonware/xwnode/nodes/strategies/bw_tree.py +531 -0
- exonware/xwnode/nodes/strategies/contracts.py +1 -1
- exonware/xwnode/nodes/strategies/{node_count_min_sketch.py → count_min_sketch.py} +3 -2
- exonware/xwnode/nodes/strategies/{node_cow_tree.py → cow_tree.py} +135 -13
- exonware/xwnode/nodes/strategies/crdt_map.py +629 -0
- exonware/xwnode/nodes/strategies/{node_cuckoo_hash.py → cuckoo_hash.py} +2 -2
- exonware/xwnode/nodes/strategies/{node_xdata_optimized.py → data_interchange_optimized.py} +21 -4
- exonware/xwnode/nodes/strategies/dawg.py +876 -0
- exonware/xwnode/nodes/strategies/deque.py +321 -153
- exonware/xwnode/nodes/strategies/extendible_hash.py +93 -0
- exonware/xwnode/nodes/strategies/{node_fenwick_tree.py → fenwick_tree.py} +111 -19
- exonware/xwnode/nodes/strategies/hamt.py +403 -0
- exonware/xwnode/nodes/strategies/hash_map.py +354 -67
- exonware/xwnode/nodes/strategies/heap.py +105 -5
- exonware/xwnode/nodes/strategies/hopscotch_hash.py +525 -0
- exonware/xwnode/nodes/strategies/{node_hyperloglog.py → hyperloglog.py} +6 -5
- exonware/xwnode/nodes/strategies/interval_tree.py +742 -0
- exonware/xwnode/nodes/strategies/kd_tree.py +703 -0
- exonware/xwnode/nodes/strategies/learned_index.py +533 -0
- exonware/xwnode/nodes/strategies/linear_hash.py +93 -0
- exonware/xwnode/nodes/strategies/linked_list.py +316 -119
- exonware/xwnode/nodes/strategies/{node_lsm_tree.py → lsm_tree.py} +219 -15
- exonware/xwnode/nodes/strategies/masstree.py +130 -0
- exonware/xwnode/nodes/strategies/{node_persistent_tree.py → persistent_tree.py} +149 -9
- exonware/xwnode/nodes/strategies/priority_queue.py +544 -132
- exonware/xwnode/nodes/strategies/queue.py +249 -120
- exonware/xwnode/nodes/strategies/{node_red_black_tree.py → red_black_tree.py} +183 -72
- exonware/xwnode/nodes/strategies/{node_roaring_bitmap.py → roaring_bitmap.py} +19 -6
- exonware/xwnode/nodes/strategies/rope.py +717 -0
- exonware/xwnode/nodes/strategies/{node_segment_tree.py → segment_tree.py} +106 -106
- exonware/xwnode/nodes/strategies/{node_set_hash.py → set_hash.py} +30 -29
- exonware/xwnode/nodes/strategies/{node_skip_list.py → skip_list.py} +74 -6
- exonware/xwnode/nodes/strategies/sparse_matrix.py +427 -131
- exonware/xwnode/nodes/strategies/{node_splay_tree.py → splay_tree.py} +55 -6
- exonware/xwnode/nodes/strategies/stack.py +244 -112
- exonware/xwnode/nodes/strategies/{node_suffix_array.py → suffix_array.py} +5 -1
- exonware/xwnode/nodes/strategies/t_tree.py +94 -0
- exonware/xwnode/nodes/strategies/{node_treap.py → treap.py} +75 -6
- exonware/xwnode/nodes/strategies/{node_tree_graph_hybrid.py → tree_graph_hybrid.py} +46 -5
- exonware/xwnode/nodes/strategies/trie.py +153 -9
- exonware/xwnode/nodes/strategies/union_find.py +111 -5
- exonware/xwnode/nodes/strategies/veb_tree.py +856 -0
- exonware/xwnode/strategies/__init__.py +5 -51
- exonware/xwnode/version.py +3 -3
- exonware_xwnode-0.0.1.24.dist-info/METADATA +900 -0
- exonware_xwnode-0.0.1.24.dist-info/RECORD +130 -0
- exonware/xwnode/edges/strategies/edge_adj_list.py +0 -353
- exonware/xwnode/edges/strategies/edge_adj_matrix.py +0 -445
- exonware/xwnode/nodes/strategies/_base_node.py +0 -307
- exonware/xwnode/nodes/strategies/node_aho_corasick.py +0 -525
- exonware/xwnode/nodes/strategies/node_array_list.py +0 -179
- exonware/xwnode/nodes/strategies/node_hash_map.py +0 -273
- exonware/xwnode/nodes/strategies/node_heap.py +0 -196
- exonware/xwnode/nodes/strategies/node_linked_list.py +0 -413
- exonware/xwnode/nodes/strategies/node_trie.py +0 -257
- exonware/xwnode/nodes/strategies/node_union_find.py +0 -192
- exonware/xwnode/queries/executors/__init__.py +0 -47
- exonware/xwnode/queries/executors/advanced/__init__.py +0 -37
- exonware/xwnode/queries/executors/advanced/aggregate_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/ask_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/construct_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/describe_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/for_loop_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/foreach_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/join_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/let_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/mutation_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/options_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/pipe_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/subscribe_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/subscription_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/union_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/window_executor.py +0 -51
- exonware/xwnode/queries/executors/advanced/with_cte_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/__init__.py +0 -21
- exonware/xwnode/queries/executors/aggregation/avg_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/count_executor.py +0 -38
- exonware/xwnode/queries/executors/aggregation/distinct_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/group_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/having_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/max_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/min_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/sum_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/summarize_executor.py +0 -50
- exonware/xwnode/queries/executors/array/__init__.py +0 -9
- exonware/xwnode/queries/executors/array/indexing_executor.py +0 -51
- exonware/xwnode/queries/executors/array/slicing_executor.py +0 -51
- exonware/xwnode/queries/executors/base.py +0 -257
- exonware/xwnode/queries/executors/capability_checker.py +0 -204
- exonware/xwnode/queries/executors/contracts.py +0 -166
- exonware/xwnode/queries/executors/core/__init__.py +0 -17
- exonware/xwnode/queries/executors/core/create_executor.py +0 -96
- exonware/xwnode/queries/executors/core/delete_executor.py +0 -99
- exonware/xwnode/queries/executors/core/drop_executor.py +0 -100
- exonware/xwnode/queries/executors/core/insert_executor.py +0 -39
- exonware/xwnode/queries/executors/core/select_executor.py +0 -152
- exonware/xwnode/queries/executors/core/update_executor.py +0 -102
- exonware/xwnode/queries/executors/data/__init__.py +0 -13
- exonware/xwnode/queries/executors/data/alter_executor.py +0 -50
- exonware/xwnode/queries/executors/data/load_executor.py +0 -50
- exonware/xwnode/queries/executors/data/merge_executor.py +0 -50
- exonware/xwnode/queries/executors/data/store_executor.py +0 -50
- exonware/xwnode/queries/executors/defs.py +0 -93
- exonware/xwnode/queries/executors/engine.py +0 -221
- exonware/xwnode/queries/executors/errors.py +0 -68
- exonware/xwnode/queries/executors/filtering/__init__.py +0 -25
- exonware/xwnode/queries/executors/filtering/between_executor.py +0 -80
- exonware/xwnode/queries/executors/filtering/filter_executor.py +0 -79
- exonware/xwnode/queries/executors/filtering/has_executor.py +0 -70
- exonware/xwnode/queries/executors/filtering/in_executor.py +0 -70
- exonware/xwnode/queries/executors/filtering/like_executor.py +0 -76
- exonware/xwnode/queries/executors/filtering/optional_executor.py +0 -76
- exonware/xwnode/queries/executors/filtering/range_executor.py +0 -80
- exonware/xwnode/queries/executors/filtering/term_executor.py +0 -77
- exonware/xwnode/queries/executors/filtering/values_executor.py +0 -71
- exonware/xwnode/queries/executors/filtering/where_executor.py +0 -44
- exonware/xwnode/queries/executors/graph/__init__.py +0 -15
- exonware/xwnode/queries/executors/graph/in_traverse_executor.py +0 -51
- exonware/xwnode/queries/executors/graph/match_executor.py +0 -51
- exonware/xwnode/queries/executors/graph/out_executor.py +0 -51
- exonware/xwnode/queries/executors/graph/path_executor.py +0 -51
- exonware/xwnode/queries/executors/graph/return_executor.py +0 -51
- exonware/xwnode/queries/executors/ordering/__init__.py +0 -9
- exonware/xwnode/queries/executors/ordering/by_executor.py +0 -50
- exonware/xwnode/queries/executors/ordering/order_executor.py +0 -51
- exonware/xwnode/queries/executors/projection/__init__.py +0 -9
- exonware/xwnode/queries/executors/projection/extend_executor.py +0 -50
- exonware/xwnode/queries/executors/projection/project_executor.py +0 -50
- exonware/xwnode/queries/executors/registry.py +0 -173
- exonware/xwnode/queries/parsers/__init__.py +0 -26
- exonware/xwnode/queries/parsers/base.py +0 -86
- exonware/xwnode/queries/parsers/contracts.py +0 -46
- exonware/xwnode/queries/parsers/errors.py +0 -53
- exonware/xwnode/queries/parsers/sql_param_extractor.py +0 -318
- exonware/xwnode/queries/strategies/__init__.py +0 -24
- exonware/xwnode/queries/strategies/base.py +0 -236
- exonware/xwnode/queries/strategies/cql.py +0 -201
- exonware/xwnode/queries/strategies/cypher.py +0 -181
- exonware/xwnode/queries/strategies/datalog.py +0 -70
- exonware/xwnode/queries/strategies/elastic_dsl.py +0 -70
- exonware/xwnode/queries/strategies/eql.py +0 -70
- exonware/xwnode/queries/strategies/flux.py +0 -70
- exonware/xwnode/queries/strategies/gql.py +0 -70
- exonware/xwnode/queries/strategies/graphql.py +0 -240
- exonware/xwnode/queries/strategies/gremlin.py +0 -181
- exonware/xwnode/queries/strategies/hiveql.py +0 -214
- exonware/xwnode/queries/strategies/hql.py +0 -70
- exonware/xwnode/queries/strategies/jmespath.py +0 -219
- exonware/xwnode/queries/strategies/jq.py +0 -66
- exonware/xwnode/queries/strategies/json_query.py +0 -66
- exonware/xwnode/queries/strategies/jsoniq.py +0 -248
- exonware/xwnode/queries/strategies/kql.py +0 -70
- exonware/xwnode/queries/strategies/linq.py +0 -238
- exonware/xwnode/queries/strategies/logql.py +0 -70
- exonware/xwnode/queries/strategies/mql.py +0 -68
- exonware/xwnode/queries/strategies/n1ql.py +0 -210
- exonware/xwnode/queries/strategies/partiql.py +0 -70
- exonware/xwnode/queries/strategies/pig.py +0 -215
- exonware/xwnode/queries/strategies/promql.py +0 -70
- exonware/xwnode/queries/strategies/sparql.py +0 -220
- exonware/xwnode/queries/strategies/sql.py +0 -275
- exonware/xwnode/queries/strategies/xml_query.py +0 -66
- exonware/xwnode/queries/strategies/xpath.py +0 -223
- exonware/xwnode/queries/strategies/xquery.py +0 -258
- exonware/xwnode/queries/strategies/xwnode_executor.py +0 -332
- exonware/xwnode/queries/strategies/xwquery.py +0 -456
- exonware_xwnode-0.0.1.22.dist-info/METADATA +0 -168
- exonware_xwnode-0.0.1.22.dist-info/RECORD +0 -214
- /exonware/xwnode/nodes/strategies/{node_ordered_map.py → ordered_map.py} +0 -0
- /exonware/xwnode/nodes/strategies/{node_ordered_map_balanced.py → ordered_map_balanced.py} +0 -0
- /exonware/xwnode/nodes/strategies/{node_patricia.py → patricia.py} +0 -0
- /exonware/xwnode/nodes/strategies/{node_radix_trie.py → radix_trie.py} +0 -0
- /exonware/xwnode/nodes/strategies/{node_set_tree.py → set_tree.py} +0 -0
- {exonware_xwnode-0.0.1.22.dist-info → exonware_xwnode-0.0.1.24.dist-info}/WHEEL +0 -0
- {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
|
-
}
|