-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Expand file tree
/
Copy pathgraph_buffer.h
More file actions
178 lines (136 loc) · 8.3 KB
/
Copy pathgraph_buffer.h
File metadata and controls
178 lines (136 loc) · 8.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*
* graph_buffer.h — In-memory graph buffer for pipeline indexing.
*
* Holds all nodes and edges in RAM during indexing, then dumps to SQLite.
* Provides O(1) node lookup by qualified name and edge dedup by key.
*
* Depends on: foundation (hash_table, dyn_array), store (data structs)
*/
#ifndef CBM_GRAPH_BUFFER_H
#define CBM_GRAPH_BUFFER_H
#include <stdbool.h>
#include <stdint.h>
#include <stdatomic.h>
/* ── Opaque handle ──────────────────────────────────────────────── */
typedef struct cbm_gbuf cbm_gbuf_t;
/* Forward declare store for dump path */
typedef struct cbm_store cbm_store_t;
/* ── Node / Edge structs (owned by the buffer) ───────────────────── */
typedef struct {
int64_t id; /* temp ID (sequential from 1) */
char *label; /* heap-owned */
char *name; /* heap-owned */
char *qualified_name; /* heap-owned */
char *file_path; /* heap-owned */
int start_line;
int end_line;
char *properties_json; /* heap-owned JSON string, "{}" default */
} cbm_gbuf_node_t;
typedef struct {
int64_t id; /* temp ID */
int64_t source_id; /* temp node ID */
int64_t target_id; /* temp node ID */
char *type; /* heap-owned */
char *properties_json; /* heap-owned JSON string, "{}" default */
} cbm_gbuf_edge_t;
/* ── Lifecycle ──────────────────────────────────────────────────── */
/* Create a new graph buffer for a project. */
cbm_gbuf_t *cbm_gbuf_new(const char *project, const char *root_path);
/* Create a graph buffer with a shared atomic ID source.
* IDs are allocated via atomic_fetch_add on *id_source.
* Used for parallel extraction where multiple gbufs need unique IDs.
* If id_source is NULL, behaves like cbm_gbuf_new(). */
cbm_gbuf_t *cbm_gbuf_new_shared_ids(const char *project, const char *root_path,
_Atomic int64_t *id_source);
/* Free the graph buffer and all owned data. NULL-safe. */
void cbm_gbuf_free(cbm_gbuf_t *gb);
/* Merge all nodes and edges from src into dst.
* Nodes are merged by QN: on collision, src wins (updates dst node fields).
* New nodes are inserted with their original IDs (from shared ID source).
* Edges are remapped for any QN-colliding nodes, then inserted with dedup.
* After merge, src can be safely freed (all data is copied).
* Returns 0 on success, -1 on error. */
int cbm_gbuf_merge(cbm_gbuf_t *dst, cbm_gbuf_t *src);
/* ── Node operations ─────────────────────────────────────────────── */
/* Upsert a node by qualified name. Returns the temp ID.
* All string fields are copied (buffer owns the copies).
* Returns 0 on error. */
int64_t cbm_gbuf_upsert_node(cbm_gbuf_t *gb, const char *label, const char *name,
const char *qualified_name, const char *file_path, int start_line,
int end_line, const char *properties_json);
/* Find a node by qualified name. Returns NULL if not found. */
const cbm_gbuf_node_t *cbm_gbuf_find_by_qn(const cbm_gbuf_t *gb, const char *qn);
/* Find a node by temp ID. Returns NULL if not found. */
const cbm_gbuf_node_t *cbm_gbuf_find_by_id(const cbm_gbuf_t *gb, int64_t id);
/* Find nodes by label. Sets *out and *count. Caller does NOT free.
* Returns 0 on success, -1 on error. */
int cbm_gbuf_find_by_label(const cbm_gbuf_t *gb, const char *label, const cbm_gbuf_node_t ***out,
int *count);
/* Find nodes by name (exact). Sets *out and *count. Caller does NOT free. */
int cbm_gbuf_find_by_name(const cbm_gbuf_t *gb, const char *name, const cbm_gbuf_node_t ***out,
int *count);
/* Count total nodes in buffer. */
int cbm_gbuf_node_count(const cbm_gbuf_t *gb);
/* Get the next ID that would be assigned. Used to initialize shared atomic counters. */
int64_t cbm_gbuf_next_id(const cbm_gbuf_t *gb);
/* Set the next ID counter. Used after merging worker gbufs to sync the main counter. */
void cbm_gbuf_set_next_id(cbm_gbuf_t *gb, int64_t next_id);
/* Delete all nodes with a label. Cascade-deletes referencing edges. */
int cbm_gbuf_delete_by_label(cbm_gbuf_t *gb, const char *label);
/* Delete all nodes for a given file path. Cascade-deletes referencing edges.
* Used by incremental indexing to remove stale nodes before re-extraction. */
int cbm_gbuf_delete_by_file(cbm_gbuf_t *gb, const char *file_path);
/* Bulk-load all nodes and edges for a project from an existing SQLite DB
* into this graph buffer. Returns 0 on success. */
int cbm_gbuf_load_from_db(cbm_gbuf_t *gb, const char *db_path, const char *project);
/* Iterate all live nodes (not deleted from QN index). */
typedef void (*cbm_gbuf_node_visitor_fn)(const cbm_gbuf_node_t *node, void *userdata);
void cbm_gbuf_foreach_node(const cbm_gbuf_t *gb, cbm_gbuf_node_visitor_fn fn, void *userdata);
/* Iterate all edges. */
typedef void (*cbm_gbuf_edge_visitor_fn)(const cbm_gbuf_edge_t *edge, void *userdata);
void cbm_gbuf_foreach_edge(const cbm_gbuf_t *gb, cbm_gbuf_edge_visitor_fn fn, void *userdata);
/* ── Edge operations ─────────────────────────────────────────────── */
/* Insert an edge. Deduplicates by (source_id, target_id, type).
* On duplicate, merges properties (later wins). Returns edge temp ID.
* Returns 0 on error. */
int64_t cbm_gbuf_insert_edge(cbm_gbuf_t *gb, int64_t source_id, int64_t target_id, const char *type,
const char *properties_json);
/* Find edges from source_id with given type.
* Sets *out and *count. Caller does NOT free. */
int cbm_gbuf_find_edges_by_source_type(const cbm_gbuf_t *gb, int64_t source_id, const char *type,
const cbm_gbuf_edge_t ***out, int *count);
/* Find edges to target_id with given type. */
int cbm_gbuf_find_edges_by_target_type(const cbm_gbuf_t *gb, int64_t target_id, const char *type,
const cbm_gbuf_edge_t ***out, int *count);
/* Find all edges of a given type. */
int cbm_gbuf_find_edges_by_type(const cbm_gbuf_t *gb, const char *type,
const cbm_gbuf_edge_t ***out, int *count);
/* Count total edges. */
int cbm_gbuf_edge_count(const cbm_gbuf_t *gb);
/* Count edges of a given type. */
int cbm_gbuf_edge_count_by_type(const cbm_gbuf_t *gb, const char *type);
/* Delete all edges of a type. */
int cbm_gbuf_delete_edges_by_type(cbm_gbuf_t *gb, const char *type);
/* ── Vector storage (for semantic embeddings) ───────────────────── */
/* Store an int8-quantized vector for a node. The vector data is copied.
* Called by pass_semantic_edges after computing RI vectors.
* Vectors are carried through to cbm_write_db during the dump phase. */
int cbm_gbuf_store_vector(cbm_gbuf_t *gb, int64_t node_id, const uint8_t *vector, int vector_len);
/* Store an enriched token vector for query-time lookup.
* Called by pass_semantic_edges after corpus finalization.
* Token string and vector data are copied. */
int cbm_gbuf_store_token_vector(cbm_gbuf_t *gb, const char *token, const uint8_t *vector,
int vector_len, float idf);
/* ── Dump to SQLite ──────────────────────────────────────────────── */
/* Dump the entire buffer to a SQLite file using the direct page writer.
* Assigns sequential final IDs and remaps edge references.
* Returns 0 on success, -1 on error. */
int cbm_gbuf_dump_to_sqlite(cbm_gbuf_t *gb, const char *path);
/* Flush the buffer to an existing store via the store API.
* Deletes existing project data first. Returns 0 on success. */
int cbm_gbuf_flush_to_store(cbm_gbuf_t *gb, cbm_store_t *store);
/* Merge the buffer into an existing store WITHOUT deleting existing data.
* Upserts nodes, inserts edges. Used for incremental indexing.
* Returns 0 on success. */
int cbm_gbuf_merge_into_store(cbm_gbuf_t *gb, cbm_store_t *store);
#endif /* CBM_GRAPH_BUFFER_H */