X-Git-Url: https://git.rrq.au/?a=blobdiff_plain;f=vector%2Frelation.h;h=c2e5293b8141425aeea418f93cf3286b7cbf20c7;hb=74eec6f62db4459232f95b5d39069b9b4ceeb830;hp=b0996c16b34510649b6235e836a73b496fc80c2d;hpb=c08a0975036f23f972a16a07efb0c07113c96d2e;p=rrq%2Frrqmisc.git diff --git a/vector/relation.h b/vector/relation.h index b0996c1..c2e5293 100644 --- a/vector/relation.h +++ b/vector/relation.h @@ -5,36 +5,160 @@ #include /** - * A relation is an implementation of a tuple set with a primary key - * through a hashvector whose "type" defines the key. Additional - * hashvectors may be added to impose additional key restrictions and - * the final relation is the intersection of them all. - * - * The relation record itself holds the column schema whereas the - * indexes hold key schemas that in practice are copies of the column - * schema with some columns blanked out. + * A relation is an implementation of a tuple set with (optional) key + * constraints. The store is a \ref hashvector whose \b type is a \ref + * tupleschema that defines the columns. The key constraints are + * represented as additional \ref hashvector "hashvectors" whose \ref + * tupleschema "tupleschemas" are clones of the column schema with + * some columns excluded. + * + * \extends hashvector */ typedef struct { - vector indexes; // one or more indexes over the tuple collection - tupleschema *columns; + /** + * This is the primary content store for the relation. Its type + * should be a tupleschema declaring the "item types" for the + * relation columns. + */ + hashvector content; + + /** + * This is a collection of relational constraints, if any, which + * are represented as hashvectors whose tupleschemas are clones of + * the content tupleschema with some columns excluded. + */ + vector constraints; } relation; /** - * Create a relation of the given arity and tupleschema. + * \brief Create a relation for the given tupleschema. + * + * \param schema is the column schema + * + * \returns the allocated relation record. + * + * The given tupleschema is set up as the type of the content + * hashvector, which also is initialised as a nibble_index_levels + * variant vector. + * + * \related relation */ -extern relation *relation_create(int arity,tupleschema *schema); +extern relation *relation_create(tupleschema *schema); /** - * Add a a key index to the relation by identifying the value part for - * this index. + * \brief Add a key constraint to a \ref relation. + * + * \param r is the relation concerned. + * + * \param ... are the column flags indicating key (1) or value (0) + * column for all columns. + * + * \returns the index into the constraints \ref vector for the added + * constraint. + * + * This function adds a \ref hashvector with a \ref tupleschema as its + * item type cloned from the content type and then modified to + * represent the constraint. Namely that the key columns have their + * "column type" set while value columsn are reset. + * + * The \b constraint \ref hashvectors are used when \ref tuple + * "tuples" are added to the \ref relation so as to identify the + * already contained \ref tuple "tuples" that contradict the addition + * by means of having the same constraint key. The already contained + * \ref tuple "tuples" are then "knocked out" from the relation by the + * new addition. + * + * \see relation_add + * \related relation */ -extern int relation_addindex(relation *r,tupleschema *ts); - +extern int relation_add_constraint(relation *r,...); /** - * Add a tuple to a relation. + * \brief Add the tuple to the relation. + * + * \param r is the \ref relation concerned. + * + * \param t is the \ref tuple to add. + * * \returns a vector of all knocked out tuples. + * + * This function adds the \ref tuple \b t to the \ref relation \b r, + * and it returns a \ref vector (single_index_level variant) of all + * same-key constraint tuples. The returned vector is malloc-ed and it + * must be free-ed by the caller. If the tuple is already contained or + * there are no other same-key tuples knocked out, then \b 0 is + * returned. + * + * \related relation */ extern vector *relation_add(relation *r,tuple *t); +/** + * \brief Delete all tuples matching to the query \ref tuple fromt the + * \ref relation. + * + * \param r is the \ref relation concerned. + * + * \param t is the \ref tuple to delete. + * + * \returns a \vector vector of all knocked out tuples, i.e. the + * same-key tuples, if any, contained in the relation + * + * Note that deletion uses a "query" tuple, which means that some + * columns may be null to mark that them match to any value. + * + * \related relation + */ +extern vector *relation_delete(relation *r,tuple *query); + +/** + * \brief Return the next \ref tuple in the \ref relation that matches + * to the query \ref tuple, at or after the index. + * + * \param r is the \ref relation concerned. + * + * \param index is a pointer to the \ref vector index to update. + * + * \param query is a query \tuple tuple for selection of certain + * column values. + * + * \returns any such matching \tuple tuple and an updateed *index. + * + * \related relation + */ +extern void *relation_next(relation *r,vector_index *index,tuple *query); + +/** + * \brief Lay out a dynamic \ref relation initializer for a relation + * wth the given column "types". + * + * This defines a \ref relation intializer that creates the \ref + * tupleschema for the given columns. + * + * \note The initializer cannot be used statically. + * + * The \b content \ref hashvector is a \ref nibble_index_level variant + * with an initial size of 16 slots. + * + * The constraints \ref vector is a \ref bitpair_index_level variant + * with initial size 0. + * + * The \b content \ref hashvector \b type is set up with an allocated + * \ref tupleschema that has an allocated \ref tuple that declares the + * column "types" view the given \ref itemkeyfun pointers. Any add + * constraints will need to clone that \ref tupleschema and then clear + * the column slots for the constraint value columns, typically by + * using \ref tupleschema_mask for this. + * + * \related relation + */ +#define RELATION(...) (relation) { \ + .content = { \ + .table = { .variant = nibble_index_levels, .size=16, .entries=0 }, \ + .fill = 0, .holes = 0, \ + .type = (itemkeyfun*) TUPLESCHEMA( __VA_ARGS__ ) \ + }, \ + .constraints = { .variant = bitpair_index_levels, .size=0, .entries=0 } \ +} + #endif