43 return std::string(DataDir) +
"/base/" + std::to_string(db_oid) +
"/" + filename;
70 auto [idx, created] =
mapping.add(token);
81 &&
gates[idx].nb_children == 0;
82 bool real_create = type !=
gate_input || !children.empty();
83 if(placeholder && real_create) {
84 gates[idx].type = type;
85 gates[idx].nb_children =
static_cast<unsigned>(children.size());
87 for(
const auto &c: children)
89 for(
const auto &c: children) {
90 auto [child_idx, child_created] =
mapping.add(c);
98 gates.add({type,
static_cast<unsigned>(children.size()),
wires.nbElements()});
99 for(
const auto &c: children)
102 for(
const auto &c: children) {
103 auto [child_idx, child_created] =
mapping.add(c);
115 return gates[idx].type;
120 std::vector<pg_uuid_t> result;
125 result.push_back(
wires[k]);
132 auto [idx, created] =
mapping.add(token);
136 gates[idx].prob = prob;
149 return gates[idx].prob;
156 gates[idx].info1=info1;
157 gates[idx].info2=info2;
168 gates[idx].extra_len=s.size();
176 return std::make_pair(0, 0);
189 for(
unsigned long start=
gates[idx].extra_idx, k=start, end=start+
gates[idx].extra_len; k<end; ++k)
211 while(
READM(c,
char)) {
213 if(!
READM(db_oid, Oid))
223 unsigned nb_children;
228 std::vector<pg_uuid_t> children(nb_children);
229 for(
unsigned i=0; i<nb_children; ++i)
245 bool ok = circuit->
setProb(token, prob);
246 char return_value = ok?
static_cast<char>(1):0;
248 if(!
WRITEB(&return_value,
char))
249 provsql_error(
"Cannot write response to pipe (message type P)");
256 unsigned info1, info2;
261 circuit->
setInfos(token, info1, info2);
274 char *data =
new char[len];
278 circuit->
setExtra(token, std::string(data, len));
294 provsql_error(
"Cannot write response to pipe (message type t)");
302 if(!
WRITEB(&nb,
unsigned long))
303 provsql_error(
"Cannot write response to pipe (message type n)");
315 unsigned nb_children = children.size();
316 if(!
WRITEB(&nb_children,
unsigned))
317 provsql_error(
"Cannot write response to pipe (message type c)");
320 provsql_error(
"Cannot write response to pipe (message type c)");
331 double prob = circuit->
getProb(token);
333 if(!
WRITEB(&prob,
double))
334 provsql_error(
"Cannot write response to pipe (message type p)");
345 auto infos = circuit->
getInfos(token);
347 if(!
WRITEB(&infos.first,
unsigned) || !
WRITEB(&infos.second,
unsigned))
348 provsql_error(
"Cannot write response to pipe (message type i)");
359 auto str = circuit->
getExtra(token);
360 unsigned len = str.size();
363 provsql_error(
"Cannot write response to pipe (message type e)");
374 std::stringstream ss;
375 boost::archive::binary_oarchive oa(ss);
378 ss.seekg(0, std::ios::end);
379 unsigned long size = ss.tellg();
380 ss.seekg(0, std::ios::beg);
408 if(!
READM(relid, Oid))
418 if(!
READM(relid, Oid))
421 char found = circuit->
getTableInfo(relid, info) ? 1 : 0;
423 provsql_error(
"Cannot write response to pipe (message type s)");
426 provsql_error(
"Cannot write response to pipe (message type s)");
429 provsql_error(
"Cannot write response to pipe (message type s)");
440 if(!
READM(relid, Oid) || !
READM(ancestor_n, uint16_t))
447 for(uint16_t i=0; i<ancestor_n; ++i)
448 if(!
READM(ancestors[i], Oid))
458 if(!
READM(relid, Oid))
468 if(!
READM(relid, Oid))
471 char found = circuit->
getTableInfo(relid, info) ? 1 : 0;
473 provsql_error(
"Cannot write response to pipe (message type a)");
476 provsql_error(
"Cannot write response to pipe (message type a)");
479 provsql_error(
"Cannot write response to pipe (message type a)");
492 if(!
READM(nb_roots,
unsigned))
495 std::vector<pg_uuid_t> roots(nb_roots);
496 for(
unsigned i=0; i<nb_roots; ++i)
500 std::stringstream ss;
501 boost::archive::binary_oarchive oa(ss);
504 ss.seekg(0, std::ios::end);
505 unsigned long size = ss.tellg();
506 ss.seekg(0, std::ios::beg);
553 unsigned long n =
tableInfo.nbElements();
554 for(
unsigned long i=0; i<n; ++i) {
564 if(tombstone < 0 &&
tableInfo[i].relid == InvalidOid)
565 tombstone =
static_cast<long>(i);
577 const Oid *ancestors)
579 if(relid == InvalidOid)
583 unsigned long n =
tableInfo.nbElements();
584 for(
unsigned long i=0; i<n; ++i) {
588 memcpy(updated.
ancestors, ancestors, ancestor_n *
sizeof(Oid));
602 if(relid == InvalidOid)
604 unsigned long n =
tableInfo.nbElements();
605 for(
unsigned long i=0; i<n; ++i) {
615 if(relid == InvalidOid)
617 unsigned long n =
tableInfo.nbElements();
618 for(
unsigned long i=0; i<n; ++i) {
628 if(relid == InvalidOid)
630 for(
unsigned long i=0; i<
tableInfo.nbElements(); ++i) {
647 return memcmp(&a, &b,
sizeof(
pg_uuid_t))<0;
656 const std::vector<pg_uuid_t> &roots)
const
664 std::set<pg_uuid_t> to_process, processed;
665 for(
const auto &r : roots)
666 to_process.insert(r);
670 while(!to_process.empty()) {
672 to_process.erase(to_process.begin());
673 processed.insert(uuid);
679 if(!std::isnan(prob))
682 std::vector<pg_uuid_t> children =
getChildren(uuid);
683 for(
unsigned i=0; i<children.size(); ++i) {
687 if(processed.find(children[i])==processed.end())
688 to_process.insert(children[i]);
693 auto [info1, info2] =
getInfos(uuid);
gate_t
Strongly-typed gate identifier.
Out-of-line template method implementations for Circuit<gateType>.
Semiring-agnostic in-memory provenance circuit.
static std::map< Oid, MMappedCircuit * > circuits
Per-database mmap-backed provenance circuits, keyed by database OID.
void destroy_provsql_mmap()
Unmap and close the mmap files.
bool operator<(const pg_uuid_t a, const pg_uuid_t b)
Lexicographic less-than comparison for pg_uuid_t.
void provsql_mmap_main_loop()
Main processing loop of the mmap background worker.
void initialize_provsql_mmap()
Open (or create) the mmap files and initialise the circuit store.
static MMappedCircuit * getCircuit(Oid db_oid)
Return (creating lazily if needed) the circuit for db_oid.
Persistent, mmap-backed storage for the full provenance circuit.
#define PROVSQL_TABLE_INFO_MAX_BLOCK_KEY
Cap on the number of block-key columns recorded per relation.
#define PROVSQL_TABLE_INFO_MAX_ANCESTORS
Cap on the number of base ancestors recorded per relation.
void addWire(gate_t f, gate_t t)
Add a directed wire from gate f (parent) to gate t (child).
gate_t getGate(const uuid &u)
Return (or create) the gate associated with UUID u.
In-memory provenance circuit with semiring-generic evaluation.
void setInfos(gate_t g, unsigned info1, unsigned info2)
Set the integer annotation pair for gate g.
gate_t setGate(gate_type type) override
Allocate a new gate with type type and no UUID.
void setExtra(gate_t g, const std::string &ex)
Attach a string extra to gate g.
void setProb(gate_t g, double p)
Set the probability for gate g.
Persistent mmap-backed representation of the provenance circuit.
void setTableAncestry(Oid relid, uint16_t ancestor_n, const Oid *ancestors)
Insert or update the ancestor set of a per-table metadata record, preserving any existing kind / bloc...
void setExtra(pg_uuid_t token, const std::string &s)
Attach a variable-length string annotation to a gate.
void setTableInfo(const ProvenanceTableInfo &info)
Insert or update the kind / block_key half of a per-table metadata record, preserving any existing an...
void removeTableInfo(Oid relid)
Remove a per-table metadata entry (both halves).
MMappedUUIDHashTable mapping
UUID → gate-index hash table.
void createGate(pg_uuid_t token, gate_type type, const std::vector< pg_uuid_t > &children)
Persist a new gate to the mmap store.
std::string getExtra(pg_uuid_t token) const
Return the variable-length string annotation for gate token.
unsigned long getNbGates() const
Return the total number of gates stored in the circuit.
static constexpr const char * GATES_FILENAME
Backing file for gates.
gate_type getGateType(pg_uuid_t token) const
Return the type of the gate identified by token.
static constexpr const char * TABLE_INFO_FILENAME
Backing file for tableInfo.
void removeTableAncestry(Oid relid)
Clear just the ancestor set of a per-table metadata record, preserving kind / block_key.
void sync()
Flush all backing files to disk with msync().
MMappedVector< ProvenanceTableInfo > tableInfo
Per-relation TID/BID metadata (safe-query optimisation).
static constexpr const char * WIRES_FILENAME
Backing file for wires.
GenericCircuit createGenericCircuit(pg_uuid_t token) const
Build an in-memory GenericCircuit rooted at token.
static std::string makePath(Oid db_oid, const char *filename)
Build the full path for a mmap file under $PGDATA/base/<db_oid>/.
bool setProb(pg_uuid_t token, double prob)
Set the probability associated with a gate.
static constexpr const char * EXTRA_FILENAME
Backing file for extra.
static constexpr const char * MAPPING_FILENAME
Backing file for mapping.
bool getTableInfo(Oid relid, ProvenanceTableInfo &out) const
Look up the full per-table metadata record (both halves).
MMappedVector< char > extra
Variable-length string data.
double getProb(pg_uuid_t token) const
Return the probability stored for the gate identified by token.
std::vector< pg_uuid_t > getChildren(pg_uuid_t token) const
Return the child UUIDs of the gate identified by token.
MMappedVector< GateInformation > gates
Gate metadata array.
MMappedVector< pg_uuid_t > wires
Flattened child UUID array.
void setInfos(pg_uuid_t token, unsigned info1, unsigned info2)
Update the info1 / info2 annotations of a gate.
MMappedCircuit(const std::string &mp, const std::string &gp, const std::string &wp, const std::string &ep, const std::string &tp, bool read_only)
Delegating constructor that accepts pre-built paths.
std::pair< unsigned, unsigned > getInfos(pg_uuid_t token) const
Return the info1 / info2 pair for the gate token.
static constexpr unsigned long NOTHING
Sentinel returned by operator[]() when the UUID is not present.
#define provsql_error(fmt,...)
Report a fatal ProvSQL error and abort the current transaction.
Background worker and IPC primitives for mmap-backed circuit storage.
#define READM(var, type)
Read one value of type from the background-to-main pipe.
#define WRITEB(pvar, type)
Write one value of type to the main-to-background pipe.
provsqlSharedState * provsql_shared_state
Pointer to the ProvSQL shared-memory segment (set in provsql_shmem_startup).
Shared-memory segment and inter-process pipe management.
@ gate_rv
Continuous random-variable leaf (extra encodes distribution).
@ gate_arith
n-ary arithmetic gate over scalar-valued children (info1 holds operator tag)
string uuid2string(pg_uuid_t uuid)
Format a pg_uuid_t as a std::string.
C++ utility functions for UUID manipulation.
Per-relation metadata for the safe-query optimisation.
Oid relid
pg_class OID of the relation (primary key)
AttrNumber block_key[PROVSQL_TABLE_INFO_MAX_BLOCK_KEY]
Block-key column numbers.
uint16_t block_key_n
Number of valid entries in block_key.
Oid ancestors[PROVSQL_TABLE_INFO_MAX_ANCESTORS]
Sorted, deduplicated base-relation OIDs.
uint8_t kind
One of provsql_table_kind.
uint16_t ancestor_n
Number of valid entries in ancestors (0 = no registry info).