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,269 @@
1
+ """
2
+ Hash Map Node Strategy Implementation
3
+
4
+ This module implements the HASH_MAP strategy for fast key-value operations
5
+ using Python's built-in dictionary.
6
+ """
7
+
8
+ from typing import Any, Iterator, Dict, List, Optional, Union
9
+ from ._base_node import aNodeStrategy
10
+ from ...types import NodeMode, NodeTrait
11
+ from ..utils import (
12
+ safe_to_native_conversion,
13
+ is_list_like,
14
+ create_basic_metrics,
15
+ create_basic_backend_info,
16
+ create_size_tracker,
17
+ create_access_tracker,
18
+ update_size_tracker,
19
+ record_access,
20
+ get_access_metrics
21
+ )
22
+
23
+
24
+ class xHashMapStrategy(aNodeStrategy):
25
+ """
26
+ Hash Map node strategy for fast O(1) key-value operations.
27
+
28
+ Uses Python's built-in dictionary for optimal performance
29
+ with associative operations.
30
+ """
31
+
32
+ def __init__(self, traits: NodeTrait = NodeTrait.NONE, **options):
33
+ """Initialize the hash map strategy."""
34
+ super().__init__(NodeMode.HASH_MAP, traits, **options)
35
+ self._data: Dict[str, Any] = {}
36
+ self._size_tracker = create_size_tracker()
37
+ self._access_tracker = create_access_tracker()
38
+
39
+ def get_supported_traits(self) -> NodeTrait:
40
+ """Get the traits supported by the hash map strategy."""
41
+ return (NodeTrait.INDEXED | NodeTrait.HIERARCHICAL)
42
+
43
+ # ============================================================================
44
+ # CORE OPERATIONS
45
+ # ============================================================================
46
+
47
+ def put(self, key: Any, value: Any = None) -> None:
48
+ """Store a key-value pair."""
49
+ str_key = str(key)
50
+ if str_key not in self._data:
51
+ update_size_tracker(self._size_tracker, 1)
52
+ self._data[str_key] = value
53
+ record_access(self._access_tracker, 'put_count')
54
+
55
+ def get(self, path: str, default: Any = None) -> Any:
56
+ """Retrieve a value by path."""
57
+ record_access(self._access_tracker, 'get_count')
58
+
59
+ # Handle simple key lookup
60
+ if '.' not in path:
61
+ return self._data.get(path, default)
62
+
63
+ # Handle path navigation
64
+ parts = path.split('.')
65
+ current = self._data
66
+
67
+ for part in parts:
68
+ if isinstance(current, dict) and part in current:
69
+ current = current[part]
70
+ else:
71
+ return default
72
+
73
+ return current
74
+
75
+ def has(self, key: Any) -> bool:
76
+ """Check if key exists."""
77
+ return str(key) in self._data
78
+
79
+ def exists(self, path: str) -> bool:
80
+ """Check if path exists."""
81
+ return self.get(path) is not None
82
+
83
+ def remove(self, key: Any) -> bool:
84
+ """Remove a key-value pair."""
85
+ str_key = str(key)
86
+ if str_key in self._data:
87
+ del self._data[str_key]
88
+ update_size_tracker(self._size_tracker, -1)
89
+ record_access(self._access_tracker, 'delete_count')
90
+ return True
91
+ return False
92
+
93
+ def delete(self, key: Any) -> bool:
94
+ """Remove a key-value pair (alias for remove)."""
95
+ return self.remove(key)
96
+
97
+ def put(self, path: str, value: Any) -> 'xHashMapStrategy':
98
+ """Set a value at path."""
99
+ # Handle simple key setting (non-string or string without dots)
100
+ if not isinstance(path, str) or '.' not in path:
101
+ str_key = str(path)
102
+ if str_key not in self._data:
103
+ update_size_tracker(self._size_tracker, 1)
104
+ self._data[str_key] = value
105
+ record_access(self._access_tracker, 'put_count')
106
+ return self
107
+
108
+ # Handle path setting
109
+ parts = path.split('.')
110
+ current = self._data
111
+
112
+ # Navigate to the parent of the target
113
+ for part in parts[:-1]:
114
+ if part not in current:
115
+ current[part] = {}
116
+ current = current[part]
117
+
118
+ # Set the value
119
+ current[parts[-1]] = value
120
+ return self
121
+
122
+ def clear(self) -> None:
123
+ """Clear all data."""
124
+ self._data.clear()
125
+ self._size_tracker['size'] = 0
126
+
127
+ def keys(self) -> Iterator[str]:
128
+ """Get all keys."""
129
+ return iter(self._data.keys())
130
+
131
+ def values(self) -> Iterator[Any]:
132
+ """Get all values."""
133
+ return iter(self._data.values())
134
+
135
+ def items(self) -> Iterator[tuple[str, Any]]:
136
+ """Get all key-value pairs."""
137
+ return iter(self._data.items())
138
+
139
+ def __len__(self) -> int:
140
+ """Get the number of items."""
141
+ return self._size_tracker['size']
142
+
143
+ def __getitem__(self, key: Union[str, int]) -> Any:
144
+ """Get item by key or index."""
145
+ return self.get(str(key))
146
+
147
+ def __setitem__(self, key: Union[str, int], value: Any) -> None:
148
+ """Set item by key or index."""
149
+ self.put(str(key), value)
150
+
151
+ def __contains__(self, key: Union[str, int]) -> bool:
152
+ """Check if key exists."""
153
+ return self.has(str(key))
154
+
155
+ def __iter__(self) -> Iterator[Any]:
156
+ """Iterate over values."""
157
+ return self.values()
158
+
159
+ @classmethod
160
+ def create_from_data(cls, data: Any) -> 'xHashMapStrategy':
161
+ """
162
+ Create a new strategy instance from data.
163
+
164
+ Args:
165
+ data: The data to create the strategy from
166
+
167
+ Returns:
168
+ A new strategy instance containing the data
169
+ """
170
+ instance = cls()
171
+ if isinstance(data, dict):
172
+ for key, value in data.items():
173
+ instance.put(key, value)
174
+ elif isinstance(data, (list, tuple)):
175
+ for i, value in enumerate(data):
176
+ instance.put(i, value)
177
+ else:
178
+ # For primitive values, store directly
179
+ instance.put('_value', data)
180
+ return instance
181
+
182
+ def to_native(self) -> Dict[str, Any]:
183
+ """Convert to native Python dictionary."""
184
+ # Return a copy with all nested XWNode objects converted to native types
185
+ return {k: safe_to_native_conversion(v) for k, v in self._data.items()}
186
+
187
+ @property
188
+ def value(self) -> Any:
189
+ """Get the value of this node."""
190
+ # If this is a primitive value node (has only _value key), return the value directly
191
+ if len(self._data) == 1 and '_value' in self._data:
192
+ return self._data['_value']
193
+ # Otherwise return the native representation
194
+ return self.to_native()
195
+
196
+ @property
197
+ def is_leaf(self) -> bool:
198
+ """Check if this is a leaf node."""
199
+ return len(self._data) == 0
200
+
201
+ @property
202
+ def is_list(self) -> bool:
203
+ """This is never a list strategy."""
204
+ return False
205
+
206
+ @property
207
+ def is_dict(self) -> bool:
208
+ """This is always a dict strategy."""
209
+ return True
210
+
211
+ @property
212
+ def is_reference(self) -> bool:
213
+ """Check if this is a reference node."""
214
+ return False
215
+
216
+ @property
217
+ def is_object(self) -> bool:
218
+ """Check if this is an object node."""
219
+ return False
220
+
221
+ @property
222
+ def type(self) -> str:
223
+ """Get the type of this node."""
224
+ return "dict"
225
+
226
+ @property
227
+ def uri(self) -> Optional[str]:
228
+ """Get the URI of this node."""
229
+ return None
230
+
231
+ @property
232
+ def reference_type(self) -> Optional[str]:
233
+ """Get the reference type of this node."""
234
+ return None
235
+
236
+ @property
237
+ def object_type(self) -> Optional[str]:
238
+ """Get the object type of this node."""
239
+ return None
240
+
241
+ @property
242
+ def mime_type(self) -> Optional[str]:
243
+ """Get the MIME type of this node."""
244
+ return None
245
+
246
+ @property
247
+ def metadata(self) -> Optional[Dict[str, Any]]:
248
+ """Get the metadata of this node."""
249
+ return None
250
+
251
+ # ============================================================================
252
+ # PERFORMANCE CHARACTERISTICS
253
+ # ============================================================================
254
+
255
+ def backend_info(self) -> Dict[str, Any]:
256
+ """Get backend implementation info."""
257
+ return create_basic_backend_info(
258
+ 'HASH_MAP',
259
+ 'Python dict',
260
+ load_factor=len(self._data) / max(8, len(self._data)),
261
+ collision_rate='~5% (Python dict optimized)'
262
+ )
263
+
264
+ def metrics(self) -> Dict[str, Any]:
265
+ """Get performance metrics."""
266
+ base_metrics = create_basic_metrics('HASH_MAP', self._size_tracker['size'])
267
+ access_metrics = get_access_metrics(self._access_tracker)
268
+ base_metrics.update(access_metrics)
269
+ return base_metrics
@@ -0,0 +1,191 @@
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
+ from ..utils import (
12
+ MinHeap,
13
+ safe_to_native_conversion,
14
+ create_basic_metrics,
15
+ create_basic_backend_info,
16
+ create_size_tracker,
17
+ create_access_tracker,
18
+ update_size_tracker,
19
+ record_access,
20
+ get_access_metrics
21
+ )
22
+
23
+
24
+ class HeapStrategy(ANodeTreeStrategy):
25
+ """
26
+ Heap node strategy for priority queue operations.
27
+
28
+ Optimized for push, pop, and peek operations with configurable min/max behavior.
29
+ """
30
+
31
+ def __init__(self, traits: NodeTrait = NodeTrait.NONE, **options):
32
+ """Initialize the heap strategy."""
33
+ super().__init__(NodeMode.HEAP, traits, **options)
34
+ self._is_max_heap = options.get('max_heap', False)
35
+ self._heap = MinHeap(max_heap=self._is_max_heap)
36
+ self._size_tracker = create_size_tracker()
37
+ self._access_tracker = create_access_tracker()
38
+
39
+ def get_supported_traits(self) -> NodeTrait:
40
+ """Get the traits supported by the heap strategy."""
41
+ return (NodeTrait.ORDERED | NodeTrait.PRIORITY_QUEUE)
42
+
43
+ # ============================================================================
44
+ # CORE OPERATIONS
45
+ # ============================================================================
46
+
47
+ def put(self, key: Any, value: Any = None) -> None:
48
+ """Store a key-value pair (key is priority, value is data)."""
49
+ priority = float(key) if key is not None else 0.0
50
+ data = value if value is not None else key
51
+ self._heap.push(data, priority)
52
+ update_size_tracker(self._size_tracker, 1)
53
+ record_access(self._access_tracker, 'put_count')
54
+
55
+ def get(self, key: Any, default: Any = None) -> Any:
56
+ """Retrieve a value by key (peek operation)."""
57
+ record_access(self._access_tracker, 'get_count')
58
+ try:
59
+ return self._heap.peek()
60
+ except IndexError:
61
+ return default
62
+
63
+ def has(self, key: Any) -> bool:
64
+ """Check if heap has any items."""
65
+ return len(self._heap) > 0
66
+
67
+ def remove(self, key: Any) -> bool:
68
+ """Remove the top item from the heap."""
69
+ try:
70
+ self._heap.pop()
71
+ update_size_tracker(self._size_tracker, -1)
72
+ record_access(self._access_tracker, 'delete_count')
73
+ return True
74
+ except IndexError:
75
+ return False
76
+
77
+ def delete(self, key: Any) -> bool:
78
+ """Remove the top item (alias for remove)."""
79
+ return self.remove(key)
80
+
81
+ def clear(self) -> None:
82
+ """Clear all data."""
83
+ self._heap = MinHeap(max_heap=self._is_max_heap)
84
+ self._size_tracker['size'] = 0
85
+
86
+ def keys(self) -> Iterator[str]:
87
+ """Get all keys (priorities) in heap order."""
88
+ return (str(priority) for priority, _, _ in self._heap._heap)
89
+
90
+ def values(self) -> Iterator[Any]:
91
+ """Get all values in heap order."""
92
+ return (value for _, _, value in self._heap._heap)
93
+
94
+ def items(self) -> Iterator[tuple[str, Any]]:
95
+ """Get all key-value pairs in heap order."""
96
+ return ((str(priority), value) for priority, _, value in self._heap._heap)
97
+
98
+ def __len__(self) -> int:
99
+ """Get the number of items."""
100
+ return self._size_tracker['size']
101
+
102
+ def to_native(self) -> List[Any]:
103
+ """Convert to native Python list sorted by priority."""
104
+ return [safe_to_native_conversion(value) for _, _, value in sorted(self._heap._heap)]
105
+
106
+ @property
107
+ def is_list(self) -> bool:
108
+ """This behaves like a list (priority-ordered)."""
109
+ return True
110
+
111
+ @property
112
+ def is_dict(self) -> bool:
113
+ """This is not a dict strategy."""
114
+ return False
115
+
116
+ # ============================================================================
117
+ # HEAP-SPECIFIC OPERATIONS
118
+ # ============================================================================
119
+
120
+ def push(self, value: Any, priority: float = None) -> str:
121
+ """Push a value with optional priority. Returns the generated key."""
122
+ key = self._heap.push(value, priority)
123
+ update_size_tracker(self._size_tracker, 1)
124
+ return key
125
+
126
+ def pop(self) -> Any:
127
+ """Remove and return the highest/lowest priority item."""
128
+ value = self._heap.pop()
129
+ update_size_tracker(self._size_tracker, -1)
130
+ return value
131
+
132
+ def peek(self) -> Any:
133
+ """Peek at the highest/lowest priority item without removing."""
134
+ return self._heap.peek()
135
+
136
+ def peek_priority(self) -> float:
137
+ """Peek at the priority of the top item."""
138
+ return self._heap.peek_priority()
139
+
140
+ def pushpop(self, value: Any, priority: float = None) -> Any:
141
+ """Push value and pop the highest/lowest priority item efficiently."""
142
+ old_value = self._heap.pushpop(value, priority)
143
+ if old_value is None:
144
+ update_size_tracker(self._size_tracker, 1)
145
+ return old_value
146
+
147
+ def replace(self, value: Any, priority: float = None) -> Any:
148
+ """Replace the top item and return the old top item."""
149
+ old_value = self._heap.replace(value, priority)
150
+ return old_value
151
+
152
+ def heapify(self) -> None:
153
+ """Rebuild the heap in-place."""
154
+ self._heap.heapify()
155
+
156
+ def nlargest(self, n: int) -> List[Any]:
157
+ """Get the n largest items."""
158
+ return self._heap.nlargest(n)
159
+
160
+ def nsmallest(self, n: int) -> List[Any]:
161
+ """Get the n smallest items."""
162
+ return self._heap.nsmallest(n)
163
+
164
+ # ============================================================================
165
+ # PERFORMANCE CHARACTERISTICS
166
+ # ============================================================================
167
+
168
+ def backend_info(self) -> Dict[str, Any]:
169
+ """Get backend implementation info."""
170
+ heap_type = "Max Heap" if self._is_max_heap else "Min Heap"
171
+ return create_basic_backend_info(
172
+ 'HEAP',
173
+ f'Python heapq ({heap_type})',
174
+ complexity={
175
+ 'push': 'O(log n)',
176
+ 'pop': 'O(log n)',
177
+ 'peek': 'O(1)',
178
+ 'heapify': 'O(n)'
179
+ }
180
+ )
181
+
182
+ def metrics(self) -> Dict[str, Any]:
183
+ """Get performance metrics."""
184
+ base_metrics = create_basic_metrics('HEAP', self._size_tracker['size'])
185
+ access_metrics = get_access_metrics(self._access_tracker)
186
+ base_metrics.update(access_metrics)
187
+ base_metrics.update({
188
+ 'heap_type': 'max' if self._is_max_heap else 'min',
189
+ 'is_empty': len(self._heap) == 0
190
+ })
191
+ return base_metrics