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,369 @@
1
+ """
2
+ DATA_INTERCHANGE_OPTIMIZED Node Strategy Implementation
3
+
4
+ Ultra-lightweight strategy specifically optimized for data interchange patterns:
5
+ - Copy-on-write semantics for data interchange
6
+ - Object pooling support for factory patterns
7
+ - Structural hash caching for fast equality checks
8
+ - Minimal metadata overhead
9
+ - Zero graph features for maximum performance
10
+ - __slots__ optimization for memory efficiency
11
+ """
12
+
13
+ import weakref
14
+ from typing import Any, Iterator, Dict, List, Optional
15
+ from ._base_node import aNodeStrategy
16
+ from ...types import NodeMode, NodeTrait
17
+ from ...errors import XWNodeUnsupportedCapabilityError
18
+
19
+ # Import shared utilities
20
+ from ..utils import (
21
+ recursive_to_native, is_sequential_numeric_keys,
22
+ calculate_structural_hash, create_performance_tracker
23
+ )
24
+
25
+
26
+ class DataInterchangeOptimizedStrategy(aNodeStrategy):
27
+ """
28
+ Ultra-lightweight node strategy optimized for data interchange patterns.
29
+
30
+ This strategy provides maximum performance for data interchange patterns:
31
+ - O(1) hash map operations using Python dict
32
+ - COW semantics with lazy copying
33
+ - Structural hash caching for fast equality
34
+ - Object pooling support
35
+ - Minimal memory overhead with __slots__
36
+ - Zero graph/edge overhead
37
+ """
38
+
39
+ __slots__ = (
40
+ '_data', '_size', '_hash_cache', '_frozen', '_cow_enabled',
41
+ '_pool_ref', '_creation_time', '_access_count', 'mode', 'traits', 'options'
42
+ )
43
+
44
+ def __init__(self, traits: NodeTrait = NodeTrait.INDEXED, **options):
45
+ """Initialize the xData-optimized strategy."""
46
+ # Initialize parent without calling super() to avoid dict overhead
47
+ self.mode = NodeMode.HASH_MAP # Using HASH_MAP as base mode
48
+ self.traits = traits
49
+ self.options = options
50
+
51
+ # Core data storage (ultra-efficient)
52
+ self._data: Dict[str, Any] = {}
53
+ self._size = 0
54
+
55
+ # COW optimization flags
56
+ self._hash_cache: Optional[int] = None
57
+ self._frozen = False # True after first copy
58
+ self._cow_enabled = options.get('enable_cow', True)
59
+
60
+ # Object pooling support
61
+ self._pool_ref: Optional[weakref.ref] = None
62
+
63
+ # Performance tracking (minimal overhead)
64
+ self._creation_time = options.get('creation_time', 0)
65
+ self._performance_tracker = create_performance_tracker()
66
+
67
+ self._validate_traits()
68
+
69
+ def get_supported_traits(self) -> NodeTrait:
70
+ """Get the traits supported by the xData-optimized strategy."""
71
+ return NodeTrait.INDEXED # Only essential traits for maximum performance
72
+
73
+ # ============================================================================
74
+ # ULTRA-OPTIMIZED CORE OPERATIONS
75
+ # ============================================================================
76
+
77
+ def put(self, key: Any, value: Any = None) -> None:
78
+ """Store a key-value pair with COW optimization."""
79
+ self._ensure_mutable()
80
+
81
+ str_key = str(key)
82
+ if str_key not in self._data:
83
+ self._size += 1
84
+
85
+ self._data[str_key] = value
86
+ self._invalidate_cache()
87
+ self._performance_tracker.record_access()
88
+
89
+ def get(self, key: Any, default: Any = None) -> Any:
90
+ """Retrieve a value by key (zero-overhead success path)."""
91
+ self._performance_tracker.record_access()
92
+ return self._data.get(str(key), default)
93
+
94
+ def has(self, key: Any) -> bool:
95
+ """Check if key exists (optimized)."""
96
+ return str(key) in self._data
97
+
98
+ def delete(self, key: Any) -> bool:
99
+ """Remove a key-value pair with COW."""
100
+ self._ensure_mutable()
101
+
102
+ str_key = str(key)
103
+ if str_key in self._data:
104
+ del self._data[str_key]
105
+ self._size -= 1
106
+ self._invalidate_cache()
107
+ return True
108
+ return False
109
+
110
+ def remove(self, key: Any) -> bool:
111
+ """Remove a key-value pair (alias for delete)."""
112
+ return self.delete(key)
113
+
114
+ def clear(self) -> None:
115
+ """Clear all data with COW."""
116
+ self._ensure_mutable()
117
+ self._data.clear()
118
+ self._size = 0
119
+ self._invalidate_cache()
120
+
121
+ def keys(self) -> Iterator[str]:
122
+ """Get all keys (zero-copy iterator)."""
123
+ return iter(self._data.keys())
124
+
125
+ def values(self) -> Iterator[Any]:
126
+ """Get all values (zero-copy iterator)."""
127
+ return iter(self._data.values())
128
+
129
+ def items(self) -> Iterator[tuple[str, Any]]:
130
+ """Get all key-value pairs (zero-copy iterator)."""
131
+ return iter(self._data.items())
132
+
133
+ def __len__(self) -> int:
134
+ """Get the number of items (zero overhead)."""
135
+ return self._size
136
+
137
+ def to_native(self) -> Dict[str, Any]:
138
+ """Convert to native Python dictionary (optimized for xData)."""
139
+ # Return a copy with all nested XWNode objects converted to native types
140
+ return {k: recursive_to_native(v) for k, v in self._data.items()}
141
+
142
+ # ============================================================================
143
+ # COPY-ON-WRITE OPTIMIZATIONS (xData Specific)
144
+ # ============================================================================
145
+
146
+ def _ensure_mutable(self) -> None:
147
+ """Ensure this instance is mutable (COW implementation)."""
148
+ if not self._cow_enabled:
149
+ return
150
+
151
+ if self._frozen:
152
+ # Create a new data dict (copy-on-write)
153
+ self._data = dict(self._data)
154
+ self._frozen = False
155
+ self._invalidate_cache()
156
+
157
+ def freeze(self) -> None:
158
+ """Freeze this instance for COW (called after first copy)."""
159
+ if self._cow_enabled:
160
+ self._frozen = True
161
+
162
+ def copy(self) -> 'DataInterchangeOptimizedStrategy':
163
+ """Create a COW copy of this strategy."""
164
+ if self._cow_enabled:
165
+ self.freeze()
166
+
167
+ # Create new instance sharing data until mutation
168
+ new_instance = DataInterchangeOptimizedStrategy(self.traits, **self.options)
169
+ new_instance._data = self._data # Shared until mutation
170
+ new_instance._size = self._size
171
+ new_instance._hash_cache = self._hash_cache
172
+ new_instance._frozen = False # New instance can be mutated
173
+
174
+ return new_instance
175
+
176
+ # ============================================================================
177
+ # STRUCTURAL HASH CACHING (xData Performance)
178
+ # ============================================================================
179
+
180
+ def _invalidate_cache(self) -> None:
181
+ """Invalidate cached hash (minimal overhead)."""
182
+ self._hash_cache = None
183
+
184
+ def structural_hash(self) -> int:
185
+ """Get structural hash with caching (xData equality optimization)."""
186
+ if self._hash_cache is None:
187
+ # Compute hash based on structure, not values
188
+ # This is optimized for xData's equality checking
189
+ self._hash_cache = calculate_structural_hash(self._data)
190
+
191
+ return self._hash_cache
192
+
193
+ def fast_equals(self, other: 'DataInterchangeOptimizedStrategy') -> bool:
194
+ """Fast equality check using structural hashes."""
195
+ if not isinstance(other, DataInterchangeOptimizedStrategy):
196
+ return False
197
+
198
+ # Quick size check
199
+ if self._size != other._size:
200
+ return False
201
+
202
+ # Structural hash comparison (much faster than deep comparison)
203
+ return self.structural_hash() == other.structural_hash()
204
+
205
+ # ============================================================================
206
+ # OBJECT POOLING SUPPORT (Factory Pattern)
207
+ # ============================================================================
208
+
209
+ def set_pool_reference(self, pool_ref: weakref.ref) -> None:
210
+ """Set reference to object pool for cleanup."""
211
+ self._pool_ref = pool_ref
212
+
213
+ def return_to_pool(self) -> None:
214
+ """Return this instance to object pool if available."""
215
+ if self._pool_ref is not None:
216
+ pool = self._pool_ref()
217
+ if pool is not None:
218
+ # Reset state for reuse
219
+ self._data.clear()
220
+ self._size = 0
221
+ self._invalidate_cache()
222
+ self._frozen = False
223
+ self._performance_tracker.reset()
224
+ pool.return_instance(self)
225
+
226
+ def __del__(self):
227
+ """Destructor with object pool support."""
228
+ self.return_to_pool()
229
+
230
+ # ============================================================================
231
+ # XDATA-SPECIFIC OPTIMIZATIONS
232
+ # ============================================================================
233
+
234
+ @property
235
+ def is_list(self) -> bool:
236
+ """Check if this represents a list (optimized for xData)."""
237
+ return is_sequential_numeric_keys(self._data)
238
+
239
+ @property
240
+ def is_dict(self) -> bool:
241
+ """Check if this represents a dict (optimized for xData)."""
242
+ return not self.is_list
243
+
244
+ @property
245
+ def is_leaf(self) -> bool:
246
+ """Check if this is a leaf node (xData pattern)."""
247
+ return len(self._data) == 1 and "value" in self._data
248
+
249
+ # ============================================================================
250
+ # PERFORMANCE MONITORING (Minimal Overhead)
251
+ # ============================================================================
252
+
253
+ @property
254
+ def backend_info(self) -> Dict[str, Any]:
255
+ """Get backend implementation info."""
256
+ return {
257
+ 'strategy': 'DATA_INTERCHANGE_OPTIMIZED',
258
+ 'backend': 'Optimized Python dict with COW',
259
+ 'complexity': {
260
+ 'get': 'O(1)',
261
+ 'put': 'O(1)',
262
+ 'has': 'O(1)',
263
+ 'delete': 'O(1)'
264
+ },
265
+ 'features': [
266
+ 'copy_on_write',
267
+ 'structural_hashing',
268
+ 'object_pooling',
269
+ 'slots_optimization'
270
+ ]
271
+ }
272
+
273
+ @property
274
+ def metrics(self) -> Dict[str, Any]:
275
+ """Get performance metrics."""
276
+ metrics = self._performance_tracker.get_metrics()
277
+ metrics.update({
278
+ 'size': self._size,
279
+ 'memory_usage': f"{self._size * 32} bytes (estimated)",
280
+ 'is_frozen': self._frozen,
281
+ 'hash_cached': self._hash_cache is not None,
282
+ 'cow_enabled': self._cow_enabled,
283
+ 'creation_time': self._creation_time
284
+ })
285
+ return metrics
286
+
287
+ def get_xdata_stats(self) -> Dict[str, Any]:
288
+ """Get xData-specific performance statistics."""
289
+ return {
290
+ 'strategy': 'DATA_INTERCHANGE_OPTIMIZED',
291
+ 'cow_active': self._cow_enabled,
292
+ 'frozen_state': self._frozen,
293
+ 'cache_efficiency': 'cached' if self._hash_cache else 'not_cached',
294
+ 'memory_footprint': 'minimal',
295
+ 'graph_overhead': 'zero',
296
+ 'pooling_support': self._pool_ref is not None,
297
+ 'access_pattern': f"{self._performance_tracker.get_metrics()['access_count']} operations"
298
+ }
299
+
300
+ # ============================================================================
301
+ # DISABLED FEATURES (Maximum Performance)
302
+ # ============================================================================
303
+
304
+ def get_ordered(self, start: Any = None, end: Any = None) -> List[tuple[Any, Any]]:
305
+ """Ordered operations not supported in DATA_INTERCHANGE_OPTIMIZED."""
306
+ raise XWNodeUnsupportedCapabilityError(
307
+ 'ordered_operations',
308
+ 'DATA_INTERCHANGE_OPTIMIZED',
309
+ ['fast_lookup', 'copy_on_write', 'structural_hashing']
310
+ ).suggest("Use preset='ANALYTICS' for ordered operations")
311
+
312
+ def get_with_prefix(self, prefix: str) -> List[tuple[Any, Any]]:
313
+ """Prefix operations not optimized in DATA_INTERCHANGE_OPTIMIZED."""
314
+ raise XWNodeUnsupportedCapabilityError(
315
+ 'prefix_operations',
316
+ 'DATA_INTERCHANGE_OPTIMIZED',
317
+ ['fast_lookup', 'copy_on_write']
318
+ ).suggest("Use preset='SEARCH_ENGINE' for prefix operations")
319
+
320
+ def get_priority(self) -> Optional[tuple[Any, Any]]:
321
+ """Priority operations not supported in DATA_INTERCHANGE_OPTIMIZED."""
322
+ raise XWNodeUnsupportedCapabilityError(
323
+ 'priority_operations',
324
+ 'DATA_INTERCHANGE_OPTIMIZED',
325
+ ['fast_lookup', 'copy_on_write']
326
+ ).suggest("Use preset='ANALYTICS' with heap structure for priorities")
327
+
328
+ # ============================================================================
329
+ # STRING REPRESENTATION (Optimized)
330
+ # ============================================================================
331
+
332
+ def __str__(self) -> str:
333
+ """Optimized string representation."""
334
+ return f"DataInterchangeOptimized(size={self._size}, cow={self._cow_enabled})"
335
+
336
+ def __repr__(self) -> str:
337
+ """Detailed string representation."""
338
+ return (f"DataInterchangeOptimizedStrategy(size={self._size}, "
339
+ f"frozen={self._frozen}, cow={self._cow_enabled}, "
340
+ f"cached={self._hash_cache is not None})")
341
+
342
+
343
+ # ============================================================================
344
+ # FACTORY FUNCTION
345
+ # ============================================================================
346
+
347
+ def create_data_interchange_optimized_strategy(**options) -> DataInterchangeOptimizedStrategy:
348
+ """
349
+ Factory function for creating data interchange optimized strategy instances.
350
+
351
+ This function provides the recommended way to create DATA_INTERCHANGE_OPTIMIZED
352
+ strategy instances with proper configuration for data interchange usage.
353
+ """
354
+ # Set data interchange specific optimizations
355
+ data_interchange_options = {
356
+ 'enable_cow': True,
357
+ 'enable_pooling': True,
358
+ 'enable_hash_caching': True,
359
+ 'minimal_metadata': True,
360
+ 'slots_optimization': True,
361
+ 'fast_creation': True,
362
+ 'lazy_loading': False, # Eager loading for predictability
363
+ 'memory_profile': 'ultra_minimal'
364
+ }
365
+
366
+ # Merge with user options
367
+ data_interchange_options.update(options)
368
+
369
+ return DataInterchangeOptimizedStrategy(NodeTrait.INDEXED, **data_interchange_options)
@@ -0,0 +1,209 @@
1
+ """
2
+ Priority Queue Strategy Implementation
3
+
4
+ Implements a priority queue using Python's heapq for efficient priority-based operations.
5
+
6
+ Company: eXonware.com
7
+ Author: Eng. Muhammad AlShehri
8
+ Email: connect@exonware.com
9
+ Version: 0.0.1.12
10
+ Generation Date: 07-Sep-2025
11
+ """
12
+
13
+ from typing import Any, Iterator, Optional, Dict, Union, Tuple
14
+ import heapq
15
+ from .base import ANodeLinearStrategy
16
+ from ...types import NodeMode, NodeTrait
17
+
18
+
19
+ class PriorityQueueStrategy(ANodeLinearStrategy):
20
+ """
21
+ Priority Queue node strategy for priority-based operations.
22
+
23
+ Uses a binary heap for efficient insertion and extraction of
24
+ highest priority elements, ideal for algorithms like Dijkstra's.
25
+ """
26
+
27
+ def __init__(self):
28
+ """Initialize an empty priority queue."""
29
+ super().__init__()
30
+ self._heap: List[Tuple[float, int, str, Any]] = [] # (priority, counter, key, value)
31
+ self._counter = 0 # For stable sorting
32
+ self._mode = NodeMode.PRIORITY_QUEUE
33
+ self._traits = {NodeTrait.PRIORITY, NodeTrait.FAST_INSERT, NodeTrait.FAST_DELETE}
34
+
35
+ def insert(self, key: str, value: Any) -> None:
36
+ """Insert an item with default priority (0)."""
37
+ self.insert_with_priority(key, value, 0.0)
38
+
39
+ def find(self, key: str) -> Optional[Any]:
40
+ """Find an item in the priority queue (O(n) operation)."""
41
+ for priority, counter, k, v in self._heap:
42
+ if k == key:
43
+ return v
44
+ return None
45
+
46
+ def delete(self, key: str) -> bool:
47
+ """Remove an item from the priority queue."""
48
+ for i, (priority, counter, k, v) in enumerate(self._heap):
49
+ if k == key:
50
+ self._heap.pop(i)
51
+ heapq.heapify(self._heap) # Re-heapify after removal
52
+ return True
53
+ return False
54
+
55
+ def size(self) -> int:
56
+ """Get the number of items in the priority queue."""
57
+ return len(self._heap)
58
+
59
+ def is_empty(self) -> bool:
60
+ """Check if the priority queue is empty."""
61
+ return len(self._heap) == 0
62
+
63
+ def to_native(self) -> Dict[str, Any]:
64
+ """Convert priority queue to native dictionary format."""
65
+ result = {}
66
+ for priority, counter, key, value in self._heap:
67
+ result[key] = value
68
+ return result
69
+
70
+ def from_native(self, data: Dict[str, Any]) -> None:
71
+ """Load priority queue from native dictionary format."""
72
+ self._heap.clear()
73
+ for key, value in data.items():
74
+ self.insert(key, value)
75
+
76
+ def insert_with_priority(self, key: str, value: Any, priority: float) -> None:
77
+ """Insert an item with specific priority."""
78
+ heapq.heappush(self._heap, (priority, self._counter, key, value))
79
+ self._counter += 1
80
+
81
+ def extract_min(self) -> Optional[Tuple[str, Any, float]]:
82
+ """Extract item with minimum priority."""
83
+ if self.is_empty():
84
+ return None
85
+
86
+ priority, counter, key, value = heapq.heappop(self._heap)
87
+ return (key, value, priority)
88
+
89
+ def extract_max(self) -> Optional[Tuple[str, Any, float]]:
90
+ """Extract item with maximum priority."""
91
+ if self.is_empty():
92
+ return None
93
+
94
+ # Convert to max-heap by negating priorities
95
+ max_heap = [(-priority, counter, key, value) for priority, counter, key, value in self._heap]
96
+ heapq.heapify(max_heap)
97
+
98
+ neg_priority, counter, key, value = heapq.heappop(max_heap)
99
+ priority = -neg_priority
100
+
101
+ # Remove from original heap
102
+ for i, (p, c, k, v) in enumerate(self._heap):
103
+ if k == key and c == counter:
104
+ self._heap.pop(i)
105
+ break
106
+
107
+ return (key, value, priority)
108
+
109
+ def peek_min(self) -> Optional[Tuple[str, Any, float]]:
110
+ """Peek at item with minimum priority without removing it."""
111
+ if self.is_empty():
112
+ return None
113
+
114
+ priority, counter, key, value = self._heap[0]
115
+ return (key, value, priority)
116
+
117
+ def peek_max(self) -> Optional[Tuple[str, Any, float]]:
118
+ """Peek at item with maximum priority without removing it."""
119
+ if self.is_empty():
120
+ return None
121
+
122
+ max_item = None
123
+ for priority, counter, key, value in self._heap:
124
+ if max_item is None or priority > max_item[2]:
125
+ max_item = (key, value, priority)
126
+
127
+ return max_item
128
+
129
+ def update_priority(self, key: str, new_priority: float) -> bool:
130
+ """Update the priority of an existing item."""
131
+ for i, (priority, counter, k, v) in enumerate(self._heap):
132
+ if k == key:
133
+ self._heap[i] = (new_priority, counter, k, v)
134
+ heapq.heapify(self._heap) # Re-heapify after update
135
+ return True
136
+ return False
137
+
138
+ def get_priority(self, key: str) -> Optional[float]:
139
+ """Get the priority of an item."""
140
+ for priority, counter, k, v in self._heap:
141
+ if k == key:
142
+ return priority
143
+ return None
144
+
145
+ def clear(self) -> None:
146
+ """Clear all items from the priority queue."""
147
+ self._heap.clear()
148
+ self._counter = 0
149
+
150
+ def get_at_index(self, index: int) -> Optional[Any]:
151
+ """Get item at specific index (not recommended for priority queue)."""
152
+ if 0 <= index < len(self._heap):
153
+ priority, counter, key, value = self._heap[index]
154
+ return value
155
+ return None
156
+
157
+ def push_front(self, value: Any) -> None:
158
+ """Push to front with high priority."""
159
+ key = f"item_{len(self._heap)}"
160
+ self.insert_with_priority(key, value, float('inf'))
161
+
162
+ def push_back(self, value: Any) -> None:
163
+ """Push to back with low priority."""
164
+ key = f"item_{len(self._heap)}"
165
+ self.insert_with_priority(key, value, float('-inf'))
166
+
167
+ def __iter__(self) -> Iterator[Any]:
168
+ """Iterate through items (order not guaranteed)."""
169
+ for priority, counter, key, value in self._heap:
170
+ yield value
171
+
172
+ def __repr__(self) -> str:
173
+ """String representation of the priority queue."""
174
+ min_item = self.peek_min()
175
+ max_item = self.peek_max()
176
+ 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})"
177
+
178
+ # Required abstract methods from base classes
179
+ def pop_front(self) -> Any:
180
+ """Remove element from front (same as extract_min for priority queue)."""
181
+ result = self.extract_min()
182
+ return result[1] if result else None
183
+
184
+ def pop_back(self) -> Any:
185
+ """Remove element from back (same as extract_max for priority queue)."""
186
+ result = self.extract_max()
187
+ return result[1] if result else None
188
+
189
+ def set_at_index(self, index: int, value: Any) -> None:
190
+ """Set element at index (not recommended for priority queue)."""
191
+ if 0 <= index < len(self._heap):
192
+ priority, counter, key, old_value = self._heap[index]
193
+ self._heap[index] = (priority, counter, key, value)
194
+
195
+ def as_linked_list(self):
196
+ """Provide LinkedList behavioral view."""
197
+ return self
198
+
199
+ def as_stack(self):
200
+ """Provide Stack behavioral view (not recommended)."""
201
+ raise NotImplementedError("PriorityQueue cannot behave as Stack")
202
+
203
+ def as_queue(self):
204
+ """Provide Queue behavioral view (not recommended)."""
205
+ raise NotImplementedError("PriorityQueue cannot behave as Queue")
206
+
207
+ def as_deque(self):
208
+ """Provide Deque behavioral view (not recommended)."""
209
+ raise NotImplementedError("PriorityQueue cannot behave as Deque")