lqft-python-engine 0.1.6__tar.gz → 0.1.8__tar.gz

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.
@@ -1,13 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lqft-python-engine
3
- Version: 0.1.6
4
- Summary: Log-Quantum Fractal Tree: Pattern-Aware Deduplicating Data Structure
3
+ Version: 0.1.8
4
+ Summary: LQFT Engine: High-Performance Deduplicating Data Structure (V4.4 Stable)
5
5
  Home-page: https://github.com/ParjadM/Log-Quantum-Fractal-Tree-LQFT-
6
6
  Author: Parjad Minooei
7
7
  License: MIT
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Programming Language :: Python :: 3.12
10
- Classifier: License :: OSI Approved :: MIT License
11
10
  Classifier: Operating System :: OS Independent
12
11
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
13
12
  Requires-Python: >=3.8
@@ -11,38 +11,39 @@
11
11
  #include <stdint.h>
12
12
 
13
13
  /**
14
- * LQFT C-Engine (Log-Quantum Fractal Tree) - V4.2 (Memory Safe Master Build)
14
+ * LQFT C-Engine - V4.4 (Large Payload Support)
15
15
  * Architect: Parjad Minooei
16
- * * INTEGRATED FIXES:
17
- * - 64-bit FNV-1a structural hashing (solves 32-bit collisions).
18
- * - Segment Indexing [i] to branch hashing (solves Ghost Sibling merges).
19
- * - Capped MAX_BITS to 64 to prevent Undefined Behavior.
20
- * - NEW: Global Registry Purge (free_all) for memory reclamation.
16
+ * * CHANGE LOG:
17
+ * - Removed fixed 8KB stack buffer in get_canonical.
18
+ * - Implemented Incremental FNV-1a Hashing to support multi-MB payloads.
19
+ * - Optimized string interning for high-concurrency memory safety.
21
20
  */
22
21
 
23
22
  #define BIT_PARTITION 5
24
23
  #define MAX_BITS 64
25
24
  #define MASK 0x1F
26
- #define REGISTRY_SIZE 8000009 // 8 Million prime slots
25
+ #define REGISTRY_SIZE 8000009
27
26
 
28
27
  typedef struct LQFTNode {
29
28
  void* value;
30
29
  uint64_t key_hash;
31
30
  struct LQFTNode* children[32];
32
- char struct_hash[17]; // 16 Hex chars + 1 Null terminator
31
+ char struct_hash[17];
33
32
  } LQFTNode;
34
33
 
35
- // Global Registry for Interning and Memory Management
36
- static LQFTNode* registry[REGISTRY_SIZE];
34
+ static LQFTNode** registry = NULL;
37
35
  static int physical_node_count = 0;
38
36
  static LQFTNode* global_root = NULL;
39
37
 
40
- // Upgraded to 64-bit FNV-1a Hash
41
- uint64_t fnv1a_64(const char* str) {
42
- uint64_t hash = 14695981039346656037ULL;
43
- while (*str) {
44
- hash ^= (uint8_t)(*str++);
45
- hash *= 1099511628211ULL;
38
+ // Incremental FNV-1a Constants
39
+ const uint64_t FNV_OFFSET_BASIS = 14695981039346656037ULL;
40
+ const uint64_t FNV_PRIME = 1099511628211ULL;
41
+
42
+ uint64_t fnv1a_update(uint64_t hash, const void* data, size_t len) {
43
+ const uint8_t* p = (const uint8_t*)data;
44
+ for (size_t i = 0; i < len; i++) {
45
+ hash ^= p[i];
46
+ hash *= FNV_PRIME;
46
47
  }
47
48
  return hash;
48
49
  }
@@ -56,8 +57,17 @@ char* portable_strdup(const char* s) {
56
57
  #endif
57
58
  }
58
59
 
60
+ static int init_registry() {
61
+ if (registry == NULL) {
62
+ registry = (LQFTNode**)calloc(REGISTRY_SIZE, sizeof(LQFTNode*));
63
+ if (registry == NULL) return 0;
64
+ }
65
+ return 1;
66
+ }
67
+
59
68
  LQFTNode* create_node(void* value, uint64_t key_hash) {
60
69
  LQFTNode* node = (LQFTNode*)malloc(sizeof(LQFTNode));
70
+ if (!node) return NULL;
61
71
  node->value = value;
62
72
  node->key_hash = key_hash;
63
73
  for (int i = 0; i < 32; i++) node->children[i] = NULL;
@@ -65,22 +75,30 @@ LQFTNode* create_node(void* value, uint64_t key_hash) {
65
75
  }
66
76
 
67
77
  LQFTNode* get_canonical(void* value, uint64_t key_hash, LQFTNode** children) {
68
- char buffer[8192] = { 0 };
78
+ if (!init_registry()) return NULL;
79
+
80
+ // V4.4 REFACTOR: Incremental hashing instead of sprintf concatenation
81
+ // This avoids the 8KB buffer overflow for large payloads.
82
+ uint64_t full_hash = FNV_OFFSET_BASIS;
83
+
69
84
  if (value != NULL) {
70
- sprintf(buffer, "leaf:%s:%llu", (char*)value, (unsigned long long)key_hash);
85
+ const char* prefix = "leaf:";
86
+ full_hash = fnv1a_update(full_hash, prefix, 5);
87
+ full_hash = fnv1a_update(full_hash, value, strlen((char*)value));
88
+ full_hash = fnv1a_update(full_hash, &key_hash, sizeof(uint64_t));
71
89
  } else {
72
- sprintf(buffer, "branch:");
73
- for (int i = 0; i < 32; i++) {
74
- if (children && children[i]) {
75
- char seg_buf[32];
76
- // FIX: Adding [%d] prevents identically hashed children in different slots from merging
77
- sprintf(seg_buf, "[%d]%s", i, children[i]->struct_hash);
78
- strcat(buffer, seg_buf);
90
+ const char* prefix = "branch:";
91
+ full_hash = fnv1a_update(full_hash, prefix, 7);
92
+ if (children) {
93
+ for (int i = 0; i < 32; i++) {
94
+ if (children[i]) {
95
+ full_hash = fnv1a_update(full_hash, &i, sizeof(int));
96
+ full_hash = fnv1a_update(full_hash, children[i]->struct_hash, 16);
97
+ }
79
98
  }
80
99
  }
81
100
  }
82
101
 
83
- uint64_t full_hash = fnv1a_64(buffer);
84
102
  char lookup_hash[17];
85
103
  sprintf(lookup_hash, "%016llx", (unsigned long long)full_hash);
86
104
  uint32_t idx = full_hash % REGISTRY_SIZE;
@@ -88,7 +106,6 @@ LQFTNode* get_canonical(void* value, uint64_t key_hash, LQFTNode** children) {
88
106
  uint32_t start_idx = idx;
89
107
  while (registry[idx] != NULL) {
90
108
  if (strcmp(registry[idx]->struct_hash, lookup_hash) == 0) {
91
- // Found existing node; free the duplicated value string if provided
92
109
  if (value) free(value);
93
110
  return registry[idx];
94
111
  }
@@ -97,6 +114,7 @@ LQFTNode* get_canonical(void* value, uint64_t key_hash, LQFTNode** children) {
97
114
  }
98
115
 
99
116
  LQFTNode* new_node = create_node(value, key_hash);
117
+ if (!new_node) return NULL;
100
118
  if (children) {
101
119
  for (int i = 0; i < 32; i++) new_node->children[i] = children[i];
102
120
  }
@@ -106,35 +124,30 @@ LQFTNode* get_canonical(void* value, uint64_t key_hash, LQFTNode** children) {
106
124
  return new_node;
107
125
  }
108
126
 
109
- // --- MEMORY RECLAMATION ---
110
-
111
127
  static PyObject* method_free_all(PyObject* self, PyObject* args) {
112
- int freed_count = 0;
113
- for (int i = 0; i < REGISTRY_SIZE; i++) {
114
- if (registry[i] != NULL) {
115
- if (registry[i]->value) {
116
- free(registry[i]->value);
128
+ if (registry != NULL) {
129
+ for (int i = 0; i < REGISTRY_SIZE; i++) {
130
+ if (registry[i] != NULL) {
131
+ if (registry[i]->value) free(registry[i]->value);
132
+ free(registry[i]);
133
+ registry[i] = NULL;
117
134
  }
118
- free(registry[i]);
119
- registry[i] = NULL;
120
- freed_count++;
121
135
  }
136
+ free(registry);
137
+ registry = NULL;
122
138
  }
123
139
  physical_node_count = 0;
124
- global_root = NULL; // Reset root for next use
125
- return PyLong_FromLong(freed_count);
140
+ global_root = NULL;
141
+ Py_RETURN_NONE;
126
142
  }
127
143
 
128
- // --- PYTHON API BRIDGE ---
129
-
130
144
  static PyObject* method_insert(PyObject* self, PyObject* args) {
131
145
  unsigned long long h;
132
146
  char* val_str;
133
147
  if (!PyArg_ParseTuple(args, "Ks", &h, &val_str)) return NULL;
134
148
 
135
149
  if (!global_root) {
136
- // First run initialization
137
- for (int i = 0; i < REGISTRY_SIZE; i++) registry[i] = NULL;
150
+ if (!init_registry()) return PyErr_NoMemory();
138
151
  global_root = get_canonical(NULL, 0, NULL);
139
152
  }
140
153
 
@@ -145,7 +158,6 @@ static PyObject* method_insert(PyObject* self, PyObject* args) {
145
158
  LQFTNode* curr = global_root;
146
159
  int bit_depth = 0;
147
160
 
148
- // 1. Traversal
149
161
  while (curr != NULL && curr->value == NULL) {
150
162
  uint32_t segment = (h >> bit_depth) & MASK;
151
163
  path_nodes[path_len] = curr;
@@ -160,7 +172,6 @@ static PyObject* method_insert(PyObject* self, PyObject* args) {
160
172
  bit_depth += BIT_PARTITION;
161
173
  }
162
174
 
163
- // 2. Node Update
164
175
  LQFTNode* new_sub_node = NULL;
165
176
  if (curr == NULL) {
166
177
  new_sub_node = get_canonical(portable_strdup(val_str), h, NULL);
@@ -178,11 +189,9 @@ static PyObject* method_insert(PyObject* self, PyObject* args) {
178
189
  if (s_old != s_new) {
179
190
  LQFTNode* c_old = get_canonical(old_val, old_h, curr->children);
180
191
  LQFTNode* c_new = get_canonical(portable_strdup(val_str), h, NULL);
181
-
182
192
  LQFTNode* new_children[32] = {NULL};
183
193
  new_children[s_old] = c_old;
184
194
  new_children[s_new] = c_new;
185
-
186
195
  new_sub_node = get_canonical(NULL, 0, new_children);
187
196
  break;
188
197
  } else {
@@ -192,12 +201,9 @@ static PyObject* method_insert(PyObject* self, PyObject* args) {
192
201
  temp_depth += BIT_PARTITION;
193
202
  }
194
203
  }
195
- if (new_sub_node == NULL) {
196
- new_sub_node = get_canonical(portable_strdup(val_str), h, curr->children);
197
- }
204
+ if (new_sub_node == NULL) new_sub_node = get_canonical(portable_strdup(val_str), h, curr->children);
198
205
  }
199
206
 
200
- // 3. Iterative Back-Propagation
201
207
  for (int i = path_len - 1; i >= 0; i--) {
202
208
  if (path_nodes[i] == NULL) {
203
209
  LQFTNode* new_children[32] = {NULL};
@@ -220,22 +226,16 @@ static PyObject* method_insert(PyObject* self, PyObject* args) {
220
226
  static PyObject* method_search(PyObject* self, PyObject* args) {
221
227
  unsigned long long h;
222
228
  if (!PyArg_ParseTuple(args, "K", &h)) return NULL;
223
- if (!global_root) { Py_RETURN_NONE; }
229
+ if (!global_root) Py_RETURN_NONE;
224
230
 
225
231
  LQFTNode* curr = global_root;
226
232
  int bit_depth = 0;
227
-
228
- while (curr != NULL) {
229
- if (curr->value != NULL) {
230
- if (curr->key_hash == h) return PyUnicode_FromString((char*)curr->value);
231
- Py_RETURN_NONE;
232
- }
233
+ while (curr != NULL && curr->value == NULL) {
233
234
  uint32_t segment = (h >> bit_depth) & MASK;
234
- if (curr->children[segment] == NULL) { Py_RETURN_NONE; }
235
235
  curr = curr->children[segment];
236
236
  bit_depth += BIT_PARTITION;
237
- if (bit_depth >= MAX_BITS) break;
238
237
  }
238
+ if (curr != NULL && curr->key_hash == h) return PyUnicode_FromString((char*)curr->value);
239
239
  Py_RETURN_NONE;
240
240
  }
241
241
 
@@ -244,17 +244,13 @@ static PyObject* method_get_metrics(PyObject* self, PyObject* args) {
244
244
  }
245
245
 
246
246
  static PyMethodDef LQFTMethods[] = {
247
- {"insert", method_insert, METH_VARARGS, "Insert into C LQFT"},
248
- {"search", method_search, METH_VARARGS, "Search C LQFT"},
249
- {"get_metrics", method_get_metrics, METH_VARARGS, "Get memory metrics"},
250
- {"free_all", method_free_all, METH_VARARGS, "Clear all C memory"},
247
+ {"insert", method_insert, METH_VARARGS, "Insert payload"},
248
+ {"search", method_search, METH_VARARGS, "Search hash"},
249
+ {"get_metrics", method_get_metrics, METH_VARARGS, "Get metrics"},
250
+ {"free_all", method_free_all, METH_VARARGS, "Reclaim memory"},
251
251
  {NULL, NULL, 0, NULL}
252
252
  };
253
253
 
254
- static struct PyModuleDef lqftmodule = {
255
- PyModuleDef_HEAD_INIT, "lqft_c_engine", "LQFT Performance Engine", -1, LQFTMethods
256
- };
254
+ static struct PyModuleDef lqftmodule = { PyModuleDef_HEAD_INIT, "lqft_c_engine", NULL, -1, LQFTMethods };
257
255
 
258
- PyMODINIT_FUNC PyInit_lqft_c_engine(void) {
259
- return PyModule_Create(&lqftmodule);
260
- }
256
+ PyMODINIT_FUNC PyInit_lqft_c_engine(void) { return PyModule_Create(&lqftmodule); }
@@ -1,13 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lqft-python-engine
3
- Version: 0.1.6
4
- Summary: Log-Quantum Fractal Tree: Pattern-Aware Deduplicating Data Structure
3
+ Version: 0.1.8
4
+ Summary: LQFT Engine: High-Performance Deduplicating Data Structure (V4.4 Stable)
5
5
  Home-page: https://github.com/ParjadM/Log-Quantum-Fractal-Tree-LQFT-
6
6
  Author: Parjad Minooei
7
7
  License: MIT
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Programming Language :: Python :: 3.12
10
- Classifier: License :: OSI Approved :: MIT License
11
10
  Classifier: Operating System :: OS Independent
12
11
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
13
12
  Requires-Python: >=3.8
@@ -1,6 +1,7 @@
1
1
  LICENSE.md
2
2
  lqft_engine.c
3
3
  lqft_engine.py
4
+ pure_python_ds.py
4
5
  pyproject.toml
5
6
  setup.py
6
7
  lqft_python_engine.egg-info/PKG-INFO
@@ -1,2 +1,3 @@
1
1
  lqft_c_engine
2
2
  lqft_engine
3
+ pure_python_ds
@@ -0,0 +1,139 @@
1
+ import struct
2
+
3
+ # ---------------------------------------------------------
4
+ # 1. DETERMINISTIC HASHING (FNV-1a 64-bit)
5
+ # ---------------------------------------------------------
6
+ def fnv1a_64(key: str) -> int:
7
+ """Generates a strict 64-bit deterministic hash for O(1) routing."""
8
+ hval = 0xcbf29ce484222325
9
+ fnv_prime = 0x100000001b3
10
+ for byte in key.encode('utf-8'):
11
+ hval ^= byte
12
+ hval = (hval * fnv_prime) & 0xFFFFFFFFFFFFFFFF
13
+ return hval
14
+
15
+ def combine_hashes(hashes: list) -> int:
16
+ """Combines child Merkle hashes to generate a parent's structural hash."""
17
+ hval = 0
18
+ for h in hashes:
19
+ if h is not None:
20
+ hval ^= h
21
+ hval = (hval * 0x100000001b3) & 0xFFFFFFFFFFFFFFFF
22
+ return hval
23
+
24
+ # ---------------------------------------------------------
25
+ # 2. GLOBAL C-REGISTRY MOCK (Structural Folding)
26
+ # ---------------------------------------------------------
27
+ # Maps a Merkle Hash -> Physical Node Instance
28
+ NODE_REGISTRY = {}
29
+
30
+ class LQFTNode:
31
+ """A fixed 32-way routing node."""
32
+ __slots__ = ('children', 'value', 'merkle_hash')
33
+
34
+ def __init__(self, value=None):
35
+ self.children = [None] * 32
36
+ self.value = value
37
+ self.merkle_hash = None
38
+
39
+ def get_deduplicated_node(node: LQFTNode) -> LQFTNode:
40
+ """
41
+ The core of O(Σ) Space Complexity.
42
+ If a node with this exact structure exists, return the existing memory pointer.
43
+ Otherwise, register this new node.
44
+ """
45
+ # Calculate structural Merkle Hash
46
+ child_hashes = [c.merkle_hash if c else None for c in node.children]
47
+ base_hash = fnv1a_64(str(node.value)) if node.value is not None else 0
48
+ node.merkle_hash = (base_hash ^ combine_hashes(child_hashes)) & 0xFFFFFFFFFFFFFFFF
49
+
50
+ # Structural Folding (Deduplication)
51
+ if node.merkle_hash in NODE_REGISTRY:
52
+ return NODE_REGISTRY[node.merkle_hash]
53
+
54
+ NODE_REGISTRY[node.merkle_hash] = node
55
+ return node
56
+
57
+ # ---------------------------------------------------------
58
+ # 3. THE LQFT ARCHITECTURE (Strictly Iterative)
59
+ # ---------------------------------------------------------
60
+ class LQFT:
61
+ def __init__(self):
62
+ self.root = get_deduplicated_node(LQFTNode())
63
+
64
+ def insert(self, key: str, value: any):
65
+ """
66
+ O(1) Insertion. Capped at exactly 13 hops.
67
+ STRICTLY ITERATIVE. NO RECURSION ALLOWED.
68
+ """
69
+ key_hash = fnv1a_64(key)
70
+
71
+ # Step 1: Iterative Traversal Down
72
+ # We store the path to allow bottom-up Merkle folding without recursion
73
+ path_stack = []
74
+ current = self.root
75
+
76
+ for level in range(13): # Fixed 64-bit space (13 chunks of 5 bits)
77
+ index = (key_hash >> (level * 5)) & 0x1F # Mask 5 bits
78
+ path_stack.append((current, index))
79
+
80
+ if current.children[index] is None:
81
+ current = LQFTNode() # Create empty node for routing
82
+ else:
83
+ current = current.children[index]
84
+
85
+ # Step 2: Create the Leaf Node
86
+ new_leaf = LQFTNode(value=value)
87
+ current = get_deduplicated_node(new_leaf)
88
+
89
+ # Step 3: Iterative Bottom-Up Folding (Copy-on-Write)
90
+ while path_stack:
91
+ parent_node, index = path_stack.pop()
92
+
93
+ # Create a copy of the parent to ensure immutability/versioning
94
+ new_parent = LQFTNode()
95
+ new_parent.children = list(parent_node.children) # Copy references
96
+ new_parent.children[index] = current # Attach the new folded child
97
+
98
+ # Deduplicate the new parent
99
+ current = get_deduplicated_node(new_parent)
100
+
101
+ # The final deduplicated node becomes the new root
102
+ self.root = current
103
+
104
+ def search(self, key: str) -> any:
105
+ """O(1) Search. Guaranteed max 13 hops. Iterative."""
106
+ key_hash = fnv1a_64(key)
107
+ current = self.root
108
+
109
+ for level in range(13):
110
+ index = (key_hash >> (level * 5)) & 0x1F
111
+ current = current.children[index]
112
+ if current is None:
113
+ return None # Key not found
114
+
115
+ # FIXED: This return statement is now outside the loop!
116
+ return current.value
117
+
118
+ # Make it easy to use like standard Python Dicts
119
+ def __setitem__(self, key, value):
120
+ self.insert(key, value)
121
+
122
+ def __getitem__(self, key):
123
+ res = self.search(key)
124
+ if res is None:
125
+ raise KeyError(key)
126
+ return res
127
+
128
+ # ---------------------------------------------------------
129
+ # 4. EASY API (The "Heapify" Equivalent)
130
+ # ---------------------------------------------------------
131
+ def build_lqft(iterable) -> LQFT:
132
+ """
133
+ Instantiates and builds an LQFT in O(1) interface time.
134
+ Usage: tree = build_lqft([("user1", "dataA"), ("user2", "dataB")])
135
+ """
136
+ tree = LQFT()
137
+ for key, value in iterable:
138
+ tree.insert(key, value)
139
+ return tree
@@ -4,16 +4,16 @@ import sys
4
4
 
5
5
  # Systems Architect Logic: Cross-Platform Compiler Detection
6
6
  extra_compile_args = []
7
-
8
7
  if os.name == 'nt':
9
8
  if 'gcc' in sys.version.lower() or 'mingw' in sys.executable.lower():
10
9
  extra_compile_args = ['-O3']
11
10
  else:
12
- extra_compile_args = ['/O2']
11
+ # MSVC specific optimization and security flags
12
+ extra_compile_args = ['/O2', '/D_CRT_SECURE_NO_WARNINGS']
13
13
  else:
14
14
  extra_compile_args = ['-O3']
15
15
 
16
- # Load README for PyPI long_description (Bulletproof File Check)
16
+ # Load README for PyPI long_description
17
17
  long_description = "Log-Quantum Fractal Tree Engine"
18
18
  if os.path.exists("readme.md"):
19
19
  with open("readme.md", "r", encoding="utf-8") as fh:
@@ -26,26 +26,24 @@ lqft_extension = Extension(
26
26
  'lqft_c_engine',
27
27
  sources=['lqft_engine.c'],
28
28
  extra_compile_args=extra_compile_args,
29
- define_macros=[('_CRT_SECURE_NO_WARNINGS', '1')]
30
29
  )
31
30
 
32
31
  setup(
33
32
  name="lqft-python-engine",
34
- version="0.1.6", # Bumped for PyPI release
35
- description="Log-Quantum Fractal Tree: Pattern-Aware Deduplicating Data Structure",
33
+ version="0.1.8",
34
+ description="LQFT Engine: High-Performance Deduplicating Data Structure (V4.4 Stable)",
36
35
  long_description=long_description,
37
36
  long_description_content_type="text/markdown",
38
37
  author="Parjad Minooei",
39
38
  url="https://github.com/ParjadM/Log-Quantum-Fractal-Tree-LQFT-",
40
39
  ext_modules=[lqft_extension],
41
40
  packages=find_packages(),
42
- py_modules=["lqft_engine"],
41
+ py_modules=["lqft_engine", "pure_python_ds"],
43
42
  install_requires=['psutil'],
44
43
  license="MIT",
45
44
  classifiers=[
46
45
  "Programming Language :: Python :: 3",
47
46
  "Programming Language :: Python :: 3.12",
48
- "License :: OSI Approved :: MIT License",
49
47
  "Operating System :: OS Independent",
50
48
  "Topic :: Software Development :: Libraries :: Python Modules",
51
49
  ],