exonware-xwnode 0.0.1.22__py3-none-any.whl → 0.0.1.23__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 (248) 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.22.dist-info → exonware_xwnode-0.0.1.23.dist-info}/METADATA +23 -3
  120. exonware_xwnode-0.0.1.23.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/RECORD +0 -214
  242. /exonware/xwnode/nodes/strategies/{node_ordered_map.py → ordered_map.py} +0 -0
  243. /exonware/xwnode/nodes/strategies/{node_ordered_map_balanced.py → ordered_map_balanced.py} +0 -0
  244. /exonware/xwnode/nodes/strategies/{node_patricia.py → patricia.py} +0 -0
  245. /exonware/xwnode/nodes/strategies/{node_radix_trie.py → radix_trie.py} +0 -0
  246. /exonware/xwnode/nodes/strategies/{node_set_tree.py → set_tree.py} +0 -0
  247. {exonware_xwnode-0.0.1.22.dist-info → exonware_xwnode-0.0.1.23.dist-info}/WHEEL +0 -0
  248. {exonware_xwnode-0.0.1.22.dist-info → exonware_xwnode-0.0.1.23.dist-info}/licenses/LICENSE +0 -0
@@ -1,16 +1,25 @@
1
1
  """
2
+ #exonware/xwnode/src/exonware/xwnode/nodes/strategies/priority_queue.py
3
+
2
4
  Priority Queue Strategy Implementation
3
5
 
4
- Implements a priority queue using Python's heapq for efficient priority-based operations.
6
+ Production-grade priority queue using binary heap.
7
+
8
+ Best Practices Implemented:
9
+ - Min-heap by default (heapq standard)
10
+ - Stable sorting with counter for equal priorities
11
+ - Efficient O(log n) operations
12
+ - Support for both min and max heaps
13
+ - Proper heap semantics following CLRS and industry standards
5
14
 
6
15
  Company: eXonware.com
7
16
  Author: Eng. Muhammad AlShehri
8
17
  Email: connect@exonware.com
9
- Version: 0.0.1.22
10
- Generation Date: 07-Sep-2025
18
+ Version: 0.0.1.23
19
+ Generation Date: October 12, 2025
11
20
  """
12
21
 
13
- from typing import Any, Iterator, Optional, Dict, Union, Tuple
22
+ from typing import Any, Iterator, List, Optional, Dict, Tuple
14
23
  import heapq
15
24
  from .base import ANodeLinearStrategy
16
25
  from .contracts import NodeType
@@ -19,44 +28,272 @@ from ...defs import NodeMode, NodeTrait
19
28
 
20
29
  class PriorityQueueStrategy(ANodeLinearStrategy):
21
30
  """
22
- Priority Queue node strategy for priority-based operations.
31
+ Production-grade Priority Queue node strategy.
32
+
33
+ Optimized for:
34
+ - Dijkstra's shortest path algorithm
35
+ - A* pathfinding
36
+ - Task scheduling with priorities
37
+ - Event simulation (discrete event systems)
38
+ - Median maintenance (with dual-heap pattern)
39
+ - Huffman coding
40
+
41
+ Performance:
42
+ - Insert: O(log n)
43
+ - Extract-Min: O(log n)
44
+ - Peek-Min: O(1)
45
+ - Decrease-Key: O(n) - requires linear search
46
+ - Build-Heap: O(n)
47
+
48
+ Security:
49
+ - Bounds checking on all operations
50
+ - Safe empty heap handling
51
+ - Priority validation
23
52
 
24
- Uses a binary heap for efficient insertion and extraction of
25
- highest priority elements, ideal for alg
53
+ Implementation Details:
54
+ - Uses min-heap by default (lowest priority value = highest priority)
55
+ - Stable sorting via counter for equal priorities (FIFO for same priority)
56
+ - Tuple format: (priority, counter, value)
57
+
58
+ Follows eXonware Priorities:
59
+ 1. Security: Input validation, safe operations
60
+ 2. Usability: Standard priority queue interface
61
+ 3. Maintainability: Clean heap implementation
62
+ 4. Performance: O(log n) operations, O(1) peek
63
+ 5. Extensibility: Support for custom priority types
64
+ """
26
65
 
27
66
  # Strategy type classification
28
67
  STRATEGY_TYPE = NodeType.LINEAR
29
- orithms like Dijkstra's.
30
- """
31
68
 
32
- def __init__(self):
33
- """Initialize an empty priority queue."""
34
- super().__init__()
35
- self._heap: List[Tuple[float, int, str, Any]] = [] # (priority, counter, key, value)
36
- self._counter = 0 # For stable sorting
37
- self._mode = NodeMode.PRIORITY_QUEUE
38
- self._traits = {NodeTrait.PRIORITY, NodeTrait.FAST_INSERT, NodeTrait.FAST_DELETE}
39
-
40
- def insert(self, key: str, value: Any) -> None:
41
- """Insert an item with default priority (0)."""
42
- self.insert_with_priority(key, value, 0.0)
43
-
44
- def find(self, key: str) -> Optional[Any]:
45
- """Find an item in the priority queue (O(n) operation)."""
46
- for priority, counter, k, v in self._heap:
47
- if k == key:
48
- return v
49
- return None
50
-
51
- def delete(self, key: str) -> bool:
52
- """Remove an item from the priority queue."""
53
- for i, (priority, counter, k, v) in enumerate(self._heap):
54
- if k == key:
69
+ __slots__ = ('_heap', '_counter', '_max_size', '_is_max_heap')
70
+
71
+ def __init__(self, traits: NodeTrait = NodeTrait.NONE, **options):
72
+ """
73
+ Initialize an empty priority queue.
74
+
75
+ Args:
76
+ traits: Additional node traits
77
+ **options:
78
+ max_size: Optional maximum heap size
79
+ is_max_heap: True for max-heap, False for min-heap (default)
80
+ initial_items: Optional list of (priority, value) tuples
81
+ """
82
+ super().__init__(
83
+ NodeMode.PRIORITY_QUEUE,
84
+ traits | NodeTrait.PRIORITY | NodeTrait.FAST_INSERT | NodeTrait.HEAP_OPERATIONS,
85
+ **options
86
+ )
87
+ self._max_size: Optional[int] = options.get('max_size')
88
+ self._is_max_heap: bool = options.get('is_max_heap', False)
89
+ self._heap: List[Tuple[float, int, Any]] = [] # (priority, counter, value)
90
+ self._counter = 0
91
+
92
+ # Build heap from initial items if provided
93
+ initial_items = options.get('initial_items', [])
94
+ if initial_items:
95
+ for priority, value in initial_items:
96
+ self.push(value, priority)
97
+
98
+ def get_supported_traits(self) -> NodeTrait:
99
+ """Get the traits supported by the priority queue strategy."""
100
+ return NodeTrait.PRIORITY | NodeTrait.FAST_INSERT | NodeTrait.HEAP_OPERATIONS
101
+
102
+ # ============================================================================
103
+ # CORE PRIORITY QUEUE OPERATIONS (Industry Standard)
104
+ # ============================================================================
105
+
106
+ def push(self, value: Any, priority: float = 0.0) -> None:
107
+ """
108
+ Insert a value with given priority.
109
+
110
+ Time: O(log n)
111
+ Space: O(1)
112
+
113
+ Args:
114
+ value: The value to insert
115
+ priority: Priority value (lower = higher priority for min-heap)
116
+
117
+ Raises:
118
+ OverflowError: If max_size is set and heap is full
119
+ """
120
+ if self._max_size and len(self._heap) >= self._max_size:
121
+ raise OverflowError(f"Priority queue overflow: max size {self._max_size} reached")
122
+
123
+ # For max-heap, negate the priority
124
+ actual_priority = -priority if self._is_max_heap else priority
125
+
126
+ heapq.heappush(self._heap, (actual_priority, self._counter, value))
127
+ self._counter += 1
128
+
129
+ def pop(self) -> Any:
130
+ """
131
+ Extract and return the highest priority item.
132
+
133
+ Time: O(log n)
134
+ Space: O(1)
135
+
136
+ Returns:
137
+ The highest priority value
138
+
139
+ Raises:
140
+ IndexError: If heap is empty
141
+ """
142
+ if self.is_empty():
143
+ raise IndexError("pop from empty priority queue")
144
+
145
+ priority, counter, value = heapq.heappop(self._heap)
146
+ return value
147
+
148
+ def peek(self) -> Any:
149
+ """
150
+ Peek at the highest priority item without removing it.
151
+
152
+ Time: O(1)
153
+ Space: O(1)
154
+
155
+ Returns:
156
+ The highest priority value
157
+
158
+ Raises:
159
+ IndexError: If heap is empty
160
+ """
161
+ if self.is_empty():
162
+ raise IndexError("peek from empty priority queue")
163
+
164
+ return self._heap[0][2] # Return value from (priority, counter, value)
165
+
166
+ def peek_with_priority(self) -> Tuple[float, Any]:
167
+ """
168
+ Peek at the highest priority item with its priority.
169
+
170
+ Returns:
171
+ Tuple of (priority, value)
172
+
173
+ Raises:
174
+ IndexError: If heap is empty
175
+ """
176
+ if self.is_empty():
177
+ raise IndexError("peek from empty priority queue")
178
+
179
+ priority, counter, value = self._heap[0]
180
+ actual_priority = -priority if self._is_max_heap else priority
181
+ return (actual_priority, value)
182
+
183
+ def pop_with_priority(self) -> Tuple[float, Any]:
184
+ """
185
+ Extract and return the highest priority item with its priority.
186
+
187
+ Returns:
188
+ Tuple of (priority, value)
189
+
190
+ Raises:
191
+ IndexError: If heap is empty
192
+ """
193
+ if self.is_empty():
194
+ raise IndexError("pop from empty priority queue")
195
+
196
+ priority, counter, value = heapq.heappop(self._heap)
197
+ actual_priority = -priority if self._is_max_heap else priority
198
+ return (actual_priority, value)
199
+
200
+ def pushpop(self, value: Any, priority: float = 0.0) -> Any:
201
+ """
202
+ Push item then pop highest priority item (more efficient than separate ops).
203
+
204
+ Time: O(log n)
205
+ Space: O(1)
206
+
207
+ Returns:
208
+ The highest priority value after insertion
209
+ """
210
+ actual_priority = -priority if self._is_max_heap else priority
211
+ priority_out, counter_out, value_out = heapq.heappushpop(
212
+ self._heap,
213
+ (actual_priority, self._counter, value)
214
+ )
215
+ self._counter += 1
216
+ return value_out
217
+
218
+ def replace(self, value: Any, priority: float = 0.0) -> Any:
219
+ """
220
+ Pop highest priority item then push new item (more efficient than separate ops).
221
+
222
+ Time: O(log n)
223
+ Space: O(1)
224
+
225
+ Returns:
226
+ The popped value
227
+
228
+ Raises:
229
+ IndexError: If heap is empty
230
+ """
231
+ if self.is_empty():
232
+ raise IndexError("replace on empty priority queue")
233
+
234
+ actual_priority = -priority if self._is_max_heap else priority
235
+ priority_out, counter_out, value_out = heapq.heapreplace(
236
+ self._heap,
237
+ (actual_priority, self._counter, value)
238
+ )
239
+ self._counter += 1
240
+ return value_out
241
+
242
+ # ============================================================================
243
+ # REQUIRED ABSTRACT METHODS (from ANodeStrategy)
244
+ # ============================================================================
245
+
246
+ def put(self, key: Any, value: Any = None) -> None:
247
+ """Store value (uses key as priority if numeric, otherwise default priority)."""
248
+ try:
249
+ priority = float(key)
250
+ self.push(value if value is not None else key, priority)
251
+ except (ValueError, TypeError):
252
+ self.push(value if value is not None else key, 0.0)
253
+
254
+ def get(self, key: Any, default: Any = None) -> Any:
255
+ """Get value in heap (O(n) - not efficient for heaps)."""
256
+ for _, _, val in self._heap:
257
+ if val == key:
258
+ return val
259
+ return default
260
+
261
+ def has(self, key: Any) -> bool:
262
+ """Check if value exists (O(n))."""
263
+ for _, _, val in self._heap:
264
+ if val == key:
265
+ return True
266
+ return False
267
+
268
+ def delete(self, key: Any) -> bool:
269
+ """Delete value from heap (O(n) - requires re-heapify)."""
270
+ for i, (priority, counter, val) in enumerate(self._heap):
271
+ if val == key:
55
272
  self._heap.pop(i)
56
- heapq.heapify(self._heap) # Re-heapify after removal
273
+ if self._heap:
274
+ heapq.heapify(self._heap)
57
275
  return True
58
276
  return False
59
277
 
278
+ def keys(self) -> Iterator[Any]:
279
+ """Get all values as keys."""
280
+ for _, _, val in self._heap:
281
+ yield val
282
+
283
+ def values(self) -> Iterator[Any]:
284
+ """Get all values."""
285
+ for _, _, val in self._heap:
286
+ yield val
287
+
288
+ def items(self) -> Iterator[tuple[Any, Any]]:
289
+ """Get all items as (value, value) pairs."""
290
+ for _, _, val in self._heap:
291
+ yield (val, val)
292
+
293
+ # ============================================================================
294
+ # UTILITY METHODS
295
+ # ============================================================================
296
+
60
297
  def size(self) -> int:
61
298
  """Get the number of items in the priority queue."""
62
299
  return len(self._heap)
@@ -65,150 +302,325 @@ orithms like Dijkstra's.
65
302
  """Check if the priority queue is empty."""
66
303
  return len(self._heap) == 0
67
304
 
305
+ def is_full(self) -> bool:
306
+ """Check if heap has reached max_size."""
307
+ return self._max_size is not None and len(self._heap) >= self._max_size
308
+
309
+ def clear(self) -> None:
310
+ """Clear all items from the priority queue."""
311
+ self._heap.clear()
312
+ self._counter = 0
313
+ self._record_access("clear")
314
+
315
+ def to_list(self) -> List[Tuple[float, Any]]:
316
+ """Convert to sorted list of (priority, value) tuples."""
317
+ return sorted(
318
+ [(p if not self._is_max_heap else -p, v) for p, c, v in self._heap],
319
+ key=lambda x: x[0]
320
+ )
321
+
68
322
  def to_native(self) -> Dict[str, Any]:
69
323
  """Convert priority queue to native dictionary format."""
70
- result = {}
71
- for priority, counter, key, value in self._heap:
72
- result[key] = value
73
- return result
324
+ return {
325
+ 'items': [(p if not self._is_max_heap else -p, v) for p, c, v in self._heap],
326
+ 'is_max_heap': self._is_max_heap
327
+ }
74
328
 
75
329
  def from_native(self, data: Dict[str, Any]) -> None:
76
330
  """Load priority queue from native dictionary format."""
77
331
  self._heap.clear()
78
- for key, value in data.items():
79
- self.insert(key, value)
332
+ self._counter = 0
333
+ self._is_max_heap = data.get('is_max_heap', False)
334
+
335
+ for priority, value in data.get('items', []):
336
+ self.push(value, priority)
80
337
 
81
- def insert_with_priority(self, key: str, value: Any, priority: float) -> None:
82
- """Insert an item with specific priority."""
83
- heapq.heappush(self._heap, (priority, self._counter, key, value))
84
- self._counter += 1
338
+ # ============================================================================
339
+ # REQUIRED ABSTRACT METHODS (Linear Strategy Base)
340
+ # ============================================================================
341
+
342
+ def get_at_index(self, index: int) -> Any:
343
+ """Get item at index in heap (order not guaranteed)."""
344
+ if 0 <= index < len(self._heap):
345
+ return self._heap[index][2]
346
+ raise IndexError(f"priority queue index out of range: {index}")
347
+
348
+ def set_at_index(self, index: int, value: Any) -> None:
349
+ """Set item at index (not recommended - breaks heap property)."""
350
+ if 0 <= index < len(self._heap):
351
+ priority, counter, _ = self._heap[index]
352
+ self._heap[index] = (priority, counter, value)
353
+ else:
354
+ raise IndexError(f"priority queue index out of range: {index}")
355
+
356
+ def push_front(self, value: Any) -> None:
357
+ """Push with highest priority."""
358
+ self.push(value, float('-inf') if not self._is_max_heap else float('inf'))
85
359
 
86
- def extract_min(self) -> Optional[Tuple[str, Any, float]]:
87
- """Extract item with minimum priority."""
360
+ def push_back(self, value: Any) -> None:
361
+ """Push with lowest priority."""
362
+ self.push(value, float('inf') if not self._is_max_heap else float('-inf'))
363
+
364
+ def pop_front(self) -> Any:
365
+ """Pop highest priority item (standard pop)."""
366
+ return self.pop()
367
+
368
+ def pop_back(self) -> Any:
369
+ """Pop lowest priority item (O(n) - not efficient)."""
88
370
  if self.is_empty():
89
- return None
371
+ raise IndexError("pop from empty priority queue")
90
372
 
91
- priority, counter, key, value = heapq.heappop(self._heap)
92
- return (key, value, priority)
373
+ # Find item with worst priority
374
+ worst_idx = max(range(len(self._heap)), key=lambda i: self._heap[i][0])
375
+ value = self._heap[worst_idx][2]
376
+ self._heap.pop(worst_idx)
377
+ if self._heap: # Re-heapify if not empty
378
+ heapq.heapify(self._heap)
379
+ return value
93
380
 
94
- def extract_max(self) -> Optional[Tuple[str, Any, float]]:
95
- """Extract item with maximum priority."""
96
- if self.is_empty():
97
- return None
381
+ # Behavioral views
382
+ def as_linked_list(self):
383
+ """Priority queue can be viewed as ordered linked list."""
384
+ return self
385
+
386
+ def as_stack(self):
387
+ """Priority queue cannot behave as Stack."""
388
+ raise NotImplementedError("PriorityQueue cannot behave as Stack - use StackStrategy instead")
389
+
390
+ def as_queue(self):
391
+ """Priority queue cannot behave as standard Queue."""
392
+ raise NotImplementedError("PriorityQueue cannot behave as Queue - use QueueStrategy instead")
393
+
394
+ def as_deque(self):
395
+ """Priority queue cannot behave as Deque."""
396
+ raise NotImplementedError("PriorityQueue cannot behave as Deque - use DequeStrategy instead")
397
+
398
+ # ============================================================================
399
+ # PYTHON SPECIAL METHODS
400
+ # ============================================================================
401
+
402
+ def __len__(self) -> int:
403
+ """Return the number of items in the priority queue."""
404
+ return len(self._heap)
405
+
406
+ def __bool__(self) -> bool:
407
+ """Return True if priority queue is not empty."""
408
+ return bool(self._heap)
409
+
410
+ def __iter__(self) -> Iterator[Any]:
411
+ """Iterate through items (order not guaranteed - heap order)."""
412
+ for _, _, value in self._heap:
413
+ yield value
414
+
415
+ def __repr__(self) -> str:
416
+ """Professional string representation."""
417
+ heap_type = "max-heap" if self._is_max_heap else "min-heap"
418
+ top = self.peek() if not self.is_empty() else None
419
+ return f"PriorityQueueStrategy(size={len(self._heap)}, type={heap_type}, top={top})"
420
+
421
+ def __str__(self) -> str:
422
+ """Human-readable string representation."""
423
+ heap_type = "MaxHeap" if self._is_max_heap else "MinHeap"
424
+ return f"{heap_type}[size={len(self._heap)}]"
425
+
426
+ # ============================================================================
427
+ # ADVANCED HEAP OPERATIONS
428
+ # ============================================================================
429
+
430
+ def nsmallest(self, n: int) -> List[Tuple[float, Any]]:
431
+ """
432
+ Get n smallest priority items without removing them.
98
433
 
99
- # Convert to max-heap by negating priorities
100
- max_heap = [(-priority, counter, key, value) for priority, counter, key, value in self._heap]
101
- heapq.heapify(max_heap)
434
+ Time: O(n log k) where k = min(n, heap_size)
102
435
 
103
- neg_priority, counter, key, value = heapq.heappop(max_heap)
104
- priority = -neg_priority
436
+ Returns:
437
+ List of (priority, value) tuples
438
+ """
439
+ items = heapq.nsmallest(n, self._heap, key=lambda x: x[0])
440
+ return [(p if not self._is_max_heap else -p, v) for p, c, v in items]
441
+
442
+ def nlargest(self, n: int) -> List[Tuple[float, Any]]:
443
+ """
444
+ Get n largest priority items without removing them.
105
445
 
106
- # Remove from original heap
107
- for i, (p, c, k, v) in enumerate(self._heap):
108
- if k == key and c == counter:
109
- self._heap.pop(i)
110
- break
446
+ Time: O(n log k) where k = min(n, heap_size)
111
447
 
112
- return (key, value, priority)
448
+ Returns:
449
+ List of (priority, value) tuples
450
+ """
451
+ items = heapq.nlargest(n, self._heap, key=lambda x: x[0])
452
+ return [(p if not self._is_max_heap else -p, v) for p, c, v in items]
113
453
 
114
- def peek_min(self) -> Optional[Tuple[str, Any, float]]:
115
- """Peek at item with minimum priority without removing it."""
116
- if self.is_empty():
117
- return None
454
+ def merge(self, other: 'PriorityQueueStrategy') -> 'PriorityQueueStrategy':
455
+ """
456
+ Merge two priority queues.
118
457
 
119
- priority, counter, key, value = self._heap[0]
120
- return (key, value, priority)
121
-
122
- def peek_max(self) -> Optional[Tuple[str, Any, float]]:
123
- """Peek at item with maximum priority without removing it."""
124
- if self.is_empty():
125
- return None
458
+ Time: O((n + m) log(n + m))
459
+
460
+ Returns:
461
+ New merged priority queue
462
+ """
463
+ merged = PriorityQueueStrategy(is_max_heap=self._is_max_heap)
126
464
 
127
- max_item = None
128
- for priority, counter, key, value in self._heap:
129
- if max_item is None or priority > max_item[2]:
130
- max_item = (key, value, priority)
465
+ # Merge heaps efficiently
466
+ merged._heap = list(heapq.merge(self._heap, other._heap, key=lambda x: x[0]))
467
+ merged._counter = self._counter + other._counter
131
468
 
132
- return max_item
469
+ return merged
133
470
 
134
- def update_priority(self, key: str, new_priority: float) -> bool:
135
- """Update the priority of an existing item."""
136
- for i, (priority, counter, k, v) in enumerate(self._heap):
137
- if k == key:
138
- self._heap[i] = (new_priority, counter, k, v)
139
- heapq.heapify(self._heap) # Re-heapify after update
140
- return True
141
- return False
471
+ # ============================================================================
472
+ # COMPATIBILITY INTERFACE
473
+ # ============================================================================
474
+
475
+ def to_list(self) -> List[Tuple[float, Any]]:
476
+ """Convert to sorted list of (priority, value) tuples."""
477
+ sorted_items = sorted(self._heap, key=lambda x: x[0])
478
+ return [(p if not self._is_max_heap else -p, v) for p, c, v in sorted_items]
479
+
480
+ def to_native(self) -> Dict[str, Any]:
481
+ """Convert priority queue to native dictionary format."""
482
+ return {
483
+ 'items': [(p if not self._is_max_heap else -p, v) for p, c, v in self._heap],
484
+ 'is_max_heap': self._is_max_heap,
485
+ 'size': len(self._heap)
486
+ }
142
487
 
143
- def get_priority(self, key: str) -> Optional[float]:
144
- """Get the priority of an item."""
145
- for priority, counter, k, v in self._heap:
146
- if k == key:
147
- return priority
148
- return None
488
+ def from_native(self, data: Dict[str, Any]) -> None:
489
+ """Load priority queue from native dictionary format."""
490
+ self._heap.clear()
491
+ self._counter = 0
492
+ self._is_max_heap = data.get('is_max_heap', False)
493
+
494
+ for priority, value in data.get('items', []):
495
+ self.push(value, priority)
496
+
497
+ # ============================================================================
498
+ # UTILITY METHODS
499
+ # ============================================================================
500
+
501
+ def size(self) -> int:
502
+ """Get the number of items in the priority queue."""
503
+ return len(self._heap)
504
+
505
+ def is_empty(self) -> bool:
506
+ """Check if the priority queue is empty."""
507
+ return len(self._heap) == 0
508
+
509
+ def is_full(self) -> bool:
510
+ """Check if heap has reached max_size."""
511
+ return self._max_size is not None and len(self._heap) >= self._max_size
149
512
 
150
513
  def clear(self) -> None:
151
514
  """Clear all items from the priority queue."""
152
515
  self._heap.clear()
153
516
  self._counter = 0
517
+ self._record_access("clear")
154
518
 
155
- def get_at_index(self, index: int) -> Optional[Any]:
156
- """Get item at specific index (not recommended for priority queue)."""
519
+ # ============================================================================
520
+ # REQUIRED ABSTRACT METHODS (Linear Strategy Base)
521
+ # ============================================================================
522
+
523
+ def get_at_index(self, index: int) -> Any:
524
+ """Get item at index (heap order, not priority order)."""
525
+ if 0 <= index < len(self._heap):
526
+ return self._heap[index][2]
527
+ raise IndexError(f"priority queue index out of range: {index}")
528
+
529
+ def set_at_index(self, index: int, value: Any) -> None:
530
+ """Set item at index (breaks heap property - requires re-heapify)."""
157
531
  if 0 <= index < len(self._heap):
158
- priority, counter, key, value = self._heap[index]
159
- return value
160
- return None
532
+ priority, counter, _ = self._heap[index]
533
+ self._heap[index] = (priority, counter, value)
534
+ else:
535
+ raise IndexError(f"priority queue index out of range: {index}")
161
536
 
162
537
  def push_front(self, value: Any) -> None:
163
- """Push to front with high priority."""
164
- key = f"item_{len(self._heap)}"
165
- self.insert_with_priority(key, value, float('inf'))
538
+ """Push with highest priority."""
539
+ self.push(value, float('-inf') if not self._is_max_heap else float('inf'))
166
540
 
167
541
  def push_back(self, value: Any) -> None:
168
- """Push to back with low priority."""
169
- key = f"item_{len(self._heap)}"
170
- self.insert_with_priority(key, value, float('-inf'))
542
+ """Push with lowest priority."""
543
+ self.push(value, float('inf') if not self._is_max_heap else float('-inf'))
171
544
 
172
- def __iter__(self) -> Iterator[Any]:
173
- """Iterate through items (order not guaranteed)."""
174
- for priority, counter, key, value in self._heap:
175
- yield value
176
-
177
- def __repr__(self) -> str:
178
- """String representation of the priority queue."""
179
- min_item = self.peek_min()
180
- max_item = self.peek_max()
181
- return f"PriorityQueueStrategy(size={len(self._heap)}, min={min_item[2] if min_item else None}, max={max_item[2] if max_item else None})"
182
-
183
- # Required abstract methods from base classes
184
545
  def pop_front(self) -> Any:
185
- """Remove element from front (same as extract_min for priority queue)."""
186
- result = self.extract_min()
187
- return result[1] if result else None
546
+ """Pop highest priority item."""
547
+ return self.pop()
188
548
 
189
549
  def pop_back(self) -> Any:
190
- """Remove element from back (same as extract_max for priority queue)."""
191
- result = self.extract_max()
192
- return result[1] if result else None
193
-
194
- def set_at_index(self, index: int, value: Any) -> None:
195
- """Set element at index (not recommended for priority queue)."""
196
- if 0 <= index < len(self._heap):
197
- priority, counter, key, old_value = self._heap[index]
198
- self._heap[index] = (priority, counter, key, value)
550
+ """Pop lowest priority item (inefficient O(n))."""
551
+ if self.is_empty():
552
+ raise IndexError("pop from empty priority queue")
553
+
554
+ worst_idx = max(range(len(self._heap)), key=lambda i: self._heap[i][0])
555
+ value = self._heap[worst_idx][2]
556
+ self._heap.pop(worst_idx)
557
+ if self._heap:
558
+ heapq.heapify(self._heap)
559
+ return value
199
560
 
561
+ # Behavioral views
200
562
  def as_linked_list(self):
201
- """Provide LinkedList behavioral view."""
563
+ """Priority queue can be viewed as ordered linked list."""
202
564
  return self
203
565
 
204
566
  def as_stack(self):
205
- """Provide Stack behavioral view (not recommended)."""
567
+ """Priority queue cannot behave as Stack."""
206
568
  raise NotImplementedError("PriorityQueue cannot behave as Stack")
207
569
 
208
570
  def as_queue(self):
209
- """Provide Queue behavioral view (not recommended)."""
571
+ """Priority queue cannot behave as Queue."""
210
572
  raise NotImplementedError("PriorityQueue cannot behave as Queue")
211
573
 
212
574
  def as_deque(self):
213
- """Provide Deque behavioral view (not recommended)."""
575
+ """Priority queue cannot behave as Deque."""
214
576
  raise NotImplementedError("PriorityQueue cannot behave as Deque")
577
+
578
+ # ============================================================================
579
+ # PYTHON SPECIAL METHODS
580
+ # ============================================================================
581
+
582
+ def __iter__(self) -> Iterator[Any]:
583
+ """Iterate in heap order (not priority order)."""
584
+ for _, _, value in self._heap:
585
+ yield value
586
+
587
+ def __repr__(self) -> str:
588
+ """Professional string representation."""
589
+ heap_type = "max-heap" if self._is_max_heap else "min-heap"
590
+ return f"PriorityQueueStrategy(size={len(self._heap)}, type={heap_type})"
591
+
592
+ # ============================================================================
593
+ # PERFORMANCE METADATA
594
+ # ============================================================================
595
+
596
+ @property
597
+ def backend_info(self) -> Dict[str, Any]:
598
+ """Get backend implementation info."""
599
+ return {
600
+ 'strategy': 'PRIORITY_QUEUE',
601
+ 'backend': 'heapq (binary heap)',
602
+ 'heap_type': 'max-heap' if self._is_max_heap else 'min-heap',
603
+ 'complexity': {
604
+ 'push': 'O(log n)',
605
+ 'pop': 'O(log n)',
606
+ 'peek': 'O(1)',
607
+ 'pushpop': 'O(log n)',
608
+ 'replace': 'O(log n)',
609
+ 'space': 'O(n)'
610
+ },
611
+ 'thread_safe': False,
612
+ 'max_size': self._max_size if self._max_size else 'unlimited'
613
+ }
614
+
615
+ @property
616
+ def metrics(self) -> Dict[str, Any]:
617
+ """Get performance metrics."""
618
+ return {
619
+ 'size': len(self._heap),
620
+ 'is_empty': self.is_empty(),
621
+ 'is_full': self.is_full(),
622
+ 'max_size': self._max_size,
623
+ 'is_max_heap': self._is_max_heap,
624
+ 'counter': self._counter,
625
+ 'memory_usage': f"{len(self._heap) * 24} bytes (estimated)"
626
+ }