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
@@ -7,8 +7,8 @@ insertions and deletions with sequential access patterns.
7
7
 
8
8
  from typing import Any, Iterator, List, Dict, Optional
9
9
  from .base import ANodeLinearStrategy
10
- from .contracts import NodeType
11
10
  from ...defs import NodeMode, NodeTrait
11
+ from .contracts import NodeType
12
12
 
13
13
 
14
14
  class ListNode:
@@ -26,18 +26,16 @@ class LinkedListStrategy(ANodeLinearStrategy):
26
26
  Linked List node strategy for efficient insertions and deletions.
27
27
 
28
28
  Provides O(1) insertions/deletions at known positions with
29
- sequential access patterns
29
+ sequential access patterns optimized for iteration.
30
+ """
30
31
 
31
32
  # Strategy type classification
32
33
  STRATEGY_TYPE = NodeType.LINEAR
33
- optimized for iteration.
34
- """
34
+
35
35
 
36
36
  def __init__(self, traits: NodeTrait = NodeTrait.NONE, **options):
37
37
  """Initialize the Linked List strategy."""
38
- super().__init__(data=None, **options)
39
- self._mode = NodeMode.LINKED_LIST
40
- self._traits = traits
38
+ super().__init__(NodeMode.LINKED_LIST, traits, **options)
41
39
 
42
40
  self.doubly_linked = options.get('doubly_linked', True)
43
41
 
@@ -55,158 +53,349 @@ optimized for iteration.
55
53
  """Get the traits supported by the linked list strategy."""
56
54
  return (NodeTrait.ORDERED | NodeTrait.INDEXED)
57
55
 
56
+ def _insert_after(self, prev_node: ListNode, key: str, value: Any) -> ListNode:
57
+ """Insert new node after given node."""
58
+ new_node = ListNode(key, value)
59
+ next_node = prev_node.next
60
+
61
+ # Link new node
62
+ prev_node.next = new_node
63
+ new_node.prev = prev_node
64
+ new_node.next = next_node
65
+ next_node.prev = new_node
66
+
67
+ return new_node
68
+
69
+ def _remove_node(self, node: ListNode) -> None:
70
+ """Remove node from list."""
71
+ prev_node = node.prev
72
+ next_node = node.next
73
+
74
+ prev_node.next = next_node
75
+ next_node.prev = prev_node
76
+
77
+ # Clear references
78
+ node.prev = None
79
+ node.next = None
80
+
81
+ def _get_node_at_index(self, index: int) -> Optional[ListNode]:
82
+ """Get node at given index."""
83
+ if index < 0 or index >= self._size:
84
+ return None
85
+
86
+ # Optimize direction based on index
87
+ if index < self._size // 2:
88
+ # Search from head
89
+ current = self._head.next
90
+ for _ in range(index):
91
+ current = current.next
92
+ else:
93
+ # Search from tail
94
+ current = self._tail.prev
95
+ for _ in range(self._size - index - 1):
96
+ current = current.prev
97
+
98
+ return current if current != self._head and current != self._tail else None
99
+
58
100
  # ============================================================================
59
- # CORE OPERATIONS
101
+ # CORE OPERATIONS (Key-based interface for compatibility)
60
102
  # ============================================================================
61
103
 
62
- def insert(self, key: Any, value: Any) -> None:
63
- """Insert key-value pair."""
104
+ def put(self, key: Any, value: Any = None) -> None:
105
+ """Add/update key-value pair."""
64
106
  key_str = str(key)
107
+
65
108
  if key_str in self._key_to_node:
66
109
  # Update existing
67
110
  self._key_to_node[key_str].value = value
68
111
  else:
69
- # Insert new node at end
70
- self._insert_at_end(key_str, value)
112
+ # Insert at end
113
+ new_node = self._insert_after(self._tail.prev, key_str, value)
114
+ self._key_to_node[key_str] = new_node
115
+ self._size += 1
71
116
 
72
- def find(self, key: Any) -> Any:
73
- """Find value by key."""
117
+ def get(self, key: Any, default: Any = None) -> Any:
118
+ """Get value by key."""
74
119
  key_str = str(key)
120
+
121
+ if key_str == "list_info":
122
+ return {
123
+ 'size': self._size,
124
+ 'doubly_linked': self.doubly_linked,
125
+ 'first': self.first(),
126
+ 'last': self.last()
127
+ }
128
+ elif key_str.isdigit():
129
+ # Numeric access by index
130
+ index = int(key_str)
131
+ node = self._get_node_at_index(index)
132
+ return node.value if node else default
133
+
75
134
  node = self._key_to_node.get(key_str)
76
- return node.value if node else None
135
+ return node.value if node else default
77
136
 
78
- def delete(self, key: Any) -> bool:
79
- """Delete by key."""
137
+ def has(self, key: Any) -> bool:
138
+ """Check if key exists."""
80
139
  key_str = str(key)
81
- if key_str in self._key_to_node:
82
- self._remove_node(self._key_to_node[key_str])
140
+
141
+ if key_str == "list_info":
142
+ return True
143
+ elif key_str.isdigit():
144
+ index = int(key_str)
145
+ return 0 <= index < self._size
146
+
147
+ return key_str in self._key_to_node
148
+
149
+ def remove(self, key: Any) -> bool:
150
+ """Remove key from list."""
151
+ key_str = str(key)
152
+
153
+ if key_str.isdigit():
154
+ # Remove by index
155
+ index = int(key_str)
156
+ node = self._get_node_at_index(index)
157
+ if node:
158
+ self._remove_node(node)
159
+ del self._key_to_node[node.key]
160
+ self._size -= 1
161
+ return True
162
+ return False
163
+
164
+ node = self._key_to_node.get(key_str)
165
+ if node:
166
+ self._remove_node(node)
83
167
  del self._key_to_node[key_str]
168
+ self._size -= 1
84
169
  return True
170
+
85
171
  return False
86
172
 
87
- def size(self) -> int:
88
- """Get size."""
89
- return self._size
173
+ def delete(self, key: Any) -> bool:
174
+ """Remove key from list (alias for remove)."""
175
+ return self.remove(key)
90
176
 
91
- def is_empty(self) -> bool:
92
- """Check if empty."""
93
- return self._size == 0
177
+ def clear(self) -> None:
178
+ """Clear all data."""
179
+ self._head.next = self._tail
180
+ self._tail.prev = self._head
181
+ self._key_to_node.clear()
182
+ self._size = 0
94
183
 
95
- def to_native(self) -> List[Any]:
96
- """Convert to native list."""
97
- result = []
184
+ def keys(self) -> Iterator[str]:
185
+ """Get all keys in insertion order."""
186
+ current = self._head.next
187
+ while current != self._tail:
188
+ yield current.key
189
+ current = current.next
190
+
191
+ def values(self) -> Iterator[Any]:
192
+ """Get all values in insertion order."""
98
193
  current = self._head.next
99
194
  while current != self._tail:
100
- result.append(current.value)
195
+ yield current.value
101
196
  current = current.next
102
- return result
197
+
198
+ def items(self) -> Iterator[tuple[str, Any]]:
199
+ """Get all key-value pairs in insertion order."""
200
+ current = self._head.next
201
+ while current != self._tail:
202
+ yield (current.key, current.value)
203
+ current = current.next
204
+
205
+ def __len__(self) -> int:
206
+ """Get number of elements."""
207
+ return self._size
208
+
209
+ def to_native(self) -> List[Any]:
210
+ """Convert to native Python list."""
211
+ return list(self.values())
212
+
213
+ @property
214
+ def is_list(self) -> bool:
215
+ """This is a list strategy."""
216
+ return True
217
+
218
+ @property
219
+ def is_dict(self) -> bool:
220
+ """This also behaves like a dict."""
221
+ return True
103
222
 
104
223
  # ============================================================================
105
- # LINEAR STRATEGY METHODS
224
+ # LINKED LIST SPECIFIC OPERATIONS
106
225
  # ============================================================================
107
226
 
108
- def push_front(self, value: Any) -> None:
109
- """Add element to front."""
110
- self._insert_after(self._head, str(self._size), value)
227
+ def append(self, value: Any) -> str:
228
+ """Append value to end of list."""
229
+ key = str(self._size)
230
+ self.put(key, value)
231
+ return key
232
+
233
+ def prepend(self, value: Any) -> str:
234
+ """Prepend value to beginning of list."""
235
+ key = f"prepend_{self._size}"
236
+ new_node = self._insert_after(self._head, key, value)
237
+ self._key_to_node[key] = new_node
238
+ self._size += 1
239
+ return key
240
+
241
+ def insert_at(self, index: int, value: Any) -> str:
242
+ """Insert value at specific index."""
243
+ if index < 0 or index > self._size:
244
+ raise IndexError(f"Index {index} out of range")
245
+
246
+ if index == 0:
247
+ return self.prepend(value)
248
+ elif index == self._size:
249
+ return self.append(value)
250
+
251
+ # Find insertion point
252
+ prev_node = self._get_node_at_index(index - 1)
253
+ if not prev_node:
254
+ raise IndexError(f"Cannot find insertion point at index {index}")
255
+
256
+ key = f"insert_{index}_{self._size}"
257
+ new_node = self._insert_after(prev_node, key, value)
258
+ self._key_to_node[key] = new_node
259
+ self._size += 1
260
+ return key
261
+
262
+ def insert(self, index: int, value: Any) -> None:
263
+ """Insert value at index."""
264
+ self.insert_at(index, value)
111
265
 
112
266
  def push_back(self, value: Any) -> None:
113
267
  """Add element to back."""
114
- self._insert_before(self._tail, str(self._size), value)
268
+ self.append(value)
115
269
 
116
- def pop_front(self) -> Any:
117
- """Remove element from front."""
118
- if self._size == 0:
119
- raise IndexError("pop from empty list")
120
- first_node = self._head.next
121
- value = first_node.value
122
- self._remove_node(first_node)
123
- return value
270
+ def push_front(self, value: Any) -> None:
271
+ """Add element to front."""
272
+ self.prepend(value)
124
273
 
125
274
  def pop_back(self) -> Any:
126
- """Remove element from back."""
275
+ """Remove and return element from back."""
276
+ return self.pop()
277
+
278
+ def pop_front(self) -> Any:
279
+ """Remove and return element from front."""
280
+ return self.popleft()
281
+
282
+ def pop(self) -> Any:
283
+ """Remove and return last element."""
127
284
  if self._size == 0:
128
285
  raise IndexError("pop from empty list")
286
+
129
287
  last_node = self._tail.prev
130
288
  value = last_node.value
131
289
  self._remove_node(last_node)
290
+ del self._key_to_node[last_node.key]
291
+ self._size -= 1
132
292
  return value
133
293
 
134
- def get_at_index(self, index: int) -> Any:
135
- """Get element at index."""
136
- if index < 0 or index >= self._size:
137
- raise IndexError("list index out of range")
138
-
139
- current = self._head.next
140
- for _ in range(index):
141
- current = current.next
142
- return current.value
143
-
144
- def set_at_index(self, index: int, value: Any) -> None:
145
- """Set element at index."""
146
- if index < 0 or index >= self._size:
147
- raise IndexError("list index out of range")
294
+ def popleft(self) -> Any:
295
+ """Remove and return first element."""
296
+ if self._size == 0:
297
+ raise IndexError("popleft from empty list")
148
298
 
149
- current = self._head.next
150
- for _ in range(index):
151
- current = current.next
152
- current.value = value
153
-
154
- # ============================================================================
155
- # AUTO-3 Phase 1 methods
156
- # ============================================================================
299
+ first_node = self._head.next
300
+ value = first_node.value
301
+ self._remove_node(first_node)
302
+ del self._key_to_node[first_node.key]
303
+ self._size -= 1
304
+ return value
157
305
 
158
- def as_linked_list(self):
159
- """Provide LinkedList behavioral view."""
160
- return self
306
+ def first(self) -> Any:
307
+ """Get first element without removing."""
308
+ if self._size == 0:
309
+ return None
310
+ return self._head.next.value
161
311
 
162
- def as_stack(self):
163
- """Provide Stack behavioral view."""
164
- # TODO: Implement Stack view
165
- return self
312
+ def last(self) -> Any:
313
+ """Get last element without removing."""
314
+ if self._size == 0:
315
+ return None
316
+ return self._tail.prev.value
166
317
 
167
- def as_queue(self):
168
- """Provide Queue behavioral view."""
169
- # TODO: Implement Queue view
170
- return self
318
+ def reverse(self) -> None:
319
+ """Reverse the list in place."""
320
+ if self._size <= 1:
321
+ return
322
+
323
+ # Swap all next/prev pointers
324
+ current = self._head
325
+ while current:
326
+ current.next, current.prev = current.prev, current.next
327
+ current = current.prev # Note: we swapped, so prev is now next
328
+
329
+ # Swap head and tail
330
+ self._head, self._tail = self._tail, self._head
171
331
 
172
- def as_deque(self):
173
- """Provide Deque behavioral view."""
174
- # TODO: Implement Deque view
175
- return self
332
+ def get_at_index(self, index: int) -> Any:
333
+ """Get value at specific index."""
334
+ node = self._get_node_at_index(index)
335
+ if not node:
336
+ raise IndexError(f"Index {index} out of range")
337
+ return node.value
176
338
 
177
- # ============================================================================
178
- # HELPER METHODS
179
- # ============================================================================
339
+ def set_at_index(self, index: int, value: Any) -> None:
340
+ """Set value at specific index."""
341
+ node = self._get_node_at_index(index)
342
+ if not node:
343
+ raise IndexError(f"Index {index} out of range")
344
+ node.value = value
345
+
346
+ def find_index(self, value: Any) -> int:
347
+ """Find index of first occurrence of value."""
348
+ current = self._head.next
349
+ index = 0
350
+
351
+ while current != self._tail:
352
+ if current.value == value:
353
+ return index
354
+ current = current.next
355
+ index += 1
356
+
357
+ return -1
180
358
 
181
- def _insert_at_end(self, key: str, value: Any) -> None:
182
- """Insert new node at the end."""
183
- self._insert_before(self._tail, key, value)
359
+ def remove_value(self, value: Any) -> bool:
360
+ """Remove first occurrence of value."""
361
+ current = self._head.next
362
+
363
+ while current != self._tail:
364
+ if current.value == value:
365
+ self._remove_node(current)
366
+ del self._key_to_node[current.key]
367
+ self._size -= 1
368
+ return True
369
+ current = current.next
370
+
371
+ return False
184
372
 
185
- def _insert_after(self, node: ListNode, key: str, value: Any) -> None:
186
- """Insert new node after specified node."""
187
- new_node = ListNode(key, value)
188
- new_node.next = node.next
189
- new_node.prev = node
190
- node.next.prev = new_node
191
- node.next = new_node
192
- self._key_to_node[key] = new_node
193
- self._size += 1
373
+ def count_value(self, value: Any) -> int:
374
+ """Count occurrences of value."""
375
+ count = 0
376
+ current = self._head.next
377
+
378
+ while current != self._tail:
379
+ if current.value == value:
380
+ count += 1
381
+ current = current.next
382
+
383
+ return count
194
384
 
195
- def _insert_before(self, node: ListNode, key: str, value: Any) -> None:
196
- """Insert new node before specified node."""
197
- new_node = ListNode(key, value)
198
- new_node.prev = node.prev
199
- new_node.next = node
200
- node.prev.next = new_node
201
- node.prev = new_node
202
- self._key_to_node[key] = new_node
203
- self._size += 1
385
+ def to_array(self) -> List[Any]:
386
+ """Convert to array representation."""
387
+ return list(self.values())
204
388
 
205
- def _remove_node(self, node: ListNode) -> None:
206
- """Remove node from list."""
207
- node.prev.next = node.next
208
- node.next.prev = node.prev
209
- self._size -= 1
389
+ def get_statistics(self) -> Dict[str, Any]:
390
+ """Get comprehensive linked list statistics."""
391
+ return {
392
+ 'size': self._size,
393
+ 'doubly_linked': self.doubly_linked,
394
+ 'first_value': self.first(),
395
+ 'last_value': self.last(),
396
+ 'memory_overhead': self._size * (64 if self.doubly_linked else 32), # Pointer overhead
397
+ 'access_pattern': 'sequential'
398
+ }
210
399
 
211
400
  # ============================================================================
212
401
  # PERFORMANCE CHARACTERISTICS
@@ -217,21 +406,29 @@ optimized for iteration.
217
406
  """Get backend implementation info."""
218
407
  return {
219
408
  'strategy': 'LINKED_LIST',
220
- 'backend': 'Doubly linked list',
409
+ 'backend': f'{"Doubly" if self.doubly_linked else "Singly"} linked list with sentinel nodes',
410
+ 'doubly_linked': self.doubly_linked,
221
411
  'complexity': {
222
- 'get': 'O(n)',
223
- 'put': 'O(1)',
224
- 'insert': 'O(1) at known position',
225
- 'delete': 'O(1) at known position',
226
- 'search': 'O(n)'
412
+ 'append': 'O(1)',
413
+ 'prepend': 'O(1)',
414
+ 'insert_at': 'O(n)',
415
+ 'remove_at': 'O(n)',
416
+ 'access_by_index': 'O(n)',
417
+ 'search': 'O(n)',
418
+ 'space': 'O(n)'
227
419
  }
228
420
  }
229
421
 
230
422
  @property
231
423
  def metrics(self) -> Dict[str, Any]:
232
424
  """Get performance metrics."""
425
+ stats = self.get_statistics()
426
+
233
427
  return {
234
- 'size': self._size,
235
- 'memory_usage': f"{self._size * 32} bytes (estimated)",
236
- 'doubly_linked': self.doubly_linked
428
+ 'size': stats['size'],
429
+ 'first_value': str(stats['first_value']) if stats['first_value'] is not None else 'None',
430
+ 'last_value': str(stats['last_value']) if stats['last_value'] is not None else 'None',
431
+ 'doubly_linked': stats['doubly_linked'],
432
+ 'memory_overhead': f"{stats['memory_overhead']} bytes",
433
+ 'access_pattern': stats['access_pattern']
237
434
  }