exonware-xwnode 0.0.1.12__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 (132) hide show
  1. exonware/__init__.py +14 -0
  2. exonware/xwnode/__init__.py +127 -0
  3. exonware/xwnode/base.py +676 -0
  4. exonware/xwnode/config.py +178 -0
  5. exonware/xwnode/contracts.py +730 -0
  6. exonware/xwnode/errors.py +503 -0
  7. exonware/xwnode/facade.py +460 -0
  8. exonware/xwnode/strategies/__init__.py +158 -0
  9. exonware/xwnode/strategies/advisor.py +463 -0
  10. exonware/xwnode/strategies/edges/__init__.py +32 -0
  11. exonware/xwnode/strategies/edges/adj_list.py +227 -0
  12. exonware/xwnode/strategies/edges/adj_matrix.py +391 -0
  13. exonware/xwnode/strategies/edges/base.py +169 -0
  14. exonware/xwnode/strategies/flyweight.py +328 -0
  15. exonware/xwnode/strategies/impls/__init__.py +13 -0
  16. exonware/xwnode/strategies/impls/_base_edge.py +403 -0
  17. exonware/xwnode/strategies/impls/_base_node.py +307 -0
  18. exonware/xwnode/strategies/impls/edge_adj_list.py +353 -0
  19. exonware/xwnode/strategies/impls/edge_adj_matrix.py +445 -0
  20. exonware/xwnode/strategies/impls/edge_bidir_wrapper.py +455 -0
  21. exonware/xwnode/strategies/impls/edge_block_adj_matrix.py +539 -0
  22. exonware/xwnode/strategies/impls/edge_coo.py +533 -0
  23. exonware/xwnode/strategies/impls/edge_csc.py +447 -0
  24. exonware/xwnode/strategies/impls/edge_csr.py +492 -0
  25. exonware/xwnode/strategies/impls/edge_dynamic_adj_list.py +503 -0
  26. exonware/xwnode/strategies/impls/edge_flow_network.py +555 -0
  27. exonware/xwnode/strategies/impls/edge_hyperedge_set.py +516 -0
  28. exonware/xwnode/strategies/impls/edge_neural_graph.py +650 -0
  29. exonware/xwnode/strategies/impls/edge_octree.py +574 -0
  30. exonware/xwnode/strategies/impls/edge_property_store.py +655 -0
  31. exonware/xwnode/strategies/impls/edge_quadtree.py +519 -0
  32. exonware/xwnode/strategies/impls/edge_rtree.py +820 -0
  33. exonware/xwnode/strategies/impls/edge_temporal_edgeset.py +558 -0
  34. exonware/xwnode/strategies/impls/edge_tree_graph_basic.py +271 -0
  35. exonware/xwnode/strategies/impls/edge_weighted_graph.py +411 -0
  36. exonware/xwnode/strategies/manager.py +775 -0
  37. exonware/xwnode/strategies/metrics.py +538 -0
  38. exonware/xwnode/strategies/migration.py +432 -0
  39. exonware/xwnode/strategies/nodes/__init__.py +50 -0
  40. exonware/xwnode/strategies/nodes/_base_node.py +307 -0
  41. exonware/xwnode/strategies/nodes/adjacency_list.py +267 -0
  42. exonware/xwnode/strategies/nodes/aho_corasick.py +345 -0
  43. exonware/xwnode/strategies/nodes/array_list.py +209 -0
  44. exonware/xwnode/strategies/nodes/base.py +247 -0
  45. exonware/xwnode/strategies/nodes/deque.py +200 -0
  46. exonware/xwnode/strategies/nodes/hash_map.py +135 -0
  47. exonware/xwnode/strategies/nodes/heap.py +307 -0
  48. exonware/xwnode/strategies/nodes/linked_list.py +232 -0
  49. exonware/xwnode/strategies/nodes/node_aho_corasick.py +520 -0
  50. exonware/xwnode/strategies/nodes/node_array_list.py +175 -0
  51. exonware/xwnode/strategies/nodes/node_avl_tree.py +371 -0
  52. exonware/xwnode/strategies/nodes/node_b_plus_tree.py +542 -0
  53. exonware/xwnode/strategies/nodes/node_bitmap.py +420 -0
  54. exonware/xwnode/strategies/nodes/node_bitset_dynamic.py +513 -0
  55. exonware/xwnode/strategies/nodes/node_bloom_filter.py +347 -0
  56. exonware/xwnode/strategies/nodes/node_btree.py +357 -0
  57. exonware/xwnode/strategies/nodes/node_count_min_sketch.py +470 -0
  58. exonware/xwnode/strategies/nodes/node_cow_tree.py +473 -0
  59. exonware/xwnode/strategies/nodes/node_cuckoo_hash.py +392 -0
  60. exonware/xwnode/strategies/nodes/node_fenwick_tree.py +301 -0
  61. exonware/xwnode/strategies/nodes/node_hash_map.py +269 -0
  62. exonware/xwnode/strategies/nodes/node_heap.py +191 -0
  63. exonware/xwnode/strategies/nodes/node_hyperloglog.py +407 -0
  64. exonware/xwnode/strategies/nodes/node_linked_list.py +409 -0
  65. exonware/xwnode/strategies/nodes/node_lsm_tree.py +400 -0
  66. exonware/xwnode/strategies/nodes/node_ordered_map.py +390 -0
  67. exonware/xwnode/strategies/nodes/node_ordered_map_balanced.py +565 -0
  68. exonware/xwnode/strategies/nodes/node_patricia.py +512 -0
  69. exonware/xwnode/strategies/nodes/node_persistent_tree.py +378 -0
  70. exonware/xwnode/strategies/nodes/node_radix_trie.py +452 -0
  71. exonware/xwnode/strategies/nodes/node_red_black_tree.py +497 -0
  72. exonware/xwnode/strategies/nodes/node_roaring_bitmap.py +570 -0
  73. exonware/xwnode/strategies/nodes/node_segment_tree.py +289 -0
  74. exonware/xwnode/strategies/nodes/node_set_hash.py +354 -0
  75. exonware/xwnode/strategies/nodes/node_set_tree.py +480 -0
  76. exonware/xwnode/strategies/nodes/node_skip_list.py +316 -0
  77. exonware/xwnode/strategies/nodes/node_splay_tree.py +393 -0
  78. exonware/xwnode/strategies/nodes/node_suffix_array.py +487 -0
  79. exonware/xwnode/strategies/nodes/node_treap.py +387 -0
  80. exonware/xwnode/strategies/nodes/node_tree_graph_hybrid.py +1434 -0
  81. exonware/xwnode/strategies/nodes/node_trie.py +252 -0
  82. exonware/xwnode/strategies/nodes/node_union_find.py +187 -0
  83. exonware/xwnode/strategies/nodes/node_xdata_optimized.py +369 -0
  84. exonware/xwnode/strategies/nodes/priority_queue.py +209 -0
  85. exonware/xwnode/strategies/nodes/queue.py +161 -0
  86. exonware/xwnode/strategies/nodes/sparse_matrix.py +206 -0
  87. exonware/xwnode/strategies/nodes/stack.py +152 -0
  88. exonware/xwnode/strategies/nodes/trie.py +274 -0
  89. exonware/xwnode/strategies/nodes/union_find.py +283 -0
  90. exonware/xwnode/strategies/pattern_detector.py +603 -0
  91. exonware/xwnode/strategies/performance_monitor.py +487 -0
  92. exonware/xwnode/strategies/queries/__init__.py +24 -0
  93. exonware/xwnode/strategies/queries/base.py +236 -0
  94. exonware/xwnode/strategies/queries/cql.py +201 -0
  95. exonware/xwnode/strategies/queries/cypher.py +181 -0
  96. exonware/xwnode/strategies/queries/datalog.py +70 -0
  97. exonware/xwnode/strategies/queries/elastic_dsl.py +70 -0
  98. exonware/xwnode/strategies/queries/eql.py +70 -0
  99. exonware/xwnode/strategies/queries/flux.py +70 -0
  100. exonware/xwnode/strategies/queries/gql.py +70 -0
  101. exonware/xwnode/strategies/queries/graphql.py +240 -0
  102. exonware/xwnode/strategies/queries/gremlin.py +181 -0
  103. exonware/xwnode/strategies/queries/hiveql.py +214 -0
  104. exonware/xwnode/strategies/queries/hql.py +70 -0
  105. exonware/xwnode/strategies/queries/jmespath.py +219 -0
  106. exonware/xwnode/strategies/queries/jq.py +66 -0
  107. exonware/xwnode/strategies/queries/json_query.py +66 -0
  108. exonware/xwnode/strategies/queries/jsoniq.py +248 -0
  109. exonware/xwnode/strategies/queries/kql.py +70 -0
  110. exonware/xwnode/strategies/queries/linq.py +238 -0
  111. exonware/xwnode/strategies/queries/logql.py +70 -0
  112. exonware/xwnode/strategies/queries/mql.py +68 -0
  113. exonware/xwnode/strategies/queries/n1ql.py +210 -0
  114. exonware/xwnode/strategies/queries/partiql.py +70 -0
  115. exonware/xwnode/strategies/queries/pig.py +215 -0
  116. exonware/xwnode/strategies/queries/promql.py +70 -0
  117. exonware/xwnode/strategies/queries/sparql.py +220 -0
  118. exonware/xwnode/strategies/queries/sql.py +275 -0
  119. exonware/xwnode/strategies/queries/xml_query.py +66 -0
  120. exonware/xwnode/strategies/queries/xpath.py +223 -0
  121. exonware/xwnode/strategies/queries/xquery.py +258 -0
  122. exonware/xwnode/strategies/queries/xwnode_executor.py +332 -0
  123. exonware/xwnode/strategies/queries/xwquery_strategy.py +424 -0
  124. exonware/xwnode/strategies/registry.py +604 -0
  125. exonware/xwnode/strategies/simple.py +273 -0
  126. exonware/xwnode/strategies/utils.py +532 -0
  127. exonware/xwnode/types.py +912 -0
  128. exonware/xwnode/version.py +78 -0
  129. exonware_xwnode-0.0.1.12.dist-info/METADATA +169 -0
  130. exonware_xwnode-0.0.1.12.dist-info/RECORD +132 -0
  131. exonware_xwnode-0.0.1.12.dist-info/WHEEL +4 -0
  132. exonware_xwnode-0.0.1.12.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,307 @@
1
+ """
2
+ Heap Node Strategy Implementation
3
+
4
+ This module implements the HEAP strategy for priority queue operations.
5
+ """
6
+
7
+ import heapq
8
+ from typing import Any, Iterator, List, Optional, Dict
9
+ from .base import ANodeTreeStrategy
10
+ from ...types import NodeMode, NodeTrait
11
+
12
+
13
+ class MinHeap:
14
+ """Min heap implementation."""
15
+
16
+ def __init__(self, max_heap: bool = False):
17
+ self._heap = []
18
+ self._max_heap = max_heap
19
+ self._counter = 0 # For stable sorting
20
+
21
+ def push(self, priority: float, value: Any) -> None:
22
+ """Push item with priority."""
23
+ if self._max_heap:
24
+ priority = -priority
25
+ heapq.heappush(self._heap, (priority, self._counter, value))
26
+ self._counter += 1
27
+
28
+ def pop(self) -> Any:
29
+ """Pop item with highest priority."""
30
+ if not self._heap:
31
+ raise IndexError("pop from empty heap")
32
+ priority, _, value = heapq.heappop(self._heap)
33
+ return value
34
+
35
+ def peek(self) -> Any:
36
+ """Peek at highest priority item."""
37
+ if not self._heap:
38
+ raise IndexError("peek from empty heap")
39
+ return self._heap[0][2]
40
+
41
+ def size(self) -> int:
42
+ """Get heap size."""
43
+ return len(self._heap)
44
+
45
+ def is_empty(self) -> bool:
46
+ """Check if heap is empty."""
47
+ return len(self._heap) == 0
48
+
49
+
50
+ class xHeapStrategy(ANodeTreeStrategy):
51
+ """
52
+ Heap node strategy for priority queue operations.
53
+
54
+ Optimized for push, pop, and peek operations with configurable min/max behavior.
55
+ """
56
+
57
+ def __init__(self, traits: NodeTrait = NodeTrait.NONE, **options):
58
+ """Initialize the heap strategy."""
59
+ super().__init__(data=None, **options)
60
+ self._mode = NodeMode.HEAP
61
+ self._traits = traits
62
+ self._is_max_heap = options.get('max_heap', False)
63
+ self._heap = MinHeap(max_heap=self._is_max_heap)
64
+ self._size = 0
65
+
66
+ def get_supported_traits(self) -> NodeTrait:
67
+ """Get the traits supported by the heap strategy."""
68
+ return (NodeTrait.ORDERED | NodeTrait.PRIORITY_QUEUE)
69
+
70
+ # ============================================================================
71
+ # CORE OPERATIONS
72
+ # ============================================================================
73
+
74
+ def insert(self, key: Any, value: Any) -> None:
75
+ """Store a key-value pair (key is priority, value is data)."""
76
+ priority = float(key) if key is not None else 0.0
77
+ data = value if value is not None else key
78
+ self._heap.push(priority, data)
79
+ self._size += 1
80
+
81
+ def find(self, key: Any) -> Any:
82
+ """Find value by priority (not efficient for heaps)."""
83
+ # Heaps don't support efficient lookup by priority
84
+ # This is a limitation of the heap data structure
85
+ return None
86
+
87
+ def delete(self, key: Any) -> bool:
88
+ """Delete by priority (not efficient for heaps)."""
89
+ # Heaps don't support efficient deletion by priority
90
+ # This is a limitation of the heap data structure
91
+ return False
92
+
93
+ def size(self) -> int:
94
+ """Get the number of items."""
95
+ return self._size
96
+
97
+ def is_empty(self) -> bool:
98
+ """Check if the structure is empty."""
99
+ return self._size == 0
100
+
101
+ def to_native(self) -> List[Any]:
102
+ """Convert to native Python list."""
103
+ # Return all values in priority order
104
+ result = []
105
+ temp_heap = MinHeap(max_heap=self._is_max_heap)
106
+
107
+ # Copy heap and extract all values
108
+ for item in self._heap._heap:
109
+ priority, counter, value = item
110
+ temp_heap._heap.append(item)
111
+
112
+ while not temp_heap.is_empty():
113
+ result.append(temp_heap.pop())
114
+
115
+ return result
116
+
117
+ # ============================================================================
118
+ # TREE STRATEGY METHODS
119
+ # ============================================================================
120
+
121
+ def traverse(self, order: str = 'inorder') -> List[Any]:
122
+ """Traverse heap in priority order."""
123
+ return self.to_native()
124
+
125
+ def get_min(self) -> Any:
126
+ """Get minimum priority item."""
127
+ if self._is_max_heap:
128
+ return None # No min in max heap
129
+ return self._heap.peek() if not self._heap.is_empty() else None
130
+
131
+ def get_max(self) -> Any:
132
+ """Get maximum priority item."""
133
+ if not self._is_max_heap:
134
+ return None # No max in min heap
135
+ return self._heap.peek() if not self._heap.is_empty() else None
136
+
137
+ # ============================================================================
138
+ # AUTO-3 Phase 2 methods
139
+ # ============================================================================
140
+
141
+ def as_trie(self):
142
+ """Provide Trie behavioral view."""
143
+ # TODO: Implement Trie view
144
+ return self
145
+
146
+ def as_heap(self):
147
+ """Provide Heap behavioral view."""
148
+ return self
149
+
150
+ def as_skip_list(self):
151
+ """Provide SkipList behavioral view."""
152
+ # TODO: Implement SkipList view
153
+ return self
154
+
155
+ # ============================================================================
156
+ # HEAP SPECIFIC OPERATIONS
157
+ # ============================================================================
158
+
159
+ def push(self, value: Any, priority: float = None) -> str:
160
+ """Push a value with optional priority."""
161
+ if priority is None:
162
+ priority = float(value) if isinstance(value, (int, float)) else 0.0
163
+ self._heap.push(priority, value)
164
+ self._size += 1
165
+ return str(priority)
166
+
167
+ def pop(self) -> Any:
168
+ """Remove and return highest priority item."""
169
+ if self._heap.is_empty():
170
+ raise IndexError("pop from empty heap")
171
+ value = self._heap.pop()
172
+ self._size -= 1
173
+ return value
174
+
175
+ def peek(self) -> Any:
176
+ """Get highest priority item without removing."""
177
+ if self._heap.is_empty():
178
+ raise IndexError("peek from empty heap")
179
+ return self._heap.peek()
180
+
181
+ def peek_priority(self) -> float:
182
+ """Get priority of highest priority item."""
183
+ if self._heap.is_empty():
184
+ raise IndexError("peek from empty heap")
185
+ # This is a simplified implementation
186
+ return 0.0
187
+
188
+ def pushpop(self, value: Any, priority: float = None) -> Any:
189
+ """Push value and pop highest priority item."""
190
+ if priority is None:
191
+ priority = float(value) if isinstance(value, (int, float)) else 0.0
192
+
193
+ if self._heap.is_empty():
194
+ self._heap.push(priority, value)
195
+ return None
196
+
197
+ # Push new value
198
+ self._heap.push(priority, value)
199
+ # Pop highest priority
200
+ return self._heap.pop()
201
+
202
+ def replace(self, value: Any, priority: float = None) -> Any:
203
+ """Replace highest priority item with new value."""
204
+ if self._heap.is_empty():
205
+ raise IndexError("replace from empty heap")
206
+
207
+ if priority is None:
208
+ priority = float(value) if isinstance(value, (int, float)) else 0.0
209
+
210
+ # Pop current highest
211
+ old_value = self._heap.pop()
212
+ # Push new value
213
+ self._heap.push(priority, value)
214
+
215
+ return old_value
216
+
217
+ def heapify(self) -> None:
218
+ """Heapify the heap (already maintained)."""
219
+ # Heap is already heapified
220
+ pass
221
+
222
+ def nlargest(self, n: int) -> List[Any]:
223
+ """Get n largest items."""
224
+ if self._is_max_heap:
225
+ # For max heap, get first n items
226
+ result = []
227
+ temp_heap = MinHeap(max_heap=True)
228
+
229
+ # Copy heap
230
+ for item in self._heap._heap:
231
+ temp_heap._heap.append(item)
232
+
233
+ for _ in range(min(n, self._size)):
234
+ if temp_heap.is_empty():
235
+ break
236
+ result.append(temp_heap.pop())
237
+
238
+ return result
239
+ else:
240
+ # For min heap, this is not efficient
241
+ return []
242
+
243
+ def nsmallest(self, n: int) -> List[Any]:
244
+ """Get n smallest items."""
245
+ if not self._is_max_heap:
246
+ # For min heap, get first n items
247
+ result = []
248
+ temp_heap = MinHeap(max_heap=False)
249
+
250
+ # Copy heap
251
+ for item in self._heap._heap:
252
+ temp_heap._heap.append(item)
253
+
254
+ for _ in range(min(n, self._size)):
255
+ if temp_heap.is_empty():
256
+ break
257
+ result.append(temp_heap.pop())
258
+
259
+ return result
260
+ else:
261
+ # For max heap, this is not efficient
262
+ return []
263
+
264
+ # ============================================================================
265
+ # ITERATION
266
+ # ============================================================================
267
+
268
+ def keys(self) -> Iterator[str]:
269
+ """Get all priorities as strings."""
270
+ # This is not efficient for heaps
271
+ return iter([])
272
+
273
+ def values(self) -> Iterator[Any]:
274
+ """Get all values."""
275
+ return iter(self.to_native())
276
+
277
+ def items(self) -> Iterator[tuple[str, Any]]:
278
+ """Get all priority-value pairs."""
279
+ # This is not efficient for heaps
280
+ return iter([])
281
+
282
+ # ============================================================================
283
+ # PERFORMANCE CHARACTERISTICS
284
+ # ============================================================================
285
+
286
+ @property
287
+ def backend_info(self) -> Dict[str, Any]:
288
+ """Get backend implementation info."""
289
+ return {
290
+ 'strategy': 'HEAP',
291
+ 'backend': 'Python heapq',
292
+ 'complexity': {
293
+ 'push': 'O(log n)',
294
+ 'pop': 'O(log n)',
295
+ 'peek': 'O(1)',
296
+ 'heapify': 'O(n)'
297
+ }
298
+ }
299
+
300
+ @property
301
+ def metrics(self) -> Dict[str, Any]:
302
+ """Get performance metrics."""
303
+ return {
304
+ 'size': self._size,
305
+ 'is_max_heap': self._is_max_heap,
306
+ 'memory_usage': f"{self._size * 24} bytes (estimated)"
307
+ }
@@ -0,0 +1,232 @@
1
+ """
2
+ Linked List Node Strategy Implementation
3
+
4
+ This module implements the LINKED_LIST strategy for efficient
5
+ insertions and deletions with sequential access patterns.
6
+ """
7
+
8
+ from typing import Any, Iterator, List, Dict, Optional
9
+ from .base import ANodeLinearStrategy
10
+ from ...types import NodeMode, NodeTrait
11
+
12
+
13
+ class ListNode:
14
+ """Node in the doubly linked list."""
15
+
16
+ def __init__(self, key: str, value: Any):
17
+ self.key = key
18
+ self.value = value
19
+ self.prev: Optional['ListNode'] = None
20
+ self.next: Optional['ListNode'] = None
21
+
22
+
23
+ class LinkedListStrategy(ANodeLinearStrategy):
24
+ """
25
+ Linked List node strategy for efficient insertions and deletions.
26
+
27
+ Provides O(1) insertions/deletions at known positions with
28
+ sequential access patterns optimized for iteration.
29
+ """
30
+
31
+ def __init__(self, traits: NodeTrait = NodeTrait.NONE, **options):
32
+ """Initialize the Linked List strategy."""
33
+ super().__init__(data=None, **options)
34
+ self._mode = NodeMode.LINKED_LIST
35
+ self._traits = traits
36
+
37
+ self.doubly_linked = options.get('doubly_linked', True)
38
+
39
+ # Doubly linked list with sentinel nodes
40
+ self._head = ListNode("HEAD", None)
41
+ self._tail = ListNode("TAIL", None)
42
+ self._head.next = self._tail
43
+ self._tail.prev = self._head
44
+
45
+ # Quick access mapping
46
+ self._key_to_node: Dict[str, ListNode] = {}
47
+ self._size = 0
48
+
49
+ def get_supported_traits(self) -> NodeTrait:
50
+ """Get the traits supported by the linked list strategy."""
51
+ return (NodeTrait.ORDERED | NodeTrait.INDEXED)
52
+
53
+ # ============================================================================
54
+ # CORE OPERATIONS
55
+ # ============================================================================
56
+
57
+ def insert(self, key: Any, value: Any) -> None:
58
+ """Insert key-value pair."""
59
+ key_str = str(key)
60
+ if key_str in self._key_to_node:
61
+ # Update existing
62
+ self._key_to_node[key_str].value = value
63
+ else:
64
+ # Insert new node at end
65
+ self._insert_at_end(key_str, value)
66
+
67
+ def find(self, key: Any) -> Any:
68
+ """Find value by key."""
69
+ key_str = str(key)
70
+ node = self._key_to_node.get(key_str)
71
+ return node.value if node else None
72
+
73
+ def delete(self, key: Any) -> bool:
74
+ """Delete by key."""
75
+ key_str = str(key)
76
+ if key_str in self._key_to_node:
77
+ self._remove_node(self._key_to_node[key_str])
78
+ del self._key_to_node[key_str]
79
+ return True
80
+ return False
81
+
82
+ def size(self) -> int:
83
+ """Get size."""
84
+ return self._size
85
+
86
+ def is_empty(self) -> bool:
87
+ """Check if empty."""
88
+ return self._size == 0
89
+
90
+ def to_native(self) -> List[Any]:
91
+ """Convert to native list."""
92
+ result = []
93
+ current = self._head.next
94
+ while current != self._tail:
95
+ result.append(current.value)
96
+ current = current.next
97
+ return result
98
+
99
+ # ============================================================================
100
+ # LINEAR STRATEGY METHODS
101
+ # ============================================================================
102
+
103
+ def push_front(self, value: Any) -> None:
104
+ """Add element to front."""
105
+ self._insert_after(self._head, str(self._size), value)
106
+
107
+ def push_back(self, value: Any) -> None:
108
+ """Add element to back."""
109
+ self._insert_before(self._tail, str(self._size), value)
110
+
111
+ def pop_front(self) -> Any:
112
+ """Remove element from front."""
113
+ if self._size == 0:
114
+ raise IndexError("pop from empty list")
115
+ first_node = self._head.next
116
+ value = first_node.value
117
+ self._remove_node(first_node)
118
+ return value
119
+
120
+ def pop_back(self) -> Any:
121
+ """Remove element from back."""
122
+ if self._size == 0:
123
+ raise IndexError("pop from empty list")
124
+ last_node = self._tail.prev
125
+ value = last_node.value
126
+ self._remove_node(last_node)
127
+ return value
128
+
129
+ def get_at_index(self, index: int) -> Any:
130
+ """Get element at index."""
131
+ if index < 0 or index >= self._size:
132
+ raise IndexError("list index out of range")
133
+
134
+ current = self._head.next
135
+ for _ in range(index):
136
+ current = current.next
137
+ return current.value
138
+
139
+ def set_at_index(self, index: int, value: Any) -> None:
140
+ """Set element at index."""
141
+ if index < 0 or index >= self._size:
142
+ raise IndexError("list index out of range")
143
+
144
+ current = self._head.next
145
+ for _ in range(index):
146
+ current = current.next
147
+ current.value = value
148
+
149
+ # ============================================================================
150
+ # AUTO-3 Phase 1 methods
151
+ # ============================================================================
152
+
153
+ def as_linked_list(self):
154
+ """Provide LinkedList behavioral view."""
155
+ return self
156
+
157
+ def as_stack(self):
158
+ """Provide Stack behavioral view."""
159
+ # TODO: Implement Stack view
160
+ return self
161
+
162
+ def as_queue(self):
163
+ """Provide Queue behavioral view."""
164
+ # TODO: Implement Queue view
165
+ return self
166
+
167
+ def as_deque(self):
168
+ """Provide Deque behavioral view."""
169
+ # TODO: Implement Deque view
170
+ return self
171
+
172
+ # ============================================================================
173
+ # HELPER METHODS
174
+ # ============================================================================
175
+
176
+ def _insert_at_end(self, key: str, value: Any) -> None:
177
+ """Insert new node at the end."""
178
+ self._insert_before(self._tail, key, value)
179
+
180
+ def _insert_after(self, node: ListNode, key: str, value: Any) -> None:
181
+ """Insert new node after specified node."""
182
+ new_node = ListNode(key, value)
183
+ new_node.next = node.next
184
+ new_node.prev = node
185
+ node.next.prev = new_node
186
+ node.next = new_node
187
+ self._key_to_node[key] = new_node
188
+ self._size += 1
189
+
190
+ def _insert_before(self, node: ListNode, key: str, value: Any) -> None:
191
+ """Insert new node before specified node."""
192
+ new_node = ListNode(key, value)
193
+ new_node.prev = node.prev
194
+ new_node.next = node
195
+ node.prev.next = new_node
196
+ node.prev = new_node
197
+ self._key_to_node[key] = new_node
198
+ self._size += 1
199
+
200
+ def _remove_node(self, node: ListNode) -> None:
201
+ """Remove node from list."""
202
+ node.prev.next = node.next
203
+ node.next.prev = node.prev
204
+ self._size -= 1
205
+
206
+ # ============================================================================
207
+ # PERFORMANCE CHARACTERISTICS
208
+ # ============================================================================
209
+
210
+ @property
211
+ def backend_info(self) -> Dict[str, Any]:
212
+ """Get backend implementation info."""
213
+ return {
214
+ 'strategy': 'LINKED_LIST',
215
+ 'backend': 'Doubly linked list',
216
+ 'complexity': {
217
+ 'get': 'O(n)',
218
+ 'put': 'O(1)',
219
+ 'insert': 'O(1) at known position',
220
+ 'delete': 'O(1) at known position',
221
+ 'search': 'O(n)'
222
+ }
223
+ }
224
+
225
+ @property
226
+ def metrics(self) -> Dict[str, Any]:
227
+ """Get performance metrics."""
228
+ return {
229
+ 'size': self._size,
230
+ 'memory_usage': f"{self._size * 32} bytes (estimated)",
231
+ 'doubly_linked': self.doubly_linked
232
+ }