276 lines
8.4 KiB
C
276 lines
8.4 KiB
C
|
/* $Id$
|
||
|
|
||
|
Part of SWI-Prolog
|
||
|
|
||
|
Author: Jan Wielemaker
|
||
|
E-mail: wielemak@science.uva.nl
|
||
|
WWW: http://www.swi-prolog.org
|
||
|
Copyright (C): 1985-2007, University of Amsterdam
|
||
|
|
||
|
This library is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU Lesser General Public
|
||
|
License as published by the Free Software Foundation; either
|
||
|
version 2.1 of the License, or (at your option) any later version.
|
||
|
|
||
|
This library is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
Lesser General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU Lesser General Public
|
||
|
License along with this library; if not, write to the Free Software
|
||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
*/
|
||
|
|
||
|
#ifndef RDFDB_H_INCLUDED
|
||
|
#define RDFDB_H_INCLUDED
|
||
|
#include "avl.h"
|
||
|
#ifdef WITH_MD5
|
||
|
#include "md5.h"
|
||
|
#endif
|
||
|
#include "lock.h"
|
||
|
|
||
|
#define RDF_VERSION 20800 /* 2.8.0 */
|
||
|
|
||
|
#define URL_subPropertyOf \
|
||
|
"http://www.w3.org/2000/01/rdf-schema#subPropertyOf"
|
||
|
|
||
|
|
||
|
/*******************************
|
||
|
* C *
|
||
|
*******************************/
|
||
|
|
||
|
/* Keep consistent with md5_type[] in rdf_db.c! */
|
||
|
#define OBJ_UNTYPED 0x0 /* partial: don't know */
|
||
|
#define OBJ_INTEGER 0x1
|
||
|
#define OBJ_DOUBLE 0x2
|
||
|
#define OBJ_STRING 0x3
|
||
|
#define OBJ_TERM 0x4
|
||
|
|
||
|
#define Q_NONE 0x0
|
||
|
#define Q_TYPE 0x1
|
||
|
#define Q_LANG 0x2
|
||
|
|
||
|
#define BY_NONE 0x00 /* 0 */
|
||
|
#define BY_S 0x01 /* 1 */
|
||
|
#define BY_P 0x02 /* 2 */
|
||
|
#define BY_O 0x04 /* 4 */
|
||
|
#define BY_SP (BY_S|BY_P) /* 3 */
|
||
|
#define BY_SO (BY_S|BY_O) /* 5 */
|
||
|
#define BY_OP (BY_P|BY_O) /* 6 */
|
||
|
#define BY_SPO (BY_S|BY_P|BY_O) /* 7 */
|
||
|
|
||
|
#define INDEX_TABLES 7
|
||
|
#define INITIAL_TABLE_SIZE 8*1024
|
||
|
#define INITIAL_PREDICATE_TABLE_SIZE 1024
|
||
|
#define INITIAL_GRAPH_TABLE_SIZE 64
|
||
|
|
||
|
#define MAX_HASH_FACTOR 8 /* factor to trigger re-hash */
|
||
|
#define MIN_HASH_FACTOR 4 /* factor after re-hash */
|
||
|
|
||
|
#define NO_LINE (0)
|
||
|
|
||
|
typedef struct cell
|
||
|
{ void * value; /* represented resource */
|
||
|
struct cell *next; /* next in chain */
|
||
|
} cell;
|
||
|
|
||
|
|
||
|
typedef struct list
|
||
|
{ cell *head; /* first in list */
|
||
|
cell *tail; /* tail of list */
|
||
|
} list;
|
||
|
|
||
|
|
||
|
typedef struct bitmatrix
|
||
|
{ size_t width;
|
||
|
size_t heigth;
|
||
|
int bits[1];
|
||
|
} bitmatrix;
|
||
|
|
||
|
|
||
|
#define DISTINCT_DIRECT 0 /* for ->distinct_subjects, etc */
|
||
|
#define DISTINCT_SUB 1
|
||
|
|
||
|
typedef struct predicate
|
||
|
{ atom_t name; /* name of the predicate */
|
||
|
struct predicate *next; /* next in hash-table */
|
||
|
/* hierarchy */
|
||
|
list subPropertyOf; /* the one I'm subPropertyOf */
|
||
|
list siblings; /* reverse of subPropertyOf */
|
||
|
int label; /* Numeric label in cloud */
|
||
|
struct predicate_cloud *cloud; /* cloud I belong to */
|
||
|
unsigned int hash; /* key used for hashing
|
||
|
(=hash if ->cloud is up-to-date) */
|
||
|
/* properties */
|
||
|
struct predicate *inverse_of; /* my inverse predicate */
|
||
|
unsigned transitive : 1; /* P(a,b)&P(b,c) --> P(a,c) */
|
||
|
/* statistics */
|
||
|
long triple_count; /* # triples on this predicate */
|
||
|
long distinct_updated[2];/* Is count still valid? */
|
||
|
long distinct_count[2]; /* Triple count at last update */
|
||
|
long distinct_subjects[2];/* # distinct subject values */
|
||
|
long distinct_objects[2];/* # distinct object values */
|
||
|
} predicate;
|
||
|
|
||
|
|
||
|
typedef struct predicate_cloud
|
||
|
{ predicate **members; /* member predicates */
|
||
|
unsigned int hash; /* hash-code */
|
||
|
size_t size; /* size of the cloud */
|
||
|
size_t deleted; /* See erase_predicates() */
|
||
|
bitmatrix *reachable; /* cloud reachability matrix */
|
||
|
unsigned dirty : 1; /* predicate hash not synchronised */
|
||
|
} predicate_cloud;
|
||
|
|
||
|
|
||
|
typedef struct graph
|
||
|
{ struct graph *next; /* next in table */
|
||
|
atom_t name; /* name of the graph */
|
||
|
atom_t source; /* URL graph was loaded from */
|
||
|
double modified; /* Modified time of source URL */
|
||
|
int triple_count; /* # triples associated to it */
|
||
|
#ifdef WITH_MD5
|
||
|
unsigned md5 : 1; /* do/don't record MD5 */
|
||
|
md5_byte_t digest[16]; /* MD5 digest */
|
||
|
#endif
|
||
|
} graph;
|
||
|
|
||
|
|
||
|
typedef struct literal
|
||
|
{ union
|
||
|
{ atom_t string;
|
||
|
int64_t integer;
|
||
|
double real;
|
||
|
struct
|
||
|
{ record_t record;
|
||
|
size_t len;
|
||
|
} term; /* external record */
|
||
|
} value;
|
||
|
atom_t type_or_lang; /* Type or language for literals */
|
||
|
unsigned int hash; /* saved hash */
|
||
|
unsigned objtype : 3;
|
||
|
unsigned qualifier : 2; /* Lang/Type qualifier */
|
||
|
unsigned shared : 1; /* member of shared table */
|
||
|
unsigned term_loaded : 1; /* OBJ_TERM from quick save file */
|
||
|
unsigned atoms_locked : 1; /* Atoms have been locked */
|
||
|
unsigned references : 24; /* # references to me */
|
||
|
} literal;
|
||
|
|
||
|
|
||
|
#define t_match next[0]
|
||
|
|
||
|
typedef struct triple
|
||
|
{ atom_t subject;
|
||
|
union
|
||
|
{ predicate* r; /* resolved: normal DB */
|
||
|
atom_t u; /* used by rdf_load_db_/3 */
|
||
|
} predicate;
|
||
|
union
|
||
|
{ literal * literal;
|
||
|
atom_t resource;
|
||
|
} object;
|
||
|
atom_t graph; /* where it comes from */
|
||
|
unsigned long line; /* graph-line number */
|
||
|
/* indexing */
|
||
|
struct triple*next[INDEX_TABLES]; /* hash-table next links */
|
||
|
/* flags */
|
||
|
unsigned object_is_literal : 1; /* Object is a literal */
|
||
|
unsigned resolve_pred : 1; /* predicates needs to be resolved */
|
||
|
unsigned indexed : 3; /* Partials: BY_* */
|
||
|
unsigned erased : 1; /* If TRUE, triple is erased */
|
||
|
unsigned first : 1; /* I'm the first on subject */
|
||
|
unsigned match : 3; /* How to match literals */
|
||
|
unsigned inversed : 1; /* Partials: using inverse match */
|
||
|
unsigned is_duplicate : 1; /* I'm a duplicate */
|
||
|
unsigned allocated : 1; /* Triple is allocated */
|
||
|
unsigned atoms_locked : 1; /* Atoms have been locked */
|
||
|
unsigned duplicates : 16; /* Duplicate count */
|
||
|
/* Total: 32 */
|
||
|
} triple;
|
||
|
|
||
|
|
||
|
typedef enum
|
||
|
{ TR_MARK, /* mark start for nesting */
|
||
|
TR_SUB_START, /* start nested transaction */
|
||
|
TR_SUB_END, /* end nested transaction */
|
||
|
TR_ASSERT, /* rdf_assert */
|
||
|
TR_RETRACT, /* rdf_retractall */
|
||
|
TR_UPDATE, /* rdf_update */
|
||
|
TR_UPDATE_SRC, /* rdf_update */
|
||
|
TR_UPDATE_MD5, /* update md5 src */
|
||
|
TR_RESET, /* rdf_reset_db */
|
||
|
TR_VOID /* no-op */
|
||
|
} tr_type;
|
||
|
|
||
|
|
||
|
typedef struct transaction_record
|
||
|
{ struct transaction_record *previous;
|
||
|
struct transaction_record *next;
|
||
|
tr_type type;
|
||
|
triple *triple; /* new/deleted triple */
|
||
|
union
|
||
|
{ triple *triple; /* used for update */
|
||
|
struct
|
||
|
{ atom_t atom;
|
||
|
unsigned long line;
|
||
|
} src;
|
||
|
struct
|
||
|
{ graph *graph;
|
||
|
md5_byte_t *digest;
|
||
|
} md5;
|
||
|
record_t transaction_id;
|
||
|
} update;
|
||
|
} transaction_record;
|
||
|
|
||
|
|
||
|
typedef struct active_transaction
|
||
|
{ struct active_transaction *parent;
|
||
|
term_t id;
|
||
|
} active_transaction;
|
||
|
|
||
|
|
||
|
typedef struct rdf_db
|
||
|
{ triple *by_none, *by_none_tail;
|
||
|
triple **table[INDEX_TABLES];
|
||
|
triple **tail[INDEX_TABLES];
|
||
|
int *counts[INDEX_TABLES];
|
||
|
int table_size[INDEX_TABLES];
|
||
|
long created; /* #triples created */
|
||
|
long erased; /* #triples erased */
|
||
|
long freed; /* #triples actually erased */
|
||
|
long subjects; /* subjects (unique first) */
|
||
|
long indexed[8]; /* Count calls */
|
||
|
int rehash_count; /* # rehashes */
|
||
|
int gc_count; /* # garbage collections */
|
||
|
int gc_blocked; /* GC is blocked; */
|
||
|
double rehash_time; /* time spent in rehash */
|
||
|
double gc_time; /* time spent in GC */
|
||
|
size_t core; /* core in use */
|
||
|
predicate **pred_table; /* Hash-table of predicates */
|
||
|
int pred_table_size; /* #entries in the table */
|
||
|
int pred_count; /* #predicates */
|
||
|
unsigned long next_hash; /* cloud hash keys */
|
||
|
int active_queries; /* Calls with choicepoints */
|
||
|
int need_update; /* We need to update */
|
||
|
long agenda_created; /* #visited nodes in agenda */
|
||
|
long duplicates; /* #duplicate triples */
|
||
|
long generation; /* generation-id of the database */
|
||
|
graph **graph_table; /* Hash table of sources */
|
||
|
int graph_table_size; /* Entries in table */
|
||
|
|
||
|
graph *last_graph; /* last accessed graph */
|
||
|
active_transaction *tr_active; /* open transactions */
|
||
|
transaction_record *tr_first; /* first transaction record */
|
||
|
transaction_record *tr_last; /* last transaction record */
|
||
|
int tr_nesting; /* nesting depth of transactions */
|
||
|
int tr_reset; /* transaction contains reset */
|
||
|
int resetting; /* We are in rdf_reset_db() */
|
||
|
|
||
|
rwlock lock; /* threaded access */
|
||
|
|
||
|
avl_tree literals;
|
||
|
} rdf_db;
|
||
|
|
||
|
#endif /*RDFDB_H_INCLUDED*/
|