1 /*
2 * Copyright (c) 2000-2006 All rights reserved,
3 * Alberto Reggiori <areggiori@webweaving.org>,
4 * Dirk-Willem van Gulik <dirkx@webweaving.org>.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 *
17 * 3. The end-user documentation included with the redistribution, if any, must
18 * include the following acknowledgment: "This product includes software
19 * developed by Alberto Reggiori <areggiori@webweaving.org> and Dirk-Willem
20 * van Gulik <dirkx@webweaving.org>." Alternately, this acknowledgment may
21 * appear in the software itself, if and wherever such third-party
22 * acknowledgments normally appear.
23 *
24 * 4. All advertising materials mentioning features or use of this software must
25 * display the following acknowledgement: This product includes software
26 * developed by the University of California, Berkeley and its contributors.
27 *
28 * 5. Neither the name of the University nor the names of its contributors may
29 * be used to endorse or promote products derived from this software without
30 * specific prior written permission.
31 *
32 * 6. Products derived from this software may not be called "RDFStore" nor may
33 * "RDFStore" appear in their names without prior written permission.
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
39 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
41 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
42 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45 * SUCH DAMAGE.
46 *
47 * ====================================================================
48 *
49 * This software consists of work developed by Alberto Reggiori and Dirk-Willem
50 * van Gulik. The RDF specific part is based based on public domain software
51 * written at the Stanford University Database Group by Sergey Melnik. For
52 * more information on the RDF API Draft work, please see
53 * <http://www-db.stanford.edu/~melnik/rdf/api.html> The DBMS TCP/IP server
54 * part is based on software originally written by Dirk-Willem van Gulik for
55 * Web Weaving Internet Engineering m/v Enschede, The Netherlands.
56 *
57 * $Id: rdfstore_kernel.c,v 1.113 2006/06/19 10:10:21 areggiori Exp $
58 *
59 */
60
61 #if !defined(WIN32)
62 #include <sys/param.h>
63 #endif
64
65 #include <sys/types.h>
66 #include <stdio.h>
67 #include <stdlib.h>
68 #include <errno.h>
69 #include <strings.h>
70 #include <fcntl.h>
71
72 #include <netinet/in.h>
73
74 #include <time.h>
75 #include <sys/stat.h>
76
77 #include "rdfstore_log.h"
78 #include "rdfstore_ms.h"
79 #include "rdfstore.h"
80 #include "rdfstore_iterator.h"
81 #include "rdfstore_serializer.h"
82 #include "rdfstore_digest.h"
83 #include "rdfstore_bits.h"
84 #include "rdfstore_utf8.h"
85 #include "rdfstore_xsd.h"
86
87 /*
88 #define MX { printf(" MX %s:%d - %p\n",__FILE__,__LINE__,me->nindex->free); }
89 */
90 #define MX
91
92 /*
93 * #define RDFSTORE_DEBUG
94 */
95
96 /*
97 * #define RDFSTORE_CONNECTIONS
98 */
99 /*
100 * #define RDFSTORE_DEBUG_CONNECTIONS
101 */
102 /*
103 * #define RDFSTORE_CONNECTIONS_REINDEXING
104 */
105
rdfstore_get_version(rdfstore * me)106 char * rdfstore_get_version (
107 rdfstore * me
108 ) {
109 return VERSION;
110 };
111
112 int
rdfstore_connect(rdfstore ** mme,char * name,int flags,int freetext,int sync,int remote,char * host,int port,void * (* _mmalloc)(size_t s),void (* _mfree)(void * adr),void (* _mcallback)(dbms_cause_t cause,int cnt),void (* _merror)(char * err,int erx))113 rdfstore_connect(
114 rdfstore * *mme,
115 char *name,
116 int flags,
117 int freetext,
118 int sync,
119 int remote,
120 char *host,
121 int port,
122 /* Callbacks for memory management and error handling. */
123 void *(*_mmalloc) (size_t s),
124 void (*_mfree) (void *adr),
125 void (*_mcallback) (dbms_cause_t cause, int cnt),
126 void (*_merror) (char *err, int erx)
127 )
128 {
129 rdfstore *me = NULL;
130 DBT key, data;
131 int err = 0,comp_alg=RDFSTORE_COMPRESSION_TYPE_DEFAULT;
132 #ifdef RDFSTORE_CONNECTIONS
133 int comp_alg_connections=RDFSTORE_COMPRESSION_TYPE_BLOCK;/* comparing on some thesaurus like 10k triples this is the best */
134 #endif
135
136 memset(&key, 0, sizeof(key));
137 memset(&data, 0, sizeof(data));
138
139 *mme = NULL;
140
141 me = (rdfstore *) RDFSTORE_MALLOC(sizeof(rdfstore));
142
143 if (me == NULL)
144 return -1;
145
146 me->model = NULL;
147 me->nodes = NULL;
148 me->subjects = NULL;
149 me->predicates = NULL;
150 me->objects = NULL;
151 #ifdef RDFSTORE_CONNECTIONS
152 me->s_connections = NULL;
153 me->p_connections = NULL;
154 me->o_connections = NULL;
155 #endif
156 me->languages = NULL;
157 me->datatypes = NULL;
158 me->xsd_integer = NULL;
159 me->xsd_double = NULL;
160 me->xsd_date = NULL;
161 me->contexts = NULL;
162 me->freetext = 0;
163 me->statements = NULL;
164 me->cursor = NULL;
165
166 /* prefixes mapping stuff */
167 me->prefixes = NULL;
168
169 /* set/get options */
170 me->flag = flags;
171 me->sync = sync;
172 me->remote = remote;
173
174 if (me->remote) {
175 if ((host != NULL) &&
176 (strlen(host) > 0))
177 strcpy(me->host, host);
178 me->port = port;
179 } else {
180 strcpy(me->host, "");
181 me->port = 0;
182 };
183 me->context = NULL;
184
185 /* name can also be file://.... for local or rdfstore://demo.asemantics.com:1234/nb for remote */
186 if (!strncmp(name,"file://",(size_t)7)) {
187 fprintf(stderr,"Aborted: RDF/XML or N-Triples file will be supported with in-memory model and C level parsing done.\n");
188 goto exitandclean;
189 } else if (!strncmp(name,"rdfstore://",(size_t)11)) {
190 char url_port[255];
191 char * p;
192 char * p1;
193 name+=11;
194 p = strstr(name,":");
195 p1 = strstr(name,"/");
196 if(p!=NULL) {
197 /* get the host out */
198 strncpy(me->host,name,p-name);
199 me->host[p-name] = '\0';
200 if (strlen(me->host)<=0) {
201 fprintf(stderr,"Aborted: You really want an Internet hostname.\n");
202 goto exitandclean;
203 };
204 host = me->host;
205 /* get the port out */
206 strncpy(url_port,p+1,p1-(p+1));
207 port = atoi(url_port);
208 if (port<=1) {
209 fprintf(stderr,"Aborted: You really want a port number >1.\n");
210 goto exitandclean;
211 };
212 name=p1+1;
213 me->port = port;
214
215 remote = 1;
216 me->remote = 1;
217 } else if(p1!=NULL) {
218 /* get the host out */
219 strncpy(me->host,name,p1-name);
220 me->host[p1-name] = '\0';
221 if (strlen(me->host)<=0) {
222 remote = 0;
223 me->remote = 0;
224 } else {
225 host = me->host;
226 remote = 1;
227 me->remote = 1;
228 name=p1+1;
229 };
230 };
231 } else if (!strncmp(name,"http://",(size_t)7)) {
232 fprintf(stderr,"Aborted: What are you trying to do? That's DAV like isn't it? ;-)\n");
233 goto exitandclean;
234 };
235
236 err = rdfstore_flat_store_open(remote,
237 flags,
238 &me->model,
239 name, (((name == NULL) || (strlen(name) == 0)) ? NULL : "/model"),
240 (unsigned int)(32 * 1024), host, port,
241 _mmalloc, _mfree, _mcallback, _merror,
242 0);
243 if (err != 0)
244 goto exitandclean;
245
246 /* check indexing version first or croak */
247 key.data = RDFSTORE_INDEXING_VERSION_KEY;
248 key.size = sizeof(RDFSTORE_INDEXING_VERSION_KEY);
249 if ((rdfstore_flat_store_fetch(me->model, key, &data)) != 0) {
250 if (!(me->flag)) {
251 data.data = RDFSTORE_INDEXING_VERSION;
252 data.size = strlen(RDFSTORE_INDEXING_VERSION) + 1;
253 err = rdfstore_flat_store_store(me->model, key, data);
254 if ((err != 0) &&
255 (err != FLAT_STORE_E_KEYEXIST)) {
256 perror("rdfstore_connect");
257 fprintf(stderr,"Could not store '%d' bytes for key '%s' in table model for store '%s': %s\n", (int)data.size, (char *)key.data, (char *)data.data, rdfstore_flat_store_get_error(me->model));
258
259 goto exitandclean;
260 };
261 } else {
262 if( (name != NULL) &&
263 (strlen(name) > 0) ) {
264 perror("rdfstore_connect");
265 fprintf(stderr,"Incompatible RDF database indexing version. This is version %s. You need to upgrade your database; dump your data, remove old database and re-ingest data.\n", RDFSTORE_INDEXING_VERSION );
266 goto exitandclean;
267 };
268 };
269 strcpy(me->version, RDFSTORE_INDEXING_VERSION);
270 } else {
271 /* just croak if different version for the moment */
272 if (strncmp( RDFSTORE_INDEXING_VERSION,
273 data.data, data.size )) {
274 perror("rdfstore_connect");
275 fprintf(stderr,"Incompatible RDF database indexing version %s. This is version %s. You need to upgrade your database; dump your data, remove old database and re-ingest data.\n", (char *)data.data, RDFSTORE_INDEXING_VERSION );
276 goto exitandclean;
277 };
278 strcpy(me->version, data.data);
279 RDFSTORE_FREE(data.data);
280 };
281
282 if ((name != NULL) &&
283 (strlen(name) > 0)) {
284 key.data = RDFSTORE_NAME_KEY;
285 key.size = sizeof(RDFSTORE_NAME_KEY);
286 if ((rdfstore_flat_store_fetch(me->model, key, &data)) != 0) {
287 if (!(me->flag)) {
288 data.data = name;
289 data.size = strlen(name) + 1;
290 err = rdfstore_flat_store_store(me->model, key, data);
291 if ((err != 0) &&
292 (err != FLAT_STORE_E_KEYEXIST)) {
293 perror("rdfstore_connect");
294 fprintf(stderr,"Could not store '%d' bytes for key '%s' in table model for store '%s': %s\n", (int)data.size, (char *)key.data, (char *)data.data, rdfstore_flat_store_get_error(me->model));
295
296 goto exitandclean;
297 };
298 } else {
299 perror("rdfstore_connect");
300 fprintf(stderr,"Store '%s' does not exist or is corrupted\n", name);
301 goto exitandclean;
302 };
303 strcpy(me->name, name);
304 } else {
305 if (strncmp(name, data.data, strlen(name))) { /* which is obvioulsy
306 * wrong but we avoid
307 * bother of ending
308 * slashes ;-) */
309 RDFSTORE_FREE(data.data);
310 perror("rdfstore_connect");
311 fprintf(stderr,"It seems you have got the wrong store name '%s' instead of '%s'\n", name, (char *)data.data);
312 goto exitandclean;
313 };
314 strcpy(me->name, data.data);
315 RDFSTORE_FREE(data.data);
316 };
317 };
318
319 key.data = RDFSTORE_FREETEXT_KEY;
320 key.size = sizeof(RDFSTORE_FREETEXT_KEY);
321
322 if ((rdfstore_flat_store_fetch(me->model, key, &data)) != 0) {
323 if (!(me->flag)) {
324 data.data = (freetext) ? "1" : "0";
325 data.size = sizeof((freetext) ? "1" : "0") + 1;
326 err = rdfstore_flat_store_store(me->model, key, data);
327 if ((err != 0) &&
328 (err != FLAT_STORE_E_KEYEXIST)) {
329 perror("rdfstore_connect");
330 fprintf(stderr,"Could not store '%d' bytes for key '%s' in model for store '%s': %s\n", (int)data.size, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->model));
331 goto exitandclean;
332 };
333 } else if ((me->name != NULL) &&
334 (strlen(me->name) > 0)) {
335 perror("rdfstore_connect");
336 fprintf(stderr,"Store '%s' seems corrupted\n", me->name);
337 goto exitandclean;
338 };
339 me->freetext = (freetext) ? 1 : 0;
340 } else {
341 me->freetext = (strcmp(data.data, "0")) ? 1 : 0;
342 RDFSTORE_FREE(data.data);
343 };
344
345 key.data = RDFSTORE_COMPRESSION_KEY;
346 key.size = sizeof(RDFSTORE_COMPRESSION_KEY);
347 if ((rdfstore_flat_store_fetch(me->model, key, &data)) != 0) {
348 if (!(me->flag)) {
349 unsigned char outbuf[256];
350 packInt(comp_alg, outbuf);
351 data.data = outbuf;
352 data.size = sizeof(int);
353 err = rdfstore_flat_store_store(me->model, key, data);
354 if ((err != 0) &&
355 (err != FLAT_STORE_E_KEYEXIST)) {
356 perror("rdfstore_connect");
357 fprintf(stderr,"Could not store '%d' bytes for key '%s' in model for store '%s': %s\n", (int)data.size, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->model));
358 goto exitandclean;
359 };
360 };
361 } else {
362 unpackInt(data.data, &comp_alg);
363 RDFSTORE_FREE(data.data);
364 };
365
366 if (rdfstore_compress_init(comp_alg,&(me->func_decode),&(me->func_encode))) {
367 #ifdef RDFSTORE_DEBUG
368 fprintf(stderr,"Could not init default compression function for algorithm '%d'\n",comp_alg);
369 #endif
370 goto exitandclean;
371 };
372
373 #ifdef RDFSTORE_CONNECTIONS
374 key.data = RDFSTORE_COMPRESSION_CONNECTIONS_KEY;
375 key.size = sizeof(RDFSTORE_COMPRESSION_CONNECTIONS_KEY);
376 if ((rdfstore_flat_store_fetch(me->model, key, &data)) != 0) {
377 if (!(me->flag)) {
378 unsigned char outbuf[256];
379 packInt(comp_alg_connections, outbuf);
380 data.data = outbuf;
381 data.size = sizeof(int);
382 err = rdfstore_flat_store_store(me->model, key, data);
383 if ((err != 0) &&
384 (err != FLAT_STORE_E_KEYEXIST)) {
385 perror("rdfstore_connect");
386 fprintf(stderr,"Could not store '%d' bytes for key '%s' in model for store '%s': %s\n", (int)data.size, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->model));
387 goto exitandclean;
388 };
389 };
390 } else {
391 unpackInt(data.data, &comp_alg_connections);
392 RDFSTORE_FREE(data.data);
393 };
394
395 /* now bear in mind we using this for sake of experiment on connections tables to see if it compresses better.... */
396 if (rdfstore_compress_init(comp_alg_connections,&(me->func_decode_connections),&(me->func_encode_connections))) {
397 #ifdef RDFSTORE_DEBUG
398 fprintf(stderr,"Could not init connections compression function for algorithm '%d'\n",comp_alg_connections);
399 #endif
400 goto exitandclean;
401 };
402 #endif
403
404 err = rdfstore_flat_store_open(remote,
405 flags,
406 &me->nodes,
407 name, (((name == NULL) || (strlen(name) == 0)) ? NULL : "/nodes"), (unsigned int)(32 * 1024), host, port,
408 _mmalloc, _mfree, _mcallback, _merror,
409 0);
410 if (err != 0) {
411 goto exitandclean;
412 };
413 err = rdfstore_flat_store_open(remote,
414 flags,
415 &me->subjects,
416 name, (((name == NULL) || (strlen(name) == 0)) ? NULL : "/subjects"), (unsigned int)(32 * 1024), host, port,
417 _mmalloc, _mfree, _mcallback, _merror,
418 0);
419 if (err != 0) {
420 goto exitandclean;
421 };
422 err = rdfstore_flat_store_open(remote,
423 flags,
424 &me->predicates,
425 name, (((name == NULL) || (strlen(name) == 0)) ? NULL : "/predicates"), (unsigned int)(32 * 1024), host, port,
426 _mmalloc, _mfree, _mcallback, _merror,
427 0);
428 if (err != 0) {
429 goto exitandclean;
430 };
431 err = rdfstore_flat_store_open(remote,
432 flags,
433 &me->objects,
434 name, (((name == NULL) || (strlen(name) == 0)) ? NULL : "/objects"), (unsigned int)(32 * 1024), host, port,
435 _mmalloc, _mfree, _mcallback, _merror,
436 0);
437 if (err != 0) {
438 goto exitandclean;
439 };
440 err = rdfstore_flat_store_open(remote,
441 flags,
442 &me->contexts,
443 name, (((name == NULL) || (strlen(name) == 0)) ? NULL : "/contexts"), (unsigned int)(32 * 1024), host, port,
444 _mmalloc, _mfree, _mcallback, _merror,
445 0);
446 if (err != 0) {
447 goto exitandclean;
448 };
449 #ifdef RDFSTORE_CONNECTIONS
450 err = rdfstore_flat_store_open(remote,
451 flags,
452 &me->s_connections,
453 name, (((name == NULL) || (strlen(name) == 0)) ? NULL : "/s_connections"), (unsigned int)(32 * 1024), host, port,
454 _mmalloc, _mfree, _mcallback, _merror,
455 0 );
456 if (err != 0) {
457 goto exitandclean;
458 };
459 err = rdfstore_flat_store_open(remote,
460 flags,
461 &me->p_connections,
462 name, (((name == NULL) || (strlen(name) == 0)) ? NULL : "/p_connections"), (unsigned int)(32 * 1024), host, port,
463 _mmalloc, _mfree, _mcallback, _merror,
464 0 );
465 if (err != 0) {
466 goto exitandclean;
467 };
468 err = rdfstore_flat_store_open(remote,
469 flags,
470 &me->o_connections,
471 name, (((name == NULL) || (strlen(name) == 0)) ? NULL : "/o_connections"), (unsigned int)(32 * 1024), host, port,
472 _mmalloc, _mfree, _mcallback, _merror,
473 0 );
474 if (err != 0) {
475 goto exitandclean;
476 };
477 #endif
478
479 err = rdfstore_flat_store_open(remote,
480 flags,
481 &me->languages,
482 name, (((name == NULL) || (strlen(name) == 0)) ? NULL : "/languages"), (unsigned int)(32 * 1024), host, port,
483 _mmalloc, _mfree, _mcallback, _merror,
484 0 );
485 if (err != 0) {
486 goto exitandclean;
487 };
488
489 err = rdfstore_flat_store_open(remote,
490 flags,
491 &me->datatypes,
492 name, (((name == NULL) || (strlen(name) == 0)) ? NULL : "/datatypes"), (unsigned int)(32 * 1024), host, port,
493 _mmalloc, _mfree, _mcallback, _merror,
494 0 );
495 if (err != 0) {
496 goto exitandclean;
497 };
498
499 /* special table for integers */
500 err = rdfstore_flat_store_open(remote,
501 flags,
502 &me->xsd_integer,
503 name, (((name == NULL) || (strlen(name) == 0)) ? NULL : "/xsd_integer"), (unsigned int)(32 * 1024), host, port,
504 _mmalloc, _mfree, _mcallback, _merror,
505 FLAT_STORE_BT_COMP_INT );
506 if (err != 0) {
507 goto exitandclean;
508 };
509
510 /* special table for doubles */
511 err = rdfstore_flat_store_open(remote,
512 flags,
513 &me->xsd_double,
514 name, (((name == NULL) || (strlen(name) == 0)) ? NULL : "/xsd_double"), (unsigned int)(32 * 1024), host, port,
515 _mmalloc, _mfree, _mcallback, _merror,
516 FLAT_STORE_BT_COMP_DOUBLE );
517 if (err != 0) {
518 goto exitandclean;
519 };
520
521 /* special table for dates */
522 err = rdfstore_flat_store_open(remote,
523 flags,
524 &me->xsd_date,
525 name, (((name == NULL) || (strlen(name) == 0)) ? NULL : "/xsd_date"), (unsigned int)(32 * 1024), host, port,
526 _mmalloc, _mfree, _mcallback, _merror,
527 0); /* I guess lexicographical order for xsd:date and xsd:dateTime should work */
528 if (err != 0) {
529 goto exitandclean;
530 };
531
532 if (me->freetext) { /* just if we need free-text indexing */
533 err = rdfstore_flat_store_open(remote,
534 flags,
535 &me->windex,
536 name, (((name == NULL) || (strlen(name) == 0)) ? NULL : "/windex"), (unsigned int)(32 * 1024), host, port,
537 _mmalloc, _mfree, _mcallback, _merror,
538 0); /* might be default lexicographical order for words is not UTF-8 safe? yeah..... */
539 if (err != 0) {
540 goto exitandclean;
541 };
542 };
543
544 err = rdfstore_flat_store_open(remote,
545 flags,
546 &me->statements,
547 name, (((name == NULL) || (strlen(name) == 0)) ? NULL : "/statements"), (unsigned int)(32 * 1024), host, port,
548 _mmalloc, _mfree, _mcallback, _merror,
549 0);
550 if (err != 0) {
551 goto exitandclean;
552 };
553
554 /* this is just used internally and never gets returned to the user */
555 me->cursor = NULL;
556 me->cursor = (rdfstore_iterator *) RDFSTORE_MALLOC(sizeof(rdfstore_iterator));
557 if (me->cursor == NULL) {
558 perror("rdfstore_connect");
559 fprintf(stderr,"Cannot create internal results cursor/iterator for store '%s'\n", (name != NULL) ? name : "(in-memory)");
560 goto exitandclean;
561 };
562
563 /* initialize statements counters if necessary */
564
565 /* keep the number of zapped statements */
566 key.data = RDFSTORE_COUNTER_REMOVED_KEY;
567 key.size = sizeof(RDFSTORE_COUNTER_REMOVED_KEY);
568 if ((rdfstore_flat_store_exists(me->model, key)) != 0) {
569 if (!(me->flag)) {
570 unsigned char outbuf[256];
571 packInt(0, outbuf);
572 data.data = outbuf;
573 data.size = sizeof(int);
574 err = rdfstore_flat_store_store(me->model, key, data);
575 if ((err != 0) &&
576 (err != FLAT_STORE_E_KEYEXIST)) {
577 perror("rdfstore_connect");
578 fprintf(stderr,"Could not store '%d' bytes for key '%s' in model for store '%s': %s\n", (int)data.size, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->model));
579 goto exitandclean;
580 };
581 } else if ((me->name != NULL) &&
582 (strlen(me->name) > 0)) {
583 perror("rdfstore_connect");
584 fprintf(stderr,"Store '%s' seems corrupted\n", (me->name != NULL) ? me->name : "(in-memory)");
585 goto exitandclean;
586 };
587 };
588
589 /* keep the total number of statements */
590 key.data = RDFSTORE_COUNTER_KEY;
591 key.size = sizeof(RDFSTORE_COUNTER_KEY);
592 if ((rdfstore_flat_store_exists(me->model, key)) != 0) {
593 if (!(me->flag)) {
594 unsigned char outbuf[256];
595 packInt(0, outbuf);
596 data.data = outbuf;
597 data.size = sizeof(int);
598 err = rdfstore_flat_store_store(me->model, key, data);
599 if ((err != 0) &&
600 (err != FLAT_STORE_E_KEYEXIST)) {
601 perror("rdfstore_connect");
602 fprintf(stderr,"Could not store '%d' bytes for key '%s' in model for store '%s': %s\n", (int)data.size, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->model));
603 goto exitandclean;
604 };
605 } else if ((me->name != NULL) &&
606 (strlen(me->name) > 0)) {
607 perror("rdfstore_connect");
608 fprintf(stderr,"Store '%s' seems corrupted\n", (me->name != NULL) ? me->name : "(in-memory)");
609 goto exitandclean;
610 };
611 };
612
613 me->cursor->store = me;
614 /* bzero(me->cursor->ids,sizeof(unsigned char)*(RDFSTORE_MAXRECORDS_BYTES_SIZE)); */
615 me->cursor->remove_holes = 0; /* reset the total of holes */
616 me->cursor->st_counter = 0;
617 if ((me->name != NULL) &&
618 (strlen(me->name) > 0)) {
619 rdfstore_size(me, &me->cursor->size);
620 } else {
621 me->cursor->size = 0;
622 };
623 me->cursor->ids_size = (me->cursor->size / 8);
624 if (me->cursor->size % 8)
625 me->cursor->ids_size++;
626 me->cursor->pos = 0;
627
628 me->attached = 0; /* reset the number of items (cursors)
629 * currenlty attached */
630 me->tobeclosed = 0;
631
632 /* it seems BDB 1.8x needs this to start properly */
633 if (!(me->flag)) {
634 /*
635 * fprintf(stderr,"Initial sync for BDB 1.8x and flag = '%d' (must be
636 * 0)",me->flag);
637 */
638 rdfstore_flat_store_sync(me->model);
639 rdfstore_flat_store_sync(me->nodes);
640 rdfstore_flat_store_sync(me->subjects);
641 rdfstore_flat_store_sync(me->predicates);
642 rdfstore_flat_store_sync(me->objects);
643 if (me->contexts)
644 rdfstore_flat_store_sync(me->contexts);
645 #ifdef RDFSTORE_CONNECTIONS
646 if (me->s_connections)
647 rdfstore_flat_store_sync(me->s_connections);
648 if (me->p_connections)
649 rdfstore_flat_store_sync(me->p_connections);
650 if (me->o_connections)
651 rdfstore_flat_store_sync(me->o_connections);
652 #endif
653 if (me->languages)
654 rdfstore_flat_store_sync(me->languages);
655 if (me->datatypes)
656 rdfstore_flat_store_sync(me->datatypes);
657 if (me->xsd_integer)
658 rdfstore_flat_store_sync(me->xsd_integer);
659 if (me->xsd_double)
660 rdfstore_flat_store_sync(me->xsd_double);
661 if (me->xsd_date)
662 rdfstore_flat_store_sync(me->xsd_date);
663 if (me->freetext)
664 rdfstore_flat_store_sync(me->windex);
665 rdfstore_flat_store_sync(me->statements);
666 };
667
668 #ifdef RDFSTORE_DEBUG
669 {
670 unsigned int size = 0;
671 if ((name != NULL) && (strlen(name) > 0)) {
672 if (rdfstore_size(me, &size)) {
673 perror("rdfstore_is_empty");
674 fprintf(stderr,"Could not carry out model size for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
675 goto exitandclean;
676 };
677 };
678 fprintf(stderr,"Connected to database \n\tname='%s'\n\tremote='%d'\n\thost='%s'\n\tport='%d'\n\tfreetext='%d'\n\tsync='%d'\n\tsize='%d'", me->name, me->remote, me->host, me->port, me->freetext, me->sync, size);
679 };
680 #endif
681
682 *mme = me;
683
684 MX;
685 return 0;
686
687 exitandclean:
688 /* XX should we not also free the me->model, me->nodes and so on ? or at least close them ? */
689 if (me->model) {
690 if (!(me->flag)) rdfstore_flat_store_sync(me->model);
691 rdfstore_flat_store_close(me->model);
692 };
693 if (me->nodes) {
694 if (!(me->flag)) rdfstore_flat_store_sync(me->nodes);
695 rdfstore_flat_store_close(me->nodes);
696 };
697 if (me->subjects) {
698 if (!(me->flag)) rdfstore_flat_store_sync(me->subjects);
699 rdfstore_flat_store_close(me->subjects);
700 };
701 if (me->predicates) {
702 if (!(me->flag)) rdfstore_flat_store_sync(me->predicates);
703 rdfstore_flat_store_close(me->predicates);
704 };
705 if (me->objects) {
706 if (!(me->flag)) rdfstore_flat_store_sync(me->objects);
707 rdfstore_flat_store_close(me->objects);
708 };
709 if (me->contexts) {
710 if (!(me->flag)) rdfstore_flat_store_sync(me->contexts);
711 rdfstore_flat_store_close(me->contexts);
712 };
713 #ifdef RDFSTORE_CONNECTIONS
714 if (me->s_connections) {
715 if (!(me->flag)) rdfstore_flat_store_sync(me->s_connections);
716 rdfstore_flat_store_close(me->s_connections);
717 };
718 if (me->p_connections) {
719 if (!(me->flag)) rdfstore_flat_store_sync(me->p_connections);
720 rdfstore_flat_store_close(me->p_connections);
721 };
722 if (me->o_connections) {
723 if (!(me->flag)) rdfstore_flat_store_sync(me->o_connections);
724 rdfstore_flat_store_close(me->o_connections);
725 };
726 #endif
727 if (me->languages) {
728 if (!(me->flag)) rdfstore_flat_store_sync(me->languages);
729 rdfstore_flat_store_close(me->languages);
730 };
731 if (me->datatypes) {
732 if (!(me->flag)) rdfstore_flat_store_sync(me->datatypes);
733 rdfstore_flat_store_close(me->datatypes);
734 };
735 if (me->xsd_integer) {
736 if (!(me->flag)) rdfstore_flat_store_sync(me->xsd_integer);
737 rdfstore_flat_store_close(me->xsd_integer);
738 };
739 if (me->xsd_double) {
740 if (!(me->flag)) rdfstore_flat_store_sync(me->xsd_double);
741 rdfstore_flat_store_close(me->xsd_double);
742 };
743 if (me->xsd_date) {
744 if (!(me->flag)) rdfstore_flat_store_sync(me->xsd_date);
745 rdfstore_flat_store_close(me->xsd_date);
746 };
747 if (me->windex) {
748 if (!(me->flag)) rdfstore_flat_store_sync(me->windex);
749 rdfstore_flat_store_close(me->windex);
750 };
751 if (me->statements) {
752 if (!(me->flag)) rdfstore_flat_store_sync(me->statements);
753 rdfstore_flat_store_close(me->statements);
754 };
755 if (me->cursor) RDFSTORE_FREE(me->cursor);
756 RDFSTORE_FREE(me);
757 return -1;
758 };
759
760 int
rdfstore_disconnect(rdfstore * me)761 rdfstore_disconnect(rdfstore * me)
762 {
763
764 if (me == NULL) {
765 #ifdef RDFSTORE_DEBUG
766 printf(">>>>>>>>>>>>>>>>>>>>%p IMPOSSIBLE TO CLOSE\n", me);
767 #endif
768 return -1;
769 };
770
771 if (me->attached > 0) {
772 #ifdef RDFSTORE_DEBUG
773 printf(">>>>>>>>>>>>>>>>>>>>%p TO BE CLOSED\n", me);
774 #endif
775 me->tobeclosed = 1;
776 return 1; /* wait the cursors to call me back :-) */
777 } else {
778 #ifdef RDFSTORE_DEBUG
779 printf("<<<<<<<<<<<<<<<<<<<<%p CLOSING\n", me);
780 #endif
781 me->tobeclosed = 0;
782 };
783 MX;
784
785 if ((me->sync) &&
786 (!(me->flag))) {
787 rdfstore_flat_store_sync(me->model);
788 rdfstore_flat_store_sync(me->nodes);
789 rdfstore_flat_store_sync(me->subjects);
790 rdfstore_flat_store_sync(me->predicates);
791 rdfstore_flat_store_sync(me->objects);
792 #ifdef RDFSTORE_CONNECTIONS
793 if (me->s_connections)
794 rdfstore_flat_store_sync(me->s_connections);
795 if (me->p_connections)
796 rdfstore_flat_store_sync(me->p_connections);
797 if (me->o_connections)
798 rdfstore_flat_store_sync(me->o_connections);
799 #endif
800 if (me->languages)
801 rdfstore_flat_store_sync(me->languages);
802 if (me->datatypes)
803 rdfstore_flat_store_sync(me->datatypes);
804 if (me->xsd_integer)
805 rdfstore_flat_store_sync(me->xsd_integer);
806 if (me->xsd_double)
807 rdfstore_flat_store_sync(me->xsd_double);
808 if (me->xsd_date)
809 rdfstore_flat_store_sync(me->xsd_date);
810 if (me->freetext)
811 rdfstore_flat_store_sync(me->windex);
812 if (me->contexts)
813 rdfstore_flat_store_sync(me->contexts);
814 rdfstore_flat_store_sync(me->statements);
815 };
816
817 if (me->cursor != NULL)
818 RDFSTORE_FREE(me->cursor);
819
820 if (me->context != NULL) {
821 RDFSTORE_FREE(me->context->value.resource.identifier);
822 RDFSTORE_FREE(me->context);
823 };
824
825 rdfstore_flat_store_close(me->model);
826 rdfstore_flat_store_close(me->nodes);
827 rdfstore_flat_store_close(me->subjects);
828 rdfstore_flat_store_close(me->predicates);
829 rdfstore_flat_store_close(me->objects);
830 if (me->contexts)
831 rdfstore_flat_store_close(me->contexts);
832 #ifdef RDFSTORE_CONNECTIONS
833 if (me->s_connections)
834 rdfstore_flat_store_close(me->s_connections);
835 if (me->p_connections)
836 rdfstore_flat_store_close(me->p_connections);
837 if (me->o_connections)
838 rdfstore_flat_store_close(me->o_connections);
839 #endif
840 if (me->languages)
841 rdfstore_flat_store_close(me->languages);
842 if (me->datatypes)
843 rdfstore_flat_store_close(me->datatypes);
844 if (me->xsd_integer)
845 rdfstore_flat_store_close(me->xsd_integer);
846 if (me->xsd_double)
847 rdfstore_flat_store_close(me->xsd_double);
848 if (me->xsd_date)
849 rdfstore_flat_store_close(me->xsd_date);
850 if (me->freetext)
851 rdfstore_flat_store_close(me->windex);
852 rdfstore_flat_store_close(me->statements);
853
854 RDFSTORE_FREE(me);
855 me = NULL;
856
857 return 0;
858 };
859
860 int
rdfstore_isconnected(rdfstore * me)861 rdfstore_isconnected(
862 rdfstore * me
863 ) {
864 return (me->model != NULL) ? 0 : 1;
865 };
866
867 /*
868 * perhaps in the future we might have different tables on different servers
869 * or some local/in-memory
870 */
871 int
rdfstore_isremote(rdfstore * me)872 rdfstore_isremote(
873 rdfstore * me
874 ) {
875 return ( (rdfstore_isconnected(me)==0) && ( rdfstore_flat_store_isremote(me->model) == 1 ) ) ? 0 : 1;
876 };
877
878 int
rdfstore_size(rdfstore * me,unsigned int * size)879 rdfstore_size(
880 rdfstore * me,
881 unsigned int *size)
882 {
883
884 DBT key, data;
885 unsigned int removed = 0;
886
887 memset(&key, 0, sizeof(key));
888 memset(&data, 0, sizeof(data));
889
890 key.data = RDFSTORE_COUNTER_REMOVED_KEY;
891 key.size = sizeof(RDFSTORE_COUNTER_REMOVED_KEY);
892 if ((rdfstore_flat_store_fetch(me->model, key, &data)) != 0) {
893 perror("rdfstore_size");
894 fprintf(stderr,"Could not find counter_removed_key for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->model));
895 return -1;
896 };
897
898 /* cast values to int */
899 unpackInt(data.data, &removed);
900 RDFSTORE_FREE(data.data);
901
902 memset(&data, 0, sizeof(data));
903 key.data = RDFSTORE_COUNTER_KEY;
904 key.size = sizeof(RDFSTORE_COUNTER_KEY);
905 if ((rdfstore_flat_store_fetch(me->model, key, &data)) != 0) {
906 perror("rdfstore_size");
907 fprintf(stderr,"Could not find counter_key for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->model));
908 return -1;
909 };
910 unpackInt(data.data, size);
911 RDFSTORE_FREE(data.data);
912
913 #ifdef RDFSTORE_DEBUG
914 fprintf(stderr,"size = %d - %d\n", (*size), removed);
915 #endif
916
917 /* sum them */
918 (*size) -= removed;
919
920 return 0;
921 };
922
923 /* try to be as lightweight as possible here without requiring full-blown rdfstore connections, but just one to model */
rdfstore_if_modified_since(char * name,char * since,void * (* _mmalloc)(size_t s),void (* _mfree)(void * adr),void (* _mcallback)(dbms_cause_t cause,int cnt),void (* _merror)(char * err,int erx))924 int rdfstore_if_modified_since (
925 char * name,
926 char * since,
927 /* Callbacks for memory management and error handling. */
928 void *(*_mmalloc) (size_t s),
929 void (*_mfree) (void *adr),
930 void (*_mcallback) (dbms_cause_t cause, int cnt),
931 void (*_merror) (char *err, int erx)
932 ) {
933 struct tm thedateval_tm;
934 char thedateval[RDFSTORE_XSD_DATETIME_FORMAT_SIZE];
935 DBT key, data;
936 int err=0;
937 FLATDB * model;
938 int port=0;
939 int remote=0;
940 char host[ MAXPATHLEN ];
941
942 strcpy(host, "");
943
944 if( name == NULL ) {
945 return 0;
946 };
947
948 memset(&key, 0, sizeof(key));
949 memset(&data, 0, sizeof(data));
950
951 if( ! rdfstore_xsd_deserialize_dateTime( since, &thedateval_tm ) ) { /* get/normalize passed xsd:dateTime */
952 return -1;
953 };
954
955 rdfstore_xsd_serialize_dateTime( thedateval_tm, thedateval );
956
957 /* get the DB name */
958 if (!strncmp(name,"rdfstore://",(size_t)11)) {
959 char url_port[255];
960 char * p;
961 char * p1;
962 name+=11;
963 p = strstr(name,":");
964 p1 = strstr(name,"/");
965 if(p!=NULL) {
966 /* get the host out */
967 strncpy(host,name,p-name);
968 host[p-name] = '\0';
969 if (strlen(host)<=0) {
970 return -1;
971 };
972 /* get the port out */
973 strncpy(url_port,p+1,p1-(p+1));
974 port = atoi(url_port);
975 if (port<=1) {
976 return -1;
977 };
978 name=p1+1;
979 remote = 1;
980 } else if(p1!=NULL) {
981 /* get the host out */
982 strncpy(host,name,p1-name);
983 host[p1-name] = '\0';
984 if (strlen(host)<=0) {
985 remote = 0;
986 } else {
987 name=p1+1;
988 remote = 1;
989 };
990 };
991 } else if ( (!strncmp(name,"file://",(size_t)7)) ||
992 (!strncmp(name,"http://",(size_t)7)) ) {
993 return -1;
994 };
995
996 /* just one quick / simple connection to model */
997 err = rdfstore_flat_store_open(remote,
998 1, /* read only */
999 &model,
1000 name, (((name == NULL) || (strlen(name) == 0)) ? NULL : "/model"),
1001 (unsigned int)(32 * 1024), host, port,
1002 _mmalloc, _mfree, _mcallback, _merror,
1003 0);
1004 if (err != 0) {
1005 return -1;
1006 };
1007
1008 key.data = RDFSTORE_LASTMODIFIED_KEY;
1009 key.size = sizeof(RDFSTORE_LASTMODIFIED_KEY);
1010
1011 err = rdfstore_flat_store_fetch(model, key, &data);
1012 if (err != 0) {
1013 if (err != FLAT_STORE_E_NOTFOUND) {
1014 perror("rdfstore_if_modified_since");
1015 fprintf(stderr,"Could not find %s key for store '%s': %s\n", RDFSTORE_LASTMODIFIED_KEY, (name != NULL) ? name : "(in-memory)", rdfstore_flat_store_get_error(model));
1016 rdfstore_flat_store_close(model);
1017
1018 return -1;
1019 } else {
1020 rdfstore_flat_store_close(model);
1021
1022 return 1;
1023 };
1024 } else {
1025 if( strcmp( thedateval, data.data ) < 0 ) {
1026 #ifdef RDFSTORE_DEBUG
1027 printf(" %s < %s \n", thedateval, (char*)(data.data) );
1028 #endif
1029 rdfstore_flat_store_close(model);
1030
1031 return 0;
1032 } else {
1033 #ifdef RDFSTORE_DEBUG
1034 printf(" %s >= %s \n", thedateval, (char*)(data.data) );
1035 #endif
1036 rdfstore_flat_store_close(model);
1037
1038 return 1;
1039 };
1040 };
1041 };
1042
1043 int
rdfstore_insert(rdfstore * me,RDF_Statement * statement,RDF_Node * given_context)1044 rdfstore_insert(
1045 rdfstore * me,
1046 RDF_Statement * statement,
1047 RDF_Node * given_context
1048 )
1049 {
1050 RDF_Node *context = NULL;
1051 char *buff = NULL;
1052 char *_buff = NULL;
1053 unsigned int outsize = 0;
1054 unsigned int st_id = 0;
1055 DBT key, data;
1056 unsigned char outbuf[256];
1057 unsigned char outbuf1[256];
1058 unsigned char nodebuf[ 32 * 1024 ];
1059 unsigned char *word;
1060 unsigned char mask = 0;
1061 unsigned char *utf8_casefolded_buff;
1062 unsigned int utf8_size = 0;
1063 char *sep = RDFSTORE_WORD_SPLITS;
1064 int err, l, i = 0;
1065 rdf_store_digest_t hc = 0;
1066
1067 int islval=0;
1068 int isdval=0;
1069 long thelval;
1070 double thedval;
1071 struct tm thedateval_tm;
1072 struct tm* ptm;
1073 time_t now;
1074 char thedateval[RDFSTORE_XSD_DATETIME_FORMAT_SIZE];
1075
1076 assert(sizeof(unsigned char)==1);
1077
1078 #ifdef RDFSTORE_CONNECTIONS
1079 /* buffers for connections matrixes */
1080 static unsigned char s_connections[RDFSTORE_MAXRECORDS_BYTES_SIZE];
1081 static unsigned char p_connections[RDFSTORE_MAXRECORDS_BYTES_SIZE];
1082 static unsigned char o_connections[RDFSTORE_MAXRECORDS_BYTES_SIZE];
1083 unsigned int s_outsize = 0;
1084 unsigned int p_outsize = 0;
1085 unsigned int o_outsize = 0;
1086
1087 bzero(s_connections,sizeof(RDFSTORE_MAXRECORDS_BYTES_SIZE));
1088 bzero(p_connections,sizeof(RDFSTORE_MAXRECORDS_BYTES_SIZE));
1089 bzero(o_connections,sizeof(RDFSTORE_MAXRECORDS_BYTES_SIZE));
1090
1091 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1092 rdfstore_iterator *reindex;
1093 unsigned int pos = 0;
1094 RDF_Statement * neighbour;
1095 unsigned int outsize_reindex = 0;
1096 static unsigned char reindex_encode[RDFSTORE_MAXRECORDS_BYTES_SIZE];
1097 static unsigned char reindex_decode[RDFSTORE_MAXRECORDS_BYTES_SIZE];
1098
1099 bzero(reindex_encode,sizeof(RDFSTORE_MAXRECORDS_BYTES_SIZE));
1100 bzero(reindex_decode,sizeof(RDFSTORE_MAXRECORDS_BYTES_SIZE));
1101 #endif
1102
1103 #endif
1104
1105 /*
1106 int ttime=0; struct timeval tstart,tnow;
1107 */
1108
1109 /*
1110 gettimeofday(&tstart,NULL);
1111 */
1112
1113 #ifdef RDFSTORE_FLAT_STORE_DEBUG /*&& RDFSTORE_COUNT_OPERATIONS_PER_STATEMENT*/
1114 rdfstore_flat_store_reset_debuginfo(me->model);
1115 rdfstore_flat_store_reset_debuginfo(me->statements);
1116 rdfstore_flat_store_reset_debuginfo(me->nodes);
1117 rdfstore_flat_store_reset_debuginfo(me->subjects);
1118 rdfstore_flat_store_reset_debuginfo(me->predicates);
1119 rdfstore_flat_store_reset_debuginfo(me->objects);
1120 #ifdef RDFSTORE_CONNECTIONS
1121 if(me->s_connections)
1122 rdfstore_flat_store_reset_debuginfo(me->s_connections);
1123 if(me->p_connections)
1124 rdfstore_flat_store_reset_debuginfo(me->p_connections);
1125 if(me->o_connections)
1126 rdfstore_flat_store_reset_debuginfo(me->o_connections);
1127 #endif
1128 if(me->languages)
1129 rdfstore_flat_store_reset_debuginfo(me->languages);
1130 if(me->datatypes)
1131 rdfstore_flat_store_reset_debuginfo(me->datatypes);
1132 if(me->xsd_integer)
1133 rdfstore_flat_store_reset_debuginfo(me->xsd_integer);
1134 if(me->xsd_double)
1135 rdfstore_flat_store_reset_debuginfo(me->xsd_double);
1136 if(me->xsd_date)
1137 rdfstore_flat_store_reset_debuginfo(me->xsd_date);
1138 if (context != NULL)
1139 rdfstore_flat_store_reset_debuginfo(me->contexts);
1140 if (me->freetext)
1141 rdfstore_flat_store_reset_debuginfo(me->windex);
1142 fprintf(stderr,"rdfstore_insert BEGIN (reset number of DB operations)\n");
1143 #endif
1144
1145 if ((statement == NULL) ||
1146 (statement->subject == NULL) ||
1147 (statement->predicate == NULL) ||
1148 (statement->subject->value.resource.identifier == NULL) ||
1149 (statement->predicate->value.resource.identifier == NULL) ||
1150 (statement->object == NULL) ||
1151 ((statement->object->type != 1) &&
1152 (statement->object->value.resource.identifier == NULL)) ||
1153 ((given_context != NULL) &&
1154 (given_context->value.resource.identifier == NULL)) ||
1155 ((statement->node != NULL) &&
1156 (statement->node->value.resource.identifier == NULL))) {
1157 #ifdef RDFSTORE_DEBUG
1158 fprintf(stderr,"Wrong params\n");
1159 #endif
1160 return -1;
1161 }
1162
1163 if (given_context == NULL) {
1164 if (statement->context != NULL)
1165 context = statement->context;
1166 else {
1167 /* use default context */
1168 if (me->context != NULL)
1169 context = me->context;
1170 };
1171 } else {
1172 /* use given context instead */
1173 context = given_context;
1174 };
1175
1176 #ifdef RDFSTORE_DEBUG
1177 fprintf(stderr,"TO ADD:\n");
1178 fprintf(stderr,"\tS='%s'\n", statement->subject->value.resource.identifier);
1179 fprintf(stderr,"\tP='%s'\n", statement->predicate->value.resource.identifier);
1180 if (statement->object->type != 1) {
1181 fprintf(stderr,"\tO='%s'\n", statement->object->value.resource.identifier);
1182 } else {
1183 fprintf(stderr,"\tOLIT='%s'", statement->object->value.literal.string);
1184 fprintf(stderr," LANG='%s'", statement->object->value.literal.lang);
1185 fprintf(stderr," TYPE='%s'", statement->object->value.literal.dataType);
1186 fprintf(stderr," PARSETYPE='%d'", statement->object->value.literal.parseType);
1187 fprintf(stderr,"\n");
1188 };
1189 if (context != NULL) {
1190 fprintf(stderr,"\tC='%s'\n", context->value.resource.identifier);
1191 };
1192 if (statement->node != NULL)
1193 fprintf(stderr,"\tSRES='%s'\n", statement->node->value.resource.identifier);
1194 fprintf(stderr," with options freetext='%d'\n", me->freetext);
1195 if ((buff = rdfstore_ntriples_statement(statement, context)) != NULL) {
1196 fprintf(stderr," N-triples: %s\n", buff);
1197 RDFSTORE_FREE(buff);
1198 };
1199 #endif
1200
1201 memset(&key, 0, sizeof(key));
1202 memset(&data, 0, sizeof(data));
1203
1204 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1205 /* init re-index iterator (needed below when filling up adjacency matrixes) */
1206 reindex = (rdfstore_iterator *) RDFSTORE_MALLOC(sizeof(rdfstore_iterator));
1207 if (reindex == NULL) {
1208 perror("rdfstore_insert");
1209 fprintf(stderr,"Cannot create reindex cursor/iterator for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
1210 return -1;
1211 };
1212 reindex->store = me;
1213 reindex->store->attached++;
1214 reindex->remove_holes = 0; /* reset the total number of holes */
1215 reindex->st_counter = 0;
1216 reindex->pos = 0;
1217 reindex->ids_size = 0;
1218 reindex->size = 0;
1219 #endif
1220
1221 /* compute statement hashcode */
1222 hc = rdfstore_digest_get_statement_hashCode(statement, context);
1223
1224 /* cache the hashcode if the statement has a "proper" identity */
1225 if ((given_context == NULL) &&
1226 (me->context == NULL))
1227 statement->hashcode = hc;
1228
1229 /* we do not want duplicates (in the same context) */
1230 packInt(hc, outbuf);
1231
1232 #ifdef RDFSTORE_DEBUG
1233 printf("Statement hashcode is '%d' while packed is '", hc);
1234 for (i = 0; i < sizeof(int); i++) {
1235 printf("%02X", outbuf[i]);
1236 };
1237 printf("'\n");
1238 #endif
1239
1240 key.data = outbuf;
1241 key.size = sizeof(int);
1242 if ((rdfstore_flat_store_exists(me->statements, key)) == 0) {
1243 #ifdef RDFSTORE_DEBUG
1244 if ((buff = rdfstore_ntriples_statement(statement, context)) != NULL) {
1245 fprintf(stderr,"Cannot insert multiple copies of the statement '%s' for store '%s' on key=%x\n",
1246 buff, (me->name != NULL) ? me->name : "(in-memory)",(int)((int *)(outbuf)));
1247 RDFSTORE_FREE(buff);
1248 };
1249 #endif
1250 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1251 rdfstore_iterator_close(reindex);
1252 #endif
1253 return 1;
1254 };
1255
1256 /*
1257 * NOTE about interpretation of contexts:
1258 *
1259 * E.g. If the context is the timestamp of yesterday we can insert a
1260 * statement in that context (temporal context); then we can retrieve
1261 * it in the given context 'has somebody said something yesterday
1262 * about the statement?'. The answer would be affermative. In case
1263 * the context is not set it make a lot of sense ask to the database
1264 * 'has never been said something about the statement (ever!)?'; the
1265 * answer would be the same and affermative. If the context would be
1266 * another one for example the timestamp of today, than the answer to
1267 * the question 'has somebody said something today about the
1268 * statement?' would be definitively *false*. This example can be
1269 * applied to RSS1.0 feeds of news if you wish....
1270 *
1271 * This to me is really much the same of 'views' (or grouping??!?)
1272 * concept in traditional relational databases
1273 */
1274
1275 /*
1276 * About the indexing algorithm see doc/SWADe-rdfstore.html
1277 */
1278
1279 /* store the STATEMENT */
1280 key.data = RDFSTORE_COUNTER_KEY;
1281 key.size = sizeof(RDFSTORE_COUNTER_KEY);
1282
1283 /* increment statement counter */
1284 if ((rdfstore_flat_store_inc(me->model, key, &data)) != 0) {
1285 perror("rdfstore_insert");
1286 fprintf(stderr,"Could not increment statement counter for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->model));
1287 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1288 rdfstore_iterator_close(reindex);
1289 #endif
1290 return -1;
1291 };
1292 unpackInt(data.data,&st_id);
1293
1294 RDFSTORE_FREE(data.data);
1295
1296 #ifdef RDFSTORE_DEBUG
1297 {
1298 fprintf(stderr, "New statement identifier: %d > %d\n", (int)st_id, (int)RDFSTORE_MAXRECORDS);
1299 };
1300 #endif
1301
1302 if (st_id > RDFSTORE_MAXRECORDS) {
1303 if ((rdfstore_flat_store_dec(me->model, key, &data)) == 0)
1304 RDFSTORE_FREE(data.data);
1305 perror("rdfstore_insert");
1306 fprintf(stderr,"RDFSTORE_MAXRECORDS(%d) reached (st_id=%d) - can not insert more statements in store '%s': %s\n", RDFSTORE_MAXRECORDS, st_id, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->model));
1307 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1308 rdfstore_iterator_close(reindex);
1309 #endif
1310 return -1;
1311 };
1312
1313 /* the counter starts from zero anyway! */
1314 st_id--;
1315
1316 /* force this (or warning/error returned ?? ) */
1317 /*
1318 * rdf:parseType="Literal" is like
1319 * rdf:datatype="http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral" - is it still after new RDF specs?
1320 */
1321 if (statement->object->type == 1) {
1322 if ((statement->object->value.literal.parseType == 1) &&
1323 (statement->object->value.literal.dataType != NULL) &&
1324 (strcmp(statement->object->value.literal.dataType, RDFSTORE_RDF_PARSETYPE_LITERAL))) {
1325 perror("rdfstore_insert");
1326 fprintf(stderr,"Statement object '%s' has rdf:parseType='Literal' but rdf:dataType='%s'\n", statement->object->value.literal.string, statement->object->value.literal.dataType);
1327 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1328 rdfstore_iterator_close(reindex);
1329 #endif
1330 return -1;
1331 } else if ((statement->object->value.literal.dataType != NULL) &&
1332 (strcmp(statement->object->value.literal.dataType, RDFSTORE_RDF_PARSETYPE_LITERAL) == 0) &&
1333 (statement->object->value.literal.parseType != 1)) {
1334 perror("rdfstore_insert");
1335 fprintf(stderr,"Statement object '%s' has rdf:dataType='%s' but rdf:parseType='Resource'\n", statement->object->value.literal.string, RDFSTORE_RDF_PARSETYPE_LITERAL);
1336 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1337 rdfstore_iterator_close(reindex);
1338 #endif
1339 return -1;
1340 };
1341 };
1342
1343 /* nodes table */
1344
1345 /* try to allocate just the necessary - this means that
1346 * we must use memcpy (and not strcpy) to fill it as other
1347 * wise the extra \0 throws us one off.
1348 */
1349 l = (sizeof(int) * 7) + sizeof(char) +
1350 (sizeof(char) * statement->subject->value.resource.identifier_len)+
1351 (sizeof(char) * statement->predicate->value.resource.identifier_len) +
1352 ((statement->object->type != 1) ?
1353 (sizeof(char) * statement->object->value.resource.identifier_len) :
1354 ((sizeof(char) * ((statement->object->value.literal.string != NULL) ? statement->object->value.literal.string_len : 0)) +
1355 (((statement->object->value.literal.lang != NULL) && (strlen(statement->object->value.literal.lang) > 0)) ?
1356 (sizeof(char) * strlen(statement->object->value.literal.lang)) : 0) +
1357 ((statement->object->value.literal.dataType != NULL) ? (sizeof(char) * strlen(statement->object->value.literal.dataType)) : 0))) +
1358 ((context != NULL) ?
1359 (sizeof(char) * context->value.resource.identifier_len) : 0) +
1360 ((statement->node != NULL) ?
1361 (sizeof(char) * statement->node->value.resource.identifier_len) : 0);
1362
1363 if (l < sizeof(nodebuf))
1364 buff = nodebuf;
1365 else
1366 buff = _buff = (char *)RDFSTORE_MALLOC(l);
1367
1368 if (buff == NULL) {
1369 perror("rdfstore_insert");
1370 fprintf(stderr,"Could not allocate memory for statement in store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
1371 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1372 rdfstore_iterator_close(reindex);
1373 #endif
1374 return -1;
1375 };
1376
1377 assert(sizeof(int) == 4);
1378
1379 /* offsets */
1380 i = 0;
1381
1382 /* subject */
1383 packInt(statement->subject->value.resource.identifier_len, outbuf);
1384 memcpy(buff + i, outbuf, sizeof(int));
1385 i += sizeof(int);
1386
1387 /* predicate */
1388 packInt(statement->predicate->value.resource.identifier_len, outbuf);
1389 memcpy(buff + i, outbuf, sizeof(int));
1390 i += sizeof(int);
1391
1392 /* object */
1393 packInt((statement->object->type != 1) ?
1394 statement->object->value.resource.identifier_len :
1395 (statement->object->value.literal.string != NULL) ? statement->object->value.literal.string_len : 0, outbuf);
1396 memcpy(buff + i, outbuf, sizeof(int));
1397 i += sizeof(int);
1398
1399 /* object literal language */
1400 packInt(((statement->object->type == 1) && (statement->object->value.literal.lang != NULL) && (strlen(statement->object->value.literal.lang) > 0)) ? strlen(statement->object->value.literal.lang) : 0, outbuf);
1401 memcpy(buff + i, outbuf, sizeof(int));
1402 i += sizeof(int);
1403
1404 /* object literal data type */
1405 packInt(((statement->object->type == 1) && (statement->object->value.literal.dataType != NULL)) ? strlen(statement->object->value.literal.dataType) : 0, outbuf);
1406 memcpy(buff + i, outbuf, sizeof(int));
1407 i += sizeof(int);
1408
1409 /* context */
1410 packInt((context != NULL) ? context->value.resource.identifier_len : 0, outbuf);
1411 memcpy(buff + i, outbuf, sizeof(int));
1412 i += sizeof(int);
1413
1414 /* statement resource hashcode (if statement is a resource) */
1415 packInt((statement->node != NULL) ? statement->node->value.resource.identifier_len : 0, outbuf);
1416 memcpy(buff + i, outbuf, sizeof(int));
1417 i += sizeof(int);
1418
1419 /* mask for special byte */
1420 if (statement->object->type == 1)
1421 mask |= 1;
1422
1423 if (statement->subject->type == 2)
1424 mask |= 2;
1425
1426 if (statement->predicate->type == 2)
1427 mask |= 4;
1428
1429 if (statement->object->type == 2)
1430 mask |= 8;
1431
1432 if ((context != NULL) &&
1433 (context->type == 2))
1434 mask |= 16;
1435
1436 if (statement->isreified == 1)
1437 mask |= 32;
1438
1439 memcpy(buff + i, &mask, 1);
1440 i++;
1441
1442 /* subject */
1443 memcpy(buff + i, statement->subject->value.resource.identifier, statement->subject->value.resource.identifier_len);
1444 i += statement->subject->value.resource.identifier_len;
1445
1446 /* predicate */
1447 memcpy(buff + i, statement->predicate->value.resource.identifier, statement->predicate->value.resource.identifier_len);
1448 i += statement->predicate->value.resource.identifier_len;
1449
1450 /* object */
1451 if (statement->object->type == 1) {
1452 /* object literal string itself */
1453 if (statement->object->value.literal.string != NULL) {
1454 memcpy(buff + i, statement->object->value.literal.string, statement->object->value.literal.string_len);
1455 i += statement->object->value.literal.string_len;
1456 };
1457 /* object literal language */
1458 if (statement->object->value.literal.lang != NULL) {
1459 memcpy(buff + i, statement->object->value.literal.lang, strlen(statement->object->value.literal.lang));
1460 i += strlen(statement->object->value.literal.lang);
1461 };
1462 /* object literal data type */
1463 if (statement->object->value.literal.dataType != NULL) {
1464 memcpy(buff + i, statement->object->value.literal.dataType, strlen(statement->object->value.literal.dataType));
1465 i += strlen(statement->object->value.literal.dataType);
1466 };
1467 } else {
1468 memcpy(buff + i, statement->object->value.resource.identifier, statement->object->value.resource.identifier_len);
1469 i += statement->object->value.resource.identifier_len;
1470 };
1471
1472 /* context */
1473 if (context != NULL) {
1474 memcpy(buff + i, context->value.resource.identifier, context->value.resource.identifier_len);
1475 i += context->value.resource.identifier_len;
1476 };
1477
1478 /* statement as resource stuff */
1479 if (statement->node != NULL) {
1480 memcpy(buff + i, statement->node->value.resource.identifier, statement->node->value.resource.identifier_len);
1481 i += statement->node->value.resource.identifier_len;
1482 };
1483
1484 /* Check out lenght calcuation.. */
1485 assert(l == i);
1486
1487 /* store the whole content */
1488 packInt(st_id, outbuf);
1489
1490 key.data = outbuf;
1491 key.size = sizeof(int);
1492
1493 buff[i++] = '\0'; /* Terminate the string and increase the length */
1494 data.data = buff;
1495 data.size = i;
1496
1497 err = rdfstore_flat_store_store(me->nodes, key, data);
1498
1499 if (_buff)
1500 RDFSTORE_FREE(_buff);
1501
1502 if ((err != 0) &&
1503 (err != FLAT_STORE_E_KEYEXIST)) {
1504 perror("rdfstore_insert");
1505 fprintf(stderr,"Could not store '%d' bytes for statememt in nodes for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->nodes));
1506 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1507 rdfstore_iterator_close(reindex);
1508 #endif
1509 return -1;
1510 };
1511
1512 /* index special literal stuff */
1513 if (statement->object->type == 1) {
1514 if ( (me->freetext) &&
1515 (statement->object->value.literal.string != NULL) &&
1516 (statement->object->value.literal.string_len > 0) ) {
1517 utf8_casefolded_buff = (unsigned char *)RDFSTORE_MALLOC(statement->object->value.literal.string_len * sizeof(unsigned char) * (RDFSTORE_UTF8_MAXLEN_FOLD + 1)); /* what about the ending '\0' here ?? */
1518 if (utf8_casefolded_buff == NULL) {
1519 perror("rdfstore_insert");
1520 fprintf(stderr,"Cannot compute case-folded string out of input literal for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
1521 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1522 rdfstore_iterator_close(reindex);
1523 #endif
1524 return -1;
1525 };
1526 if (rdfstore_utf8_string_to_utf8_foldedcase(statement->object->value.literal.string_len, statement->object->value.literal.string, &utf8_size, utf8_casefolded_buff)) {
1527 perror("rdfstore_insert");
1528 fprintf(stderr,"Cannot compute case-folded string out of input literal for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
1529 RDFSTORE_FREE(utf8_casefolded_buff);
1530 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1531 rdfstore_iterator_close(reindex);
1532 #endif
1533 return -1;
1534 };
1535
1536 /* we do not even try to avoid duplicates for the moment */
1537 for ( word = strtok(utf8_casefolded_buff, sep);
1538 word;
1539 word = strtok(NULL, sep) ) {
1540 int jj=0;
1541 int kk=0;
1542
1543 key.data = word;
1544 key.size = strlen(word);
1545
1546 /*
1547 *
1548 * bzero(me->bits_encode,sizeof(me->bits_encode
1549 * ));
1550 * bzero(me->bits_decode,sizeof(me->bits_decod
1551 * e));
1552 */
1553 err = rdfstore_flat_store_fetch_compressed(me->windex, me->func_decode, key, &outsize, me->bits_decode);
1554 if (err != 0) {
1555 if (err != FLAT_STORE_E_NOTFOUND) {
1556 RDFSTORE_FREE(utf8_casefolded_buff);
1557 perror("rdfstore_insert");
1558 fprintf(stderr,"Could not fetch windex of word '%s' for store '%s': %s\n", word, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->windex));
1559 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1560 rdfstore_iterator_close(reindex);
1561 #endif
1562 return -1;
1563 } else {
1564 outsize = 0;
1565 };
1566 };
1567
1568 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 1, sizeof(me->bits_decode));
1569
1570 if (outsize) {
1571 err = rdfstore_flat_store_store_compressed(me->windex, me->func_encode, key, outsize, me->bits_decode,me->bits_encode );
1572 if (err == 0) {
1573 #ifdef RDFSTORE_DEBUG_COMPRESSION
1574 fprintf(stderr,"Stored %d bytes for '%s' in windex for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
1575 #endif
1576 } else {
1577 if (err != FLAT_STORE_E_KEYEXIST) {
1578 RDFSTORE_FREE(utf8_casefolded_buff);
1579 perror("rdfstore_insert");
1580 fprintf(stderr,"Could not store '%d' bytes for word '%s' in windex for store '%s': %s\n", (int)data.size, word, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->windex));
1581 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1582 rdfstore_iterator_close(reindex);
1583 #endif
1584 return -1;
1585 };
1586 };
1587
1588 #ifdef RDFSTORE_DEBUG
1589 {
1590 int i;
1591 if ((rdfstore_flat_store_fetch(me->windex, key, &data)) == 0) {
1592 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
1593 RDFSTORE_FREE(data.data);
1594 };
1595 printf("ADDED (%d) windex for case-folded word '%s' -->'", st_id, word);
1596 for(i=0;i<8*outsize;i++) {
1597 printf("Rec %d %c\n", i, (me->bits_decode[i>>3] & (1<<(i&7))) ? '1':'0');
1598 };
1599 printf("'\n");
1600 }
1601 #endif
1602
1603 };
1604
1605 /*
1606 stemming code for ISO-Latin languiages (left-to-right) and shouild be UTF-8 aware
1607 ie. word = "stemming" -- do index --> "s", "st", "ste", ....
1608 */
1609 #if RDFSTORE_WORD_STEMMING > 0
1610
1611 if( ( rdfstore_xsd_deserialize_integer( word, &thelval ) ) ||
1612 ( rdfstore_xsd_deserialize_double( word, &thedval ) ) ||
1613 ( rdfstore_xsd_deserialize_dateTime( word,
1614 &thedateval_tm ) ) ||
1615 ( rdfstore_xsd_deserialize_date( word,
1616 &thedateval_tm ) ) || /* dates are skipped, even if rdf:datatype is not set */
1617 (strlen(word)<=1) )
1618 continue;
1619
1620 /* for efficency we should check if the given partial stem has been already indexed for the same word!!! */
1621 jj=1;
1622 while ( ( jj < strlen(word) ) &&
1623 ( kk < RDFSTORE_WORD_STEMMING ) ) {
1624 char stem[MIN((RDFSTORE_WORD_STEMMING*RDFSTORE_UTF8_MAXLEN_FOLD),strlen(word))+1];
1625
1626 bzero(stem,MIN((RDFSTORE_WORD_STEMMING*RDFSTORE_UTF8_MAXLEN_FOLD),strlen(word))+1);
1627
1628 /* look for next utf8 char to add to stemming string */
1629 utf8_size=0;
1630 while ( ( jj < strlen(word) ) &&
1631 (!( rdfstore_utf8_is_utf8( word+jj, &utf8_size ) )) ) {
1632 jj++;
1633 };
1634
1635 if (jj>strlen(word)) {
1636 strncpy(stem, word, jj-1);
1637 } else {
1638 strncpy(stem, word, jj);
1639 };
1640
1641 key.data = stem;
1642 key.size = strlen(stem);
1643
1644 err = rdfstore_flat_store_fetch(me->windex, key, &data);
1645 if (err != 0) {
1646 if (err != FLAT_STORE_E_NOTFOUND) {
1647 RDFSTORE_FREE(utf8_casefolded_buff);
1648 perror("rdfstore_insert");
1649 fprintf(stderr,"Could not fetch windex of stemming '%s' of word '%s' for store '%s': %s\n", stem, word, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->windex));
1650 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1651 rdfstore_iterator_close(reindex);
1652 #endif
1653 return -1;
1654 } else {
1655 outsize = 0;
1656 };
1657 } else {
1658 me->func_decode(data.size, data.data, &outsize, me->bits_decode); /* perhaps the
1659 * compression for
1660 * single bits could be
1661 * different */
1662 RDFSTORE_FREE(data.data);
1663 };
1664 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 1, sizeof(me->bits_decode));
1665
1666 me->func_encode(outsize, me->bits_decode, &outsize, me->bits_encode);
1667 if (outsize) {
1668 data.data = me->bits_encode;
1669 data.size = outsize;
1670 err = rdfstore_flat_store_store(me->windex, key, data);
1671 if (err == 0) {
1672 #ifdef RDFSTORE_DEBUG_COMPRESSION
1673 fprintf(stderr,"Stored %d bytes for '%s' in windex for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
1674 #endif
1675 } else {
1676 if (err != FLAT_STORE_E_KEYEXIST) {
1677 RDFSTORE_FREE(utf8_casefolded_buff);
1678 perror("rdfstore_insert");
1679 fprintf(stderr,"Could not store '%d' bytes for stemming '%s' in windex for store '%s': %s\n", (int)data.size, stem, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->windex));
1680 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1681 rdfstore_iterator_close(reindex);
1682 #endif
1683 return -1;
1684 };
1685 };
1686
1687 #ifdef RDFSTORE_DEBUG
1688 {
1689 int i;
1690 if ((rdfstore_flat_store_fetch(me->windex, key, &data)) == 0) {
1691 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
1692 RDFSTORE_FREE(data.data);
1693 };
1694 printf("ADDED (%d) windex for case-folded stemming '%s' of word '%s' -->'", st_id, stem, word);
1695 for (i = 0; i < outsize; i++) {
1696 printf("%02X", me->bits_decode[i]);
1697 };
1698 printf("'\n");
1699 }
1700 #endif
1701
1702 };
1703 jj++;
1704 kk++;
1705 };
1706 #endif
1707 };
1708 RDFSTORE_FREE(utf8_casefolded_buff);
1709 };
1710
1711 /* languages table */
1712 if ( (statement->object->value.literal.lang != NULL) &&
1713 (strlen(statement->object->value.literal.lang) > 0) ) {
1714 utf8_casefolded_buff = (unsigned char *)RDFSTORE_MALLOC(strlen(statement->object->value.literal.lang) * sizeof(unsigned char) * (RDFSTORE_UTF8_MAXLEN_FOLD + 1));
1715 if (utf8_casefolded_buff == NULL) {
1716 perror("rdfstore_insert");
1717 fprintf(stderr,"Cannot compute case-folded string for literal language code '%s' for store '%s'\n", statement->object->value.literal.lang, (me->name != NULL) ? me->name : "(in-memory)");
1718 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1719 rdfstore_iterator_close(reindex);
1720 #endif
1721 return -1;
1722 };
1723 if (rdfstore_utf8_string_to_utf8_foldedcase(strlen(statement->object->value.literal.lang), statement->object->value.literal.lang, &utf8_size, utf8_casefolded_buff)) {
1724 perror("rdfstore_insert");
1725 fprintf(stderr,"Cannot compute case-folded string for literal language code '%s' for store '%s'\n", statement->object->value.literal.lang, (me->name != NULL) ? me->name : "(in-memory)");
1726 RDFSTORE_FREE(utf8_casefolded_buff);
1727 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1728 rdfstore_iterator_close(reindex);
1729 #endif
1730 return -1;
1731 };
1732
1733 key.data = utf8_casefolded_buff;
1734 key.size = utf8_size;
1735
1736 err = rdfstore_flat_store_fetch(me->languages, key, &data);
1737 if (err != 0) {
1738 if (err != FLAT_STORE_E_NOTFOUND) {
1739 RDFSTORE_FREE(utf8_casefolded_buff);
1740 perror("rdfstore_insert");
1741 fprintf(stderr,"Could not fetch language '%s' of literal '%s' for store '%s': %s\n", statement->object->value.literal.lang, statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->languages));
1742 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1743 rdfstore_iterator_close(reindex);
1744 #endif
1745 return -1;
1746 } else {
1747 outsize = 0;
1748 };
1749 } else {
1750 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
1751 RDFSTORE_FREE(data.data);
1752 };
1753 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 1, sizeof(me->bits_decode));
1754
1755 me->func_encode(outsize, me->bits_decode, &outsize, me->bits_encode);
1756 if (outsize) {
1757 data.data = me->bits_encode;
1758 data.size = outsize;
1759 err = rdfstore_flat_store_store(me->languages, key, data);
1760 if (err == 0) {
1761 #ifdef RDFSTORE_DEBUG_COMPRESSION
1762 fprintf(stderr,"Stored %d bytes for '%s' in languages for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
1763 #endif
1764 } else {
1765 if (err != FLAT_STORE_E_KEYEXIST) {
1766 RDFSTORE_FREE(utf8_casefolded_buff);
1767 perror("rdfstore_insert");
1768 fprintf(stderr,"Could not store '%d' bytes for language '%s' in languages for store '%s': %s\n", (int)data.size, statement->object->value.literal.lang, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->languages));
1769 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1770 rdfstore_iterator_close(reindex);
1771 #endif
1772 return -1;
1773 };
1774 };
1775
1776 #ifdef RDFSTORE_DEBUG
1777 {
1778 int i;
1779 if ((rdfstore_flat_store_fetch(me->languages, key, &data)) == 0) {
1780 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
1781 RDFSTORE_FREE(data.data);
1782 };
1783 printf("ADDED (%d) language '%s' of literal '%s' -->'", st_id, statement->object->value.literal.lang, statement->object->value.literal.string);
1784 for (i = 0; i < outsize; i++) {
1785 printf("%02X", me->bits_decode[i]);
1786 };
1787 printf("'\n");
1788 }
1789 #endif
1790
1791 };
1792
1793 RDFSTORE_FREE(utf8_casefolded_buff);
1794 };
1795
1796 /* datatypes table */
1797 if ( (statement->object->value.literal.dataType != NULL) &&
1798 (strlen(statement->object->value.literal.dataType) > 0) ) {
1799 key.data = statement->object->value.literal.dataType;
1800 key.size = strlen(statement->object->value.literal.dataType);
1801
1802 err = rdfstore_flat_store_fetch(me->datatypes, key, &data);
1803 if (err != 0) {
1804 if (err != FLAT_STORE_E_NOTFOUND) {
1805 perror("rdfstore_insert");
1806 fprintf(stderr,"Could not fetch datatype '%s' of literal '%s' for store '%s': %s\n", statement->object->value.literal.dataType, statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->datatypes));
1807 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1808 rdfstore_iterator_close(reindex);
1809 #endif
1810 return -1;
1811 } else {
1812 outsize = 0;
1813 };
1814 } else {
1815 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
1816 RDFSTORE_FREE(data.data);
1817 };
1818 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 1, sizeof(me->bits_decode));
1819
1820 me->func_encode(outsize, me->bits_decode, &outsize, me->bits_encode);
1821 if (outsize) {
1822 data.data = me->bits_encode;
1823 data.size = outsize;
1824 err = rdfstore_flat_store_store(me->datatypes, key, data);
1825 if (err == 0) {
1826 #ifdef RDFSTORE_DEBUG_COMPRESSION
1827 fprintf(stderr,"Stored %d bytes for '%s' in datatypes for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
1828 #endif
1829 } else {
1830 if (err != FLAT_STORE_E_KEYEXIST) {
1831 perror("rdfstore_insert");
1832 fprintf(stderr,"Could not store '%d' bytes for datatype '%s' in datatypes for store '%s': %s\n", (int)data.size, statement->object->value.literal.dataType, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->datatypes));
1833 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1834 rdfstore_iterator_close(reindex);
1835 #endif
1836 return -1;
1837 };
1838 };
1839
1840 #ifdef RDFSTORE_DEBUG
1841 {
1842 int i;
1843 if ((rdfstore_flat_store_fetch(me->datatypes, key, &data)) == 0) {
1844 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
1845 RDFSTORE_FREE(data.data);
1846 };
1847 printf("ADDED (%d) datatype '%s' of literal '%s' -->'", st_id, statement->object->value.literal.dataType, statement->object->value.literal.string);
1848 for (i = 0; i < outsize; i++) {
1849 printf("%02X", me->bits_decode[i]);
1850 };
1851 printf("'\n");
1852 }
1853 #endif
1854
1855 };
1856
1857 /* date type indexing only if rdf:datatype is set accordingly to xsd:date or xsd:dateTime */
1858 if( (strcmp(statement->object->value.literal.dataType,RDFSTORE_MS_XSD_DATE)==0) ||
1859 (strcmp(statement->object->value.literal.dataType,RDFSTORE_MS_XSD_DATETIME)==0) ) {
1860 if ( ( rdfstore_xsd_deserialize_dateTime( statement->object->value.literal.string,
1861 &thedateval_tm ) ) ||
1862 ( rdfstore_xsd_deserialize_date( statement->object->value.literal.string,
1863 &thedateval_tm ) ) ) {
1864
1865 rdfstore_xsd_serialize_dateTime( thedateval_tm, thedateval ); /* we index xsd:dataTime version anyway */
1866
1867 key.data = thedateval;
1868 key.size = strlen(thedateval)+1;
1869
1870 #ifdef RDFSTORE_DEBUG
1871 fprintf(stderr, "INDEX DATE '%s' for LITERAL '%s' \n",thedateval, statement->object->value.literal.string);
1872 #endif
1873
1874 err = rdfstore_flat_store_fetch(me->xsd_date, key, &data);
1875 if (err != 0) {
1876 if (err != FLAT_STORE_E_NOTFOUND) {
1877 perror("rdfstore_insert");
1878 fprintf(stderr,"Could not fetch from date table value '%s' for store '%s': %s\n", statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->xsd_date));
1879 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1880 rdfstore_iterator_close(reindex);
1881 #endif
1882 return -1;
1883 } else {
1884 outsize = 0;
1885 };
1886 } else {
1887 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
1888 RDFSTORE_FREE(data.data);
1889 };
1890 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 1, sizeof(me->bits_decode));
1891
1892 me->func_encode(outsize, me->bits_decode, &outsize, me->bits_encode);
1893 if (outsize) {
1894 data.data = me->bits_encode;
1895 data.size = outsize;
1896 err = rdfstore_flat_store_store(me->xsd_date, key, data);
1897 if (err == 0) {
1898 #ifdef RDFSTORE_DEBUG_COMPRESSION
1899 fprintf(stderr,"Stored %d bytes for date '%s' in literal '%s' in integer table for store '%s'\n", outsize, thedateval, statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)");
1900 #endif
1901 } else {
1902 if (err != FLAT_STORE_E_KEYEXIST) {
1903 perror("rdfstore_insert");
1904 fprintf(stderr,"Could not store '%d' bytes for date '%s' in literal '%s' in date table for store '%s': %s\n", (int)data.size, thedateval, statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->xsd_date));
1905 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1906 rdfstore_iterator_close(reindex);
1907 #endif
1908 return -1;
1909 };
1910 };
1911
1912 #ifdef RDFSTORE_DEBUG
1913 {
1914 int i;
1915 if ((rdfstore_flat_store_fetch(me->xsd_date, key, &data)) == 0) {
1916 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
1917 RDFSTORE_FREE(data.data);
1918 };
1919 printf("ADDED (%d) date '%s' of literal '%s' -->'", st_id, thedateval, statement->object->value.literal.string);
1920 for (i = 0; i < outsize; i++) {
1921 printf("%02X", me->bits_decode[i]);
1922 };
1923 printf("'\n");
1924 }
1925 #endif
1926
1927 };
1928 };
1929 }; /* end of date indexing */
1930 };
1931
1932 /* for xsd:integer alike literals use special b-tree sorted index if strtol() works.... */
1933 if( ( islval = rdfstore_xsd_deserialize_integer( statement->object->value.literal.string, &thelval ) ) != 0 ) {
1934 key.data = (long*) &thelval; /* should pack int perhaps... */
1935 key.size = sizeof(long);
1936
1937 #ifdef RDFSTORE_DEBUG
1938 fprintf(stderr, "INDEX INTEGER '%ld' for LITERAL '%s' \n",(long)thelval, statement->object->value.literal.string);
1939 #endif
1940
1941 err = rdfstore_flat_store_fetch(me->xsd_integer, key, &data);
1942 if (err != 0) {
1943 if (err != FLAT_STORE_E_NOTFOUND) {
1944 perror("rdfstore_insert");
1945 fprintf(stderr,"Could not fetch from integer table value '%s' for store '%s': %s\n", statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->xsd_integer));
1946 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1947 rdfstore_iterator_close(reindex);
1948 #endif
1949 return -1;
1950 } else {
1951 outsize = 0;
1952 };
1953 } else {
1954 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
1955 RDFSTORE_FREE(data.data);
1956 };
1957 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 1, sizeof(me->bits_decode));
1958
1959 me->func_encode(outsize, me->bits_decode, &outsize, me->bits_encode);
1960 if (outsize) {
1961 data.data = me->bits_encode;
1962 data.size = outsize;
1963 err = rdfstore_flat_store_store(me->xsd_integer, key, data);
1964 if (err == 0) {
1965 #ifdef RDFSTORE_DEBUG_COMPRESSION
1966 fprintf(stderr,"Stored %d bytes for integer '%ld' in literal '%s' in integer table for store '%s'\n", outsize, (long)thelval, statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)");
1967 #endif
1968 } else {
1969 if (err != FLAT_STORE_E_KEYEXIST) {
1970 perror("rdfstore_insert");
1971 fprintf(stderr,"Could not store '%d' bytes for integer '%ld' in literal '%s' in integer table for store '%s': %s\n", (int)data.size, (long)thelval, statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->xsd_integer));
1972 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
1973 rdfstore_iterator_close(reindex);
1974 #endif
1975 return -1;
1976 };
1977 };
1978
1979 #ifdef RDFSTORE_DEBUG
1980 {
1981 int i;
1982 if ((rdfstore_flat_store_fetch(me->xsd_integer, key, &data)) == 0) {
1983 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
1984 RDFSTORE_FREE(data.data);
1985 };
1986 printf("ADDED (%d) integer '%ld' of literal '%s' -->'", st_id, (long)thelval, statement->object->value.literal.string);
1987 for (i = 0; i < outsize; i++) {
1988 printf("%02X", me->bits_decode[i]);
1989 };
1990 printf("'\n");
1991 }
1992 #endif
1993
1994 };
1995
1996 };
1997
1998 /* for xsd:double or xsd:float alike literals use special b-tree sorted index if strtod() works.... */
1999 if( ( islval == 0 ) && /* do not index xsd:integer(s) twice also as xsd:double */
2000 ( ( isdval = rdfstore_xsd_deserialize_double( statement->object->value.literal.string, &thedval ) ) != 0 ) ) {
2001 key.data = (double*) &thedval; /* should pack int perhaps... */
2002 key.size = sizeof(double);
2003
2004 #ifdef RDFSTORE_DEBUG
2005 fprintf(stderr, "INDEX DOUBLE '%f' for LITERAL '%s' \n",thedval, statement->object->value.literal.string);
2006 #endif
2007
2008 err = rdfstore_flat_store_fetch(me->xsd_double, key, &data);
2009 if (err != 0) {
2010 if (err != FLAT_STORE_E_NOTFOUND) {
2011 perror("rdfstore_insert");
2012 fprintf(stderr,"Could not fetch from double table value '%s' for store '%s': %s\n", statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->xsd_double));
2013 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2014 rdfstore_iterator_close(reindex);
2015 #endif
2016 return -1;
2017 } else {
2018 outsize = 0;
2019 };
2020 } else {
2021 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
2022 RDFSTORE_FREE(data.data);
2023 };
2024 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 1, sizeof(me->bits_decode));
2025
2026 me->func_encode(outsize, me->bits_decode, &outsize, me->bits_encode);
2027 if (outsize) {
2028 data.data = me->bits_encode;
2029 data.size = outsize;
2030 err = rdfstore_flat_store_store(me->xsd_double, key, data);
2031 if (err == 0) {
2032 #ifdef RDFSTORE_DEBUG_COMPRESSION
2033 fprintf(stderr,"Stored %d bytes for double '%f' in literal '%s' in double table for store '%s'\n", outsize, thedval, statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)");
2034 #endif
2035 } else {
2036 if (err != FLAT_STORE_E_KEYEXIST) {
2037 perror("rdfstore_insert");
2038 fprintf(stderr,"Could not store '%d' bytes for double '%f' in literal '%s' in double table for store '%s': %s\n", (int)data.size, thedval, statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->xsd_double));
2039 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2040 rdfstore_iterator_close(reindex);
2041 #endif
2042 return -1;
2043 };
2044 };
2045
2046 #ifdef RDFSTORE_DEBUG
2047 {
2048 int i;
2049 if ((rdfstore_flat_store_fetch(me->xsd_double, key, &data)) == 0) {
2050 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
2051 RDFSTORE_FREE(data.data);
2052 };
2053 printf("ADDED (%d) double '%f' of literal '%s' -->'", st_id, thedval, statement->object->value.literal.string);
2054 for (i = 0; i < outsize; i++) {
2055 printf("%02X", me->bits_decode[i]);
2056 };
2057 printf("'\n");
2058 }
2059 #endif
2060
2061 };
2062
2063 };
2064 }; /* end index special literal stuff */
2065
2066 /*
2067 * gettimeofday(&tnow,NULL); ttime = ( tnow.tv_sec - tstart.tv_sec ) *
2068 * 1000000 + ( tnow.tv_usec - tstart.tv_usec ) * 1;
2069 * printf("rdfstore_insert DONE [%d micro sec]\n",ttime);
2070 */
2071
2072 /* adjacency matrixes (tables) i.e. subjects, predicates, objects, contexts and connections */
2073
2074 /*
2075 * compute other hashcodes (the should be cached because the
2076 * underlying digest is carried out also for the statement->hashcode
2077 * above)
2078 */
2079 statement->subject->hashcode = rdfstore_digest_get_node_hashCode(statement->subject, 0);
2080 statement->predicate->hashcode = rdfstore_digest_get_node_hashCode(statement->predicate, 0);
2081 statement->object->hashcode = rdfstore_digest_get_node_hashCode(statement->object, 0);
2082 if (context != NULL)
2083 context->hashcode = rdfstore_digest_get_node_hashCode(context, 0);
2084
2085 /*
2086 * possible connections (see doc/SWADe-rdfstore.html)
2087 *
2088 *
2089 * subjects table template:
2090 * -------------------------------------
2091 * st_num 01234567 89..
2092 * node
2093 * -------------------------------------
2094 * subject-node 10000010 00
2095 * -------------------------------------
2096 * ^ ^
2097 * | |
2098 * st_num(0)->subject --+ |
2099 * |
2100 * st_num(6)->subject --------+
2101 *
2102 *
2103 * Similarly the other predicates and objects tables
2104 * are being generated - similarly contexts table is
2105 * filled in for particulat context-node(s) for a
2106 * a given statement.
2107 *
2108 *
2109 * connections tables template: (to be completed)
2110 *
2111 * --> it maps DUG (normalized DLG) graph nodes to their connections and
2112 * corresponding statements
2113 *
2114 *
2115 * Anoatomy of connections insertion/updation
2116 *
2117 * here are all the possible connections a new statement might get into (i.e. "swiss army knife problem"):
2118 *
2119 * a4 a6 a8
2120 * \ \ \
2121 * \ \ \
2122 * \---> A =============> B =============> C------>b9----->c9
2123 * / ^\ /^\ ^\
2124 * / | \ / | \ | \
2125 * b5<---/ | \--->c4 / | \--->c6 | \--->c8
2126 * / b1 / b2 b3
2127 * / ^ b7<---/ ^ ^
2128 * c5<---/ | \ | |
2129 * | \ | |
2130 * a1 \--->c7 a2 a3
2131 *
2132 *
2133 * where A======>B======>C is the new statement to add
2134 *
2135 * then each A, B or C gets it respective connections (s_connection, p_connections or o_connections) table
2136 * set with ALL the possible other connections with the existing statements - the possible connections are
2137 * carried out by a permutation on all possible positions of each s,p,o component node on the subject, predicates
2138 * or objects table values (who has which node). Due that no intrisic ordering of statement can be assumed, quite a
2139 * lot of re-indexing is required when inserting a new statement - such overhaead can be roughly estimated up to 6*3
2140 * re-indexing operations per statement. This is the case when the new statement is being connected to mostly any other
2141 * neighbour statement already existing - the re-indexing require to set the right bitno into connections tables for each
2142 * neighbour its components (see code below now). Of course molteplicity of connections on arcs is assumed not to be a
2143 * problem in the resulting Directed Unlabelled Graph (DUG) of nodes.
2144 *
2145 */
2146
2147 /* subjects */
2148 packInt(statement->subject->hashcode, outbuf);
2149 key.data = outbuf;
2150 key.size = sizeof(int);
2151
2152 /*
2153 * bzero(me->bits_encode,sizeof(me->bits_encode));
2154 * bzero(me->bits_decode,sizeof(me->bits_decode));
2155 */
2156
2157 err = rdfstore_flat_store_fetch(me->subjects, key, &data);
2158 if (err != 0) {
2159 if (err != FLAT_STORE_E_NOTFOUND) {
2160 perror("rdfstore_insert");
2161 fprintf(stderr,"Could not fetch key '%s' for subject in subjects table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->subjects));
2162 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2163 rdfstore_iterator_close(reindex);
2164 #endif
2165 return -1;
2166 } else {
2167 outsize = 0;
2168 };
2169 } else {
2170 me->func_decode(data.size, data.data, &outsize, me->bits_decode); /* perhaps the
2171 * compression for
2172 * single bits could be
2173 * different */
2174 RDFSTORE_FREE(data.data);
2175 };
2176
2177 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2178 /*
2179 We need to re-index quite a lot for each new statement component now - hope caching will
2180 help here!! i.e. the swiss army nife problem (see SWAD-E paper and preso)
2181
2182 1.1) add this new statement (st_id) to p_connections(neighbour->predicate) and o_connections(neighbour->object)
2183 tables of each other statement (neighbour) connected to this one via subjects(SUBJECT) node
2184 1.2) add this new statement (st_id) to s_connections(neighbour->subject) and o_connections(neighbour->object)
2185 tables of each other statement (neighbour) connected to this one via predicates(SUBJECT) node
2186 1.3) add this new statement (st_id) to s_connections(neighbour->subject) and p_connections(neighbour->predicate)
2187 tables of each other statement (neighbour) connected to this one via objects(SUBJECT) node
2188 */
2189
2190 /* 1.1) reindex st_id for connections to subjects(SUBJECT) node */
2191
2192 /* copy the subjects(SUBJECT) bits through the reindex iterator array */
2193 memcpy(reindex->ids, me->bits_decode, outsize);
2194 reindex->ids_size = outsize;
2195 /* set the size - inefficient!! */
2196 pos = 0;
2197 reindex->size = 0;
2198 /* count the ones (inefficient still) */
2199 while ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < 8 * outsize) {
2200 reindex->size++;
2201 pos++;
2202 };
2203
2204 /* scan the obtained iterator */
2205 while ( ( neighbour = rdfstore_iterator_each ( reindex ) ) != NULL ) {
2206
2207 #ifdef RDFSTORE_DEBUG_CONNECTIONS
2208 printf("(insert)REINDEXING predicate '%s' for connections to subjects('%s') node in st_id=%d\n",neighbour->predicate->value.resource.identifier,statement->subject->value.resource.identifier,st_id);
2209 #endif
2210 neighbour->predicate->hashcode = rdfstore_digest_get_node_hashCode(neighbour->predicate, 0);
2211
2212 /* fetch p_connections(neighbour->predicate) */
2213 packInt(neighbour->predicate->hashcode, outbuf); /* wrong */
2214 key.data = outbuf;
2215 key.size = sizeof(int);
2216
2217 err = rdfstore_flat_store_fetch(me->p_connections, key, &data);
2218 if (err != 0) {
2219 if (err != FLAT_STORE_E_NOTFOUND) {
2220 perror("rdfstore_insert");
2221 fprintf(stderr,"Could not fetch key '%s' for predicate in p_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
2222 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2223 rdfstore_iterator_close(reindex);
2224 #endif
2225 return -1;
2226 } else {
2227 outsize_reindex = 0;
2228 };
2229 } else {
2230 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
2231 RDFSTORE_FREE(data.data);
2232 };
2233
2234 /* set the corresponding bit of this statement */
2235 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 1, sizeof(reindex_decode));
2236
2237 /* store it back */
2238 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
2239
2240 data.data = reindex_encode;
2241 data.size = outsize_reindex;
2242 err = rdfstore_flat_store_store(me->p_connections, key, data);
2243 if (err != 0) {
2244 if (err != FLAT_STORE_E_KEYEXIST) {
2245 perror("rdfstore_insert");
2246 fprintf(stderr,"Could not store '%d' bytes for predicate in p_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
2247 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2248 rdfstore_iterator_close(reindex);
2249 #endif
2250 return -1;
2251 };
2252 };
2253
2254 #ifdef RDFSTORE_DEBUG_CONNECTIONS
2255 printf("(insert)REINDEXING object '%s' for connections to subjects('%s') node in st_id=%d\n",(neighbour->object->type==1) ? neighbour->object->value.literal.string : neighbour->object->value.resource.identifier,statement->subject->value.resource.identifier,st_id);
2256 #endif
2257 neighbour->object->hashcode = rdfstore_digest_get_node_hashCode(neighbour->object, 0);
2258
2259 /* fetch o_connections(neighbour->object) */
2260 packInt(neighbour->object->hashcode, outbuf); /* wrong */
2261 key.data = outbuf;
2262 key.size = sizeof(int);
2263
2264 err = rdfstore_flat_store_fetch(me->o_connections, key, &data);
2265 if (err != 0) {
2266 if (err != FLAT_STORE_E_NOTFOUND) {
2267 perror("rdfstore_insert");
2268 fprintf(stderr,"Could not fetch key '%s' for object in o_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
2269 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2270 rdfstore_iterator_close(reindex);
2271 #endif
2272 return -1;
2273 } else {
2274 outsize_reindex = 0;
2275 };
2276 } else {
2277 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
2278 RDFSTORE_FREE(data.data);
2279 };
2280
2281 /* set the corresponding bit of this statement */
2282 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 1, sizeof(reindex_decode));
2283
2284 /* store it back */
2285 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
2286
2287 data.data = reindex_encode;
2288 data.size = outsize_reindex;
2289 err = rdfstore_flat_store_store(me->o_connections, key, data);
2290 if (err != 0) {
2291 if (err != FLAT_STORE_E_KEYEXIST) {
2292 perror("rdfstore_insert");
2293 fprintf(stderr,"Could not store '%d' bytes for object in o_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
2294 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2295 rdfstore_iterator_close(reindex);
2296 #endif
2297 return -1;
2298 };
2299 };
2300
2301 /* free neighbour */
2302 RDFSTORE_FREE( neighbour->subject->value.resource.identifier );
2303 RDFSTORE_FREE( neighbour->subject );
2304 RDFSTORE_FREE( neighbour->predicate->value.resource.identifier );
2305 RDFSTORE_FREE( neighbour->predicate );
2306 if ( neighbour->object->type == 1 ) {
2307 if ( neighbour->object->value.literal.dataType != NULL )
2308 RDFSTORE_FREE( neighbour->object->value.literal.dataType );
2309 RDFSTORE_FREE( neighbour->object->value.literal.string );
2310 } else {
2311 RDFSTORE_FREE( neighbour->object->value.resource.identifier );
2312 };
2313 RDFSTORE_FREE( neighbour->object );
2314 if ( neighbour->context != NULL ) {
2315 RDFSTORE_FREE( neighbour->context->value.resource.identifier );
2316 RDFSTORE_FREE( neighbour->context );
2317 };
2318 if ( neighbour->node != NULL ) {
2319 RDFSTORE_FREE( neighbour->node->value.resource.identifier );
2320 RDFSTORE_FREE( neighbour->node );
2321 };
2322 RDFSTORE_FREE( neighbour );
2323 };
2324 #endif
2325
2326 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 1, sizeof(me->bits_decode));
2327
2328 #ifdef RDFSTORE_CONNECTIONS
2329 /* COPY subjects(SUBJECT) to s_connections(SUBJECT) */
2330 bcopy(me->bits_decode, s_connections, outsize); /* slow? */
2331 s_outsize = outsize;
2332
2333 /* COPY subjects(SUBJECT) to p_connections(PREDICATE) */
2334 bcopy(me->bits_decode, p_connections, outsize); /* slow? */
2335 p_outsize = outsize;
2336
2337 /* COPY subjects(SUBJECT) to o_connections(OBJECT) */
2338 bcopy(me->bits_decode, o_connections, outsize); /* slow? */
2339 o_outsize = outsize;
2340 #endif
2341
2342 me->func_encode(outsize, me->bits_decode, &outsize, me->bits_encode);
2343 if (outsize) {
2344
2345 /* regenerate it due to the re-indexing above which uses key already */
2346 packInt(statement->subject->hashcode, outbuf);
2347 key.data = outbuf;
2348 key.size = sizeof(int);
2349
2350 data.data = me->bits_encode;
2351 data.size = outsize;
2352 err = rdfstore_flat_store_store(me->subjects, key, data);
2353 if (err == 0) {
2354 #ifdef RDFSTORE_DEBUG_COMPRESSION
2355 fprintf(stderr,"Stored %d bytes for '%s' in subjects table for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
2356 #endif
2357 } else {
2358 if (err != FLAT_STORE_E_KEYEXIST) {
2359 perror("rdfstore_insert");
2360 fprintf(stderr,"Could not store '%d' bytes for subject in subjects table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->subjects));
2361 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2362 rdfstore_iterator_close(reindex);
2363 #endif
2364 return -1;
2365 };
2366 };
2367
2368 #ifdef RDFSTORE_DEBUG
2369 {
2370 int i=0;
2371 if ((rdfstore_flat_store_fetch(me->subjects, key, &data)) == 0) {
2372 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
2373 RDFSTORE_FREE(data.data);
2374 };
2375 printf("ADDED st_num=%d bitno=%d subjects for S '%s' -->'", st_id, st_id, statement->subject->value.resource.identifier);
2376 for(i=0;i<8*outsize;i++) {
2377 printf("Rec %d %c\n", i, (me->bits_decode[i>>3] & (1<<(i&7))) ? '1':'0');
2378 };
2379 printf("'\n");
2380 }
2381 #endif
2382
2383 };
2384
2385 MX;
2386 /* predicates */
2387 packInt(statement->predicate->hashcode, outbuf);
2388 key.data = outbuf;
2389 key.size = sizeof(int);
2390 MX;
2391
2392 /*
2393 * bzero(me->bits_encode,sizeof(me->bits_encode));
2394 * bzero(me->bits_decode,sizeof(me->bits_decode));
2395 */
2396 err = rdfstore_flat_store_fetch(me->predicates, key, &data);
2397 MX;
2398 if (err != 0) {
2399 if (err != FLAT_STORE_E_NOTFOUND) {
2400 perror("rdfstore_insert");
2401 fprintf(stderr,"Could not fetch key '%s' for predicate in predicates table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->predicates));
2402 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2403 rdfstore_iterator_close(reindex);
2404 #endif
2405 return -1;
2406 } else {
2407 outsize = 0;
2408 };
2409 MX;
2410 } else {
2411 MX;
2412 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
2413 MX;
2414 RDFSTORE_FREE(data.data);
2415 };
2416
2417 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2418 /* 2.2) reindex st_id for connections to predicates(PREDICATE) node */
2419
2420 /* copy the predicates(PREDICATE) bits through the reindex iterator array */
2421 memcpy(reindex->ids, me->bits_decode, outsize);
2422 reindex->ids_size = outsize;
2423 /* set the size - inefficient!! */
2424 pos = 0;
2425 reindex->size = 0;
2426 /* count the ones (inefficient still) */
2427 while ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < 8 * outsize) {
2428 reindex->size++;
2429 pos++;
2430 };
2431
2432 /* scan the obtained iterator */
2433 while ( ( neighbour = rdfstore_iterator_each ( reindex ) ) != NULL ) {
2434
2435 #ifdef RDFSTORE_DEBUG_CONNECTIONS
2436 printf("(insert)REINDEXING subject '%s' for connections to predicates('%s') node in st_id=%d\n",neighbour->subject->value.resource.identifier,statement->predicate->value.resource.identifier,st_id);
2437 #endif
2438 neighbour->subject->hashcode = rdfstore_digest_get_node_hashCode(neighbour->subject, 0);
2439
2440 /* fetch s_connections(neighbour->subject) */
2441 packInt(neighbour->subject->hashcode, outbuf); /* wrong */
2442 key.data = outbuf;
2443 key.size = sizeof(int);
2444
2445 err = rdfstore_flat_store_fetch(me->s_connections, key, &data);
2446 if (err != 0) {
2447 if (err != FLAT_STORE_E_NOTFOUND) {
2448 perror("rdfstore_insert");
2449 fprintf(stderr,"Could not fetch key '%s' for subject in s_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
2450 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2451 rdfstore_iterator_close(reindex);
2452 #endif
2453 return -1;
2454 } else {
2455 outsize_reindex = 0;
2456 };
2457 } else {
2458 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
2459 RDFSTORE_FREE(data.data);
2460 };
2461
2462 /* set the corresponding bit of this statement */
2463 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 1, sizeof(reindex_decode));
2464
2465 /* store it back */
2466 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
2467
2468 data.data = reindex_encode;
2469 data.size = outsize_reindex;
2470 err = rdfstore_flat_store_store(me->s_connections, key, data);
2471 if (err != 0) {
2472 if (err != FLAT_STORE_E_KEYEXIST) {
2473 perror("rdfstore_insert");
2474 fprintf(stderr,"Could not store '%d' bytes for subject in s_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
2475 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2476 rdfstore_iterator_close(reindex);
2477 #endif
2478 return -1;
2479 };
2480 };
2481
2482 #ifdef RDFSTORE_DEBUG_CONNECTIONS
2483 printf("(insert)REINDEXING object '%s' for connections to predicates('%s') node in st_id=%d\n",(neighbour->object->type==1) ? neighbour->object->value.literal.string : neighbour->object->value.resource.identifier,statement->predicate->value.resource.identifier,st_id);
2484 #endif
2485 neighbour->object->hashcode = rdfstore_digest_get_node_hashCode(neighbour->object, 0);
2486
2487 /* fetch o_connections(neighbour->object) */
2488 packInt(neighbour->object->hashcode, outbuf); /* wrong */
2489 key.data = outbuf;
2490 key.size = sizeof(int);
2491
2492 err = rdfstore_flat_store_fetch(me->o_connections, key, &data);
2493 if (err != 0) {
2494 if (err != FLAT_STORE_E_NOTFOUND) {
2495 perror("rdfstore_insert");
2496 fprintf(stderr,"Could not fetch key '%s' for object in o_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
2497 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2498 rdfstore_iterator_close(reindex);
2499 #endif
2500 return -1;
2501 } else {
2502 outsize_reindex = 0;
2503 };
2504 } else {
2505 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
2506 RDFSTORE_FREE(data.data);
2507 };
2508
2509 /* set the corresponding bit of this statement */
2510 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 1, sizeof(reindex_decode));
2511
2512 /* store it back */
2513 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
2514
2515 data.data = reindex_encode;
2516 data.size = outsize_reindex;
2517 err = rdfstore_flat_store_store(me->o_connections, key, data);
2518 if (err != 0) {
2519 if (err != FLAT_STORE_E_KEYEXIST) {
2520 perror("rdfstore_insert");
2521 fprintf(stderr,"Could not store '%d' bytes for object in o_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
2522 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2523 rdfstore_iterator_close(reindex);
2524 #endif
2525 return -1;
2526 };
2527 };
2528
2529 /* free neighbour */
2530 RDFSTORE_FREE( neighbour->subject->value.resource.identifier );
2531 RDFSTORE_FREE( neighbour->subject );
2532 RDFSTORE_FREE( neighbour->predicate->value.resource.identifier );
2533 RDFSTORE_FREE( neighbour->predicate );
2534 if ( neighbour->object->type == 1 ) {
2535 if ( neighbour->object->value.literal.dataType != NULL )
2536 RDFSTORE_FREE( neighbour->object->value.literal.dataType );
2537 RDFSTORE_FREE( neighbour->object->value.literal.string );
2538 } else {
2539 RDFSTORE_FREE( neighbour->object->value.resource.identifier );
2540 };
2541 RDFSTORE_FREE( neighbour->object );
2542 if ( neighbour->context != NULL ) {
2543 RDFSTORE_FREE( neighbour->context->value.resource.identifier );
2544 RDFSTORE_FREE( neighbour->context );
2545 };
2546 if ( neighbour->node != NULL ) {
2547 RDFSTORE_FREE( neighbour->node->value.resource.identifier );
2548 RDFSTORE_FREE( neighbour->node );
2549 };
2550 RDFSTORE_FREE( neighbour );
2551 };
2552 #endif
2553
2554 MX;
2555 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 1, sizeof(me->bits_decode));
2556 MX;
2557
2558 #ifdef RDFSTORE_CONNECTIONS
2559 /* OR predicates(PREDICATE) to s_connections(SUBJECT) */
2560 s_outsize = rdfstore_bits_or(outsize, me->bits_decode, s_outsize, s_connections, me->bits_encode); /* use me->bits_encode for easyness
2561 no problem due is rest with encode
2562 operation below here */
2563 bcopy(me->bits_encode, s_connections, s_outsize); /* slow? */
2564
2565
2566 /* OR predicates(PREDICATE) to p_connections(PREDICATE) */
2567 p_outsize = rdfstore_bits_or(outsize, me->bits_decode, p_outsize, p_connections, me->bits_encode);
2568 bcopy(me->bits_encode, p_connections, p_outsize); /* slow? */
2569
2570 /* OR predicates(PREDICATE) to o_connections(OBJECT) */
2571 o_outsize = rdfstore_bits_or(outsize, me->bits_decode, o_outsize, o_connections, me->bits_encode);
2572 bcopy(me->bits_encode, o_connections, o_outsize); /* slow? */
2573 #endif
2574
2575 me->func_encode(outsize, me->bits_decode, &outsize, me->bits_encode);
2576 if (outsize) {
2577
2578 /* regenerate it due to the re-indexing above which uses key already */
2579 packInt(statement->predicate->hashcode, outbuf);
2580 key.data = outbuf;
2581 key.size = sizeof(int);
2582
2583 data.data = me->bits_encode;
2584 data.size = outsize;
2585 err = rdfstore_flat_store_store(me->predicates, key, data);
2586 if (err == 0) {
2587 #ifdef RDFSTORE_DEBUG_COMPRESSION
2588 fprintf(stderr,"Stored %d bytes for '%s' in predicates table for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
2589 #endif
2590 } else {
2591 if (err != FLAT_STORE_E_KEYEXIST) {
2592 perror("rdfstore_insert");
2593 fprintf(stderr,"Could not store '%d' bytes for predicate in predicates table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->predicates));
2594 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2595 rdfstore_iterator_close(reindex);
2596 #endif
2597 return -1;
2598 };
2599 };
2600
2601 #ifdef RDFSTORE_DEBUG
2602 {
2603 int i=0;
2604 if ((rdfstore_flat_store_fetch(me->predicates, key, &data)) == 0) {
2605 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
2606 RDFSTORE_FREE(data.data);
2607 };
2608 printf("ADDED st_num=%d bitno=%d predicates for P '%s' -->'", st_id, st_id, statement->predicate->value.resource.identifier);
2609 for(i=0;i<8*outsize;i++) {
2610 printf("Rec %d %c\n", i, (me->bits_decode[i>>3] & (1<<(i&7))) ? '1':'0');
2611 };
2612 printf("'\n");
2613 }
2614 #endif
2615
2616 };
2617
2618 /* objects */
2619 packInt(statement->object->hashcode, outbuf);
2620 key.data = outbuf;
2621 key.size = sizeof(int);
2622
2623 /*
2624 * bzero(me->bits_encode,sizeof(me->bits_encode));
2625 * bzero(me->bits_decode,sizeof(me->bits_decode));
2626 */
2627
2628 err = rdfstore_flat_store_fetch(me->objects, key, &data);
2629 if (err != 0) {
2630 if (err != FLAT_STORE_E_NOTFOUND) {
2631 perror("rdfstore_insert");
2632 fprintf(stderr,"Could not fetch key '%s' for object in objects table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->objects));
2633 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2634 rdfstore_iterator_close(reindex);
2635 #endif
2636 return -1;
2637 } else {
2638 outsize = 0;
2639 };
2640 } else {
2641 me->func_decode(data.size, data.data, &outsize, me->bits_decode); /* perhaps the
2642 * compression for
2643 * single bits could be
2644 * different */
2645 RDFSTORE_FREE(data.data);
2646 };
2647
2648 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2649 /* 3.3) reindex st_id for connections to objects(OBJECT) node */
2650
2651 /* copy the objects(OBJECT) bits through the reindex iterator array */
2652 memcpy(reindex->ids, me->bits_decode, outsize);
2653 reindex->ids_size = outsize;
2654 /* set the size - inefficient!! */
2655 pos = 0;
2656 reindex->size = 0;
2657 /* count the ones (inefficient still) */
2658 while ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < 8 * outsize) {
2659 reindex->size++;
2660 pos++;
2661 };
2662
2663 /* scan the obtained iterator */
2664 while ( ( neighbour = rdfstore_iterator_each ( reindex ) ) != NULL ) {
2665
2666 #ifdef RDFSTORE_DEBUG_CONNECTIONS
2667 printf("(insert)REINDEXING subject '%s' for connections to objects('%s') node in st_id=%d\n",neighbour->subject->value.resource.identifier,(statement->object->type==1) ? statement->object->value.literal.string : statement->object->value.resource.identifier,st_id);
2668 #endif
2669 neighbour->subject->hashcode = rdfstore_digest_get_node_hashCode(neighbour->subject, 0);
2670
2671 /* fetch s_connections(neighbour->subject) */
2672 packInt(neighbour->subject->hashcode, outbuf); /* wrong */
2673 key.data = outbuf;
2674 key.size = sizeof(int);
2675
2676 err = rdfstore_flat_store_fetch(me->s_connections, key, &data);
2677 if (err != 0) {
2678 if (err != FLAT_STORE_E_NOTFOUND) {
2679 perror("rdfstore_insert");
2680 fprintf(stderr,"Could not fetch key '%s' for subject in s_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
2681 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2682 rdfstore_iterator_close(reindex);
2683 #endif
2684 return -1;
2685 } else {
2686 outsize_reindex = 0;
2687 };
2688 } else {
2689 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
2690 RDFSTORE_FREE(data.data);
2691 };
2692
2693 /* set the corresponding bit of this statement */
2694 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 1, sizeof(reindex_decode));
2695
2696 /* store it back */
2697 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
2698
2699 data.data = reindex_encode;
2700 data.size = outsize_reindex;
2701 err = rdfstore_flat_store_store(me->s_connections, key, data);
2702 if (err != 0) {
2703 if (err != FLAT_STORE_E_KEYEXIST) {
2704 perror("rdfstore_insert");
2705 fprintf(stderr,"Could not store '%d' bytes for subject in s_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
2706 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2707 rdfstore_iterator_close(reindex);
2708 #endif
2709 return -1;
2710 };
2711 };
2712
2713 #ifdef RDFSTORE_DEBUG_CONNECTIONS
2714 printf("(insert)REINDEXING predicate '%s' for connections to objects('%s') node in st_id=%d\n",neighbour->predicate->value.resource.identifier,(statement->object->type==1) ? statement->object->value.literal.string : statement->object->value.resource.identifier,st_id);
2715 #endif
2716 neighbour->predicate->hashcode = rdfstore_digest_get_node_hashCode(neighbour->predicate, 0);
2717
2718 /* fetch p_connections(neighbour->predicate) */
2719 packInt(neighbour->predicate->hashcode, outbuf); /* wrong */
2720 key.data = outbuf;
2721 key.size = sizeof(int);
2722
2723 err = rdfstore_flat_store_fetch(me->p_connections, key, &data);
2724 if (err != 0) {
2725 if (err != FLAT_STORE_E_NOTFOUND) {
2726 perror("rdfstore_insert");
2727 fprintf(stderr,"Could not fetch key '%s' for predicate in p_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
2728 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2729 rdfstore_iterator_close(reindex);
2730 #endif
2731 return -1;
2732 } else {
2733 outsize_reindex = 0;
2734 };
2735 } else {
2736 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
2737 RDFSTORE_FREE(data.data);
2738 };
2739
2740 /* set the corresponding bit of this statement */
2741 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 1, sizeof(reindex_decode));
2742
2743 /* store it back */
2744 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
2745
2746 data.data = reindex_encode;
2747 data.size = outsize_reindex;
2748 err = rdfstore_flat_store_store(me->p_connections, key, data);
2749 if (err != 0) {
2750 if (err != FLAT_STORE_E_KEYEXIST) {
2751 perror("rdfstore_insert");
2752 fprintf(stderr,"Could not store '%d' bytes for predicate in p_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
2753 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2754 rdfstore_iterator_close(reindex);
2755 #endif
2756 return -1;
2757 };
2758 };
2759
2760 /* free neighbour */
2761 RDFSTORE_FREE( neighbour->subject->value.resource.identifier );
2762 RDFSTORE_FREE( neighbour->subject );
2763 RDFSTORE_FREE( neighbour->predicate->value.resource.identifier );
2764 RDFSTORE_FREE( neighbour->predicate );
2765 if ( neighbour->object->type == 1 ) {
2766 if ( neighbour->object->value.literal.dataType != NULL )
2767 RDFSTORE_FREE( neighbour->object->value.literal.dataType );
2768 RDFSTORE_FREE( neighbour->object->value.literal.string );
2769 } else {
2770 RDFSTORE_FREE( neighbour->object->value.resource.identifier );
2771 };
2772 RDFSTORE_FREE( neighbour->object );
2773 if ( neighbour->context != NULL ) {
2774 RDFSTORE_FREE( neighbour->context->value.resource.identifier );
2775 RDFSTORE_FREE( neighbour->context );
2776 };
2777 if ( neighbour->node != NULL ) {
2778 RDFSTORE_FREE( neighbour->node->value.resource.identifier );
2779 RDFSTORE_FREE( neighbour->node );
2780 };
2781 RDFSTORE_FREE( neighbour );
2782 };
2783 #endif
2784
2785 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 1, sizeof(me->bits_decode));
2786
2787 #ifdef RDFSTORE_CONNECTIONS
2788 /* OR objects(OBJECT) to s_connections(SUBJECT) */
2789 s_outsize = rdfstore_bits_or(outsize, me->bits_decode, s_outsize, s_connections, me->bits_encode);
2790 bcopy(me->bits_encode, s_connections, s_outsize); /* slow? */
2791
2792 /* OR objects(OBJECT) to p_connections(PREDICATE) */
2793 p_outsize = rdfstore_bits_or(outsize, me->bits_decode, p_outsize, p_connections, me->bits_encode);
2794 bcopy(me->bits_encode, p_connections, p_outsize); /* slow? */
2795
2796 /* OR objects(OBJECT) to o_connections(OBJECT) */
2797 o_outsize = rdfstore_bits_or(outsize, me->bits_decode, o_outsize, o_connections, me->bits_encode);
2798 bcopy(me->bits_encode, o_connections, o_outsize); /* slow? */
2799 #endif
2800
2801 me->func_encode(outsize, me->bits_decode, &outsize, me->bits_encode);
2802 if (outsize) {
2803
2804 /* regenerate it due to the re-indexing above which uses key already */
2805 packInt(statement->object->hashcode, outbuf);
2806 key.data = outbuf;
2807 key.size = sizeof(int);
2808
2809 data.data = me->bits_encode;
2810 data.size = outsize;
2811 err = rdfstore_flat_store_store(me->objects, key, data);
2812 if (err == 0) {
2813 #ifdef RDFSTORE_DEBUG_COMPRESSION
2814 fprintf(stderr,"Stored %d bytes for '%s' in objects table for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
2815 #endif
2816 } else {
2817 if (err != FLAT_STORE_E_KEYEXIST) {
2818 perror("rdfstore_insert");
2819 fprintf(stderr,"Could not store '%d' bytes for object in objects table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->objects));
2820 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2821 rdfstore_iterator_close(reindex);
2822 #endif
2823 return -1;
2824 };
2825 };
2826
2827 #ifdef RDFSTORE_DEBUG
2828 {
2829 int i=0;
2830 if ((rdfstore_flat_store_fetch(me->objects, key, &data)) == 0) {
2831 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
2832 RDFSTORE_FREE(data.data);
2833 };
2834 printf("ADDED st_num=%d bitno=%d objects for O '%s' -->'", st_id, st_id, (statement->object->type != 1) ? statement->object->value.resource.identifier : statement->object->value.literal.string);
2835 for(i=0;i<8*outsize;i++) {
2836 printf("Rec %d %c\n", i, (me->bits_decode[i>>3] & (1<<(i&7))) ? '1':'0');
2837 };
2838 printf("'\n");
2839 }
2840 #endif
2841
2842 };
2843
2844 #ifdef RDFSTORE_CONNECTIONS
2845 /* fill up all the rest of s_connections, p_connections and o_connections i.e. carry out remaining permutations of each component */
2846
2847 /* fetch subjects(PREDICATE) i.e. statements which has PREDICATE as subject */
2848 packInt(statement->predicate->hashcode, outbuf);
2849 key.data = outbuf;
2850 key.size = sizeof(int);
2851
2852 err = rdfstore_flat_store_fetch(me->subjects, key, &data);
2853 if (err != 0) {
2854 if (err != FLAT_STORE_E_NOTFOUND) {
2855 perror("rdfstore_insert");
2856 fprintf(stderr,"Could not fetch key '%s' for predicate in subjects table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->subjects));
2857 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2858 rdfstore_iterator_close(reindex);
2859 #endif
2860 return -1;
2861 } else {
2862 outsize = 0;
2863 };
2864 } else {
2865 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
2866 RDFSTORE_FREE(data.data);
2867 };
2868
2869 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2870 /*
2871 We need to re-index quite a lot for each new statement component now - hope caching will
2872 help here!! i.e. the swiss army nife problem (see SWAD-E paper and preso)
2873
2874 2.1) add this new statement (st_id) to p_connections(neighbour->predicate) and o_connections(neighbour->object)
2875 tables of each other statement (neighbour) connected to this one via subjects(PREDICATE) node
2876 2.2) add this new statement (st_id) to s_connections(neighbour->subject) and o_connections(neighbour->object)
2877 tables of each other statement (neighbour) connected to this one via predicates(PREDICATE) node
2878 2.3) add this new statement (st_id) to s_connections(neighbour->subject) and p_connections(neighbour->predicate)
2879 tables of each other statement (neighbour) connected to this one via objects(PREDICATE) node
2880 */
2881
2882 /* 2.1) reindex st_id for connections to subjects(PREDICATE) node */
2883
2884 /* copy the subjects(PREDICATE) bits through the reindex iterator array */
2885 memcpy(reindex->ids, me->bits_decode, outsize);
2886 reindex->ids_size = outsize;
2887 /* set the size - inefficient!! */
2888 pos = 0;
2889 reindex->size = 0;
2890 /* count the ones (inefficient still) */
2891 while ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < 8 * outsize) {
2892 reindex->size++;
2893 pos++;
2894 };
2895
2896 /* scan the obtained iterator */
2897 while ( ( neighbour = rdfstore_iterator_each ( reindex ) ) != NULL ) {
2898
2899 #ifdef RDFSTORE_DEBUG_CONNECTIONS
2900 printf("(insert)REINDEXING predicate '%s' for connections to subjects('%s') node in st_id=%d\n",neighbour->predicate->value.resource.identifier,statement->predicate->value.resource.identifier,st_id);
2901 #endif
2902 neighbour->predicate->hashcode = rdfstore_digest_get_node_hashCode(neighbour->predicate, 0);
2903
2904 /* fetch p_connections(neighbour->predicate) */
2905 packInt(neighbour->predicate->hashcode, outbuf); /* wrong */
2906 key.data = outbuf;
2907 key.size = sizeof(int);
2908
2909 err = rdfstore_flat_store_fetch(me->p_connections, key, &data);
2910 if (err != 0) {
2911 if (err != FLAT_STORE_E_NOTFOUND) {
2912 perror("rdfstore_insert");
2913 fprintf(stderr,"Could not fetch key '%s' for predicate in p_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
2914 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2915 rdfstore_iterator_close(reindex);
2916 #endif
2917 return -1;
2918 } else {
2919 outsize_reindex = 0;
2920 };
2921 } else {
2922 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
2923 RDFSTORE_FREE(data.data);
2924 };
2925
2926 /* set the corresponding bit of this statement */
2927 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 1, sizeof(reindex_decode));
2928
2929 /* store it back */
2930 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
2931
2932 data.data = reindex_encode;
2933 data.size = outsize_reindex;
2934 err = rdfstore_flat_store_store(me->p_connections, key, data);
2935 if (err != 0) {
2936 if (err != FLAT_STORE_E_KEYEXIST) {
2937 perror("rdfstore_insert");
2938 fprintf(stderr,"Could not store '%d' bytes for predicate in p_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
2939 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2940 rdfstore_iterator_close(reindex);
2941 #endif
2942 return -1;
2943 };
2944 };
2945
2946 #ifdef RDFSTORE_DEBUG_CONNECTIONS
2947 printf("(insert)REINDEXING object '%s' for connections to subjects('%s') node in st_id=%d\n",(neighbour->object->type==1) ? neighbour->object->value.literal.string : neighbour->object->value.resource.identifier,statement->predicate->value.resource.identifier,st_id);
2948 #endif
2949 neighbour->object->hashcode = rdfstore_digest_get_node_hashCode(neighbour->object, 0);
2950
2951 /* fetch o_connections(neighbour->object) */
2952 packInt(neighbour->object->hashcode, outbuf); /* wrong */
2953 key.data = outbuf;
2954 key.size = sizeof(int);
2955
2956 err = rdfstore_flat_store_fetch(me->o_connections, key, &data);
2957 if (err != 0) {
2958 if (err != FLAT_STORE_E_NOTFOUND) {
2959 perror("rdfstore_insert");
2960 fprintf(stderr,"Could not fetch key '%s' for object in o_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
2961 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2962 rdfstore_iterator_close(reindex);
2963 #endif
2964 return -1;
2965 } else {
2966 outsize_reindex = 0;
2967 };
2968 } else {
2969 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
2970 RDFSTORE_FREE(data.data);
2971 };
2972
2973 /* set the corresponding bit of this statement */
2974 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 1, sizeof(reindex_decode));
2975
2976 /* store it back */
2977 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
2978
2979 data.data = reindex_encode;
2980 data.size = outsize_reindex;
2981 err = rdfstore_flat_store_store(me->o_connections, key, data);
2982 if (err != 0) {
2983 if (err != FLAT_STORE_E_KEYEXIST) {
2984 perror("rdfstore_insert");
2985 fprintf(stderr,"Could not store '%d' bytes for object in o_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
2986 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
2987 rdfstore_iterator_close(reindex);
2988 #endif
2989 return -1;
2990 };
2991 };
2992
2993 /* free neighbour */
2994 RDFSTORE_FREE( neighbour->subject->value.resource.identifier );
2995 RDFSTORE_FREE( neighbour->subject );
2996 RDFSTORE_FREE( neighbour->predicate->value.resource.identifier );
2997 RDFSTORE_FREE( neighbour->predicate );
2998 if ( neighbour->object->type == 1 ) {
2999 if ( neighbour->object->value.literal.dataType != NULL )
3000 RDFSTORE_FREE( neighbour->object->value.literal.dataType );
3001 RDFSTORE_FREE( neighbour->object->value.literal.string );
3002 } else {
3003 RDFSTORE_FREE( neighbour->object->value.resource.identifier );
3004 };
3005 RDFSTORE_FREE( neighbour->object );
3006 if ( neighbour->context != NULL ) {
3007 RDFSTORE_FREE( neighbour->context->value.resource.identifier );
3008 RDFSTORE_FREE( neighbour->context );
3009 };
3010 if ( neighbour->node != NULL ) {
3011 RDFSTORE_FREE( neighbour->node->value.resource.identifier );
3012 RDFSTORE_FREE( neighbour->node );
3013 };
3014 RDFSTORE_FREE( neighbour );
3015 };
3016 #endif
3017
3018 /* OR subjects(PREDICATE) to s_connections(SUBJECT) */
3019 s_outsize = rdfstore_bits_or(outsize, me->bits_decode, s_outsize, s_connections, me->bits_encode);
3020 bcopy(me->bits_encode, s_connections, s_outsize); /* slow? */
3021
3022 /* OR subjects(PREDICATE) to p_connections(PREDICATE) */
3023 p_outsize = rdfstore_bits_or(outsize, me->bits_decode, p_outsize, p_connections, me->bits_encode);
3024 bcopy(me->bits_encode, p_connections, p_outsize); /* slow? */
3025
3026 /* OR subjects(PREDICATE) to o_connections(OBJECT) */
3027 o_outsize = rdfstore_bits_or(outsize, me->bits_decode, o_outsize, o_connections, me->bits_encode);
3028 bcopy(me->bits_encode, o_connections, o_outsize); /* slow? */
3029
3030 /* fetch subjects(OBJECT) */
3031 packInt(statement->object->hashcode, outbuf);
3032 key.data = outbuf;
3033 key.size = sizeof(int);
3034
3035 err = rdfstore_flat_store_fetch(me->subjects, key, &data);
3036 if (err != 0) {
3037 if (err != FLAT_STORE_E_NOTFOUND) {
3038 perror("rdfstore_insert");
3039 fprintf(stderr,"Could not fetch key '%s' for object in subjects table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->subjects));
3040 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3041 rdfstore_iterator_close(reindex);
3042 #endif
3043 return -1;
3044 } else {
3045 outsize = 0;
3046 };
3047 } else {
3048 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
3049 RDFSTORE_FREE(data.data);
3050 };
3051
3052 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3053 /*
3054 We need to re-index quite a lot for each new statement component now - hope caching will
3055 help here!! i.e. the swiss army nife problem (see SWAD-E paper and preso)
3056
3057 3.1) add this new statement (st_id) to p_connections(neighbour->predicate) and o_connections(neighbour->object)
3058 tables of each other statement (neighbour) connected to this one via subjects(OBJECT) node
3059 3.2) add this new statement (st_id) to s_connections(neighbour->subject) and o_connections(neighbour->object)
3060 tables of each other statement (neighbour) connected to this one via predicates(OBJECT) node
3061 3.3) add this new statement (st_id) to s_connections(neighbour->subject) and p_connections(neighbour->predicate)
3062 tables of each other statement (neighbour) connected to this one via objects(OBJECT) node
3063 */
3064
3065 /* 3.1) reindex st_id for connections to subjects(OBJECT) node */
3066
3067 /* copy the subjects(OBJECT) bits through the reindex iterator array */
3068 memcpy(reindex->ids, me->bits_decode, outsize);
3069 reindex->ids_size = outsize;
3070 /* set the size - inefficient!! */
3071 pos = 0;
3072 reindex->size = 0;
3073 /* count the ones (inefficient still) */
3074 while ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < 8 * outsize) {
3075 reindex->size++;
3076 pos++;
3077 };
3078
3079 /* scan the obtained iterator */
3080 while ( ( neighbour = rdfstore_iterator_each ( reindex ) ) != NULL ) {
3081
3082 #ifdef RDFSTORE_DEBUG_CONNECTIONS
3083 printf("(insert)REINDEXING predicate '%s' for connections to subjects('%s') node in st_id=%d\n",neighbour->predicate->value.resource.identifier,(statement->object->type==1) ? statement->object->value.literal.string : statement->object->value.resource.identifier,st_id);
3084 #endif
3085 neighbour->predicate->hashcode = rdfstore_digest_get_node_hashCode(neighbour->predicate, 0);
3086
3087 /* fetch p_connections(neighbour->predicate) */
3088 packInt(neighbour->predicate->hashcode, outbuf); /* wrong */
3089 key.data = outbuf;
3090 key.size = sizeof(int);
3091
3092 err = rdfstore_flat_store_fetch(me->p_connections, key, &data);
3093 if (err != 0) {
3094 if (err != FLAT_STORE_E_NOTFOUND) {
3095 perror("rdfstore_insert");
3096 fprintf(stderr,"Could not fetch key '%s' for predicate in p_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
3097 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3098 rdfstore_iterator_close(reindex);
3099 #endif
3100 return -1;
3101 } else {
3102 outsize_reindex = 0;
3103 };
3104 } else {
3105 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
3106 RDFSTORE_FREE(data.data);
3107 };
3108
3109 /* set the corresponding bit of this statement */
3110 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 1, sizeof(reindex_decode));
3111
3112 /* store it back */
3113 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
3114
3115 data.data = reindex_encode;
3116 data.size = outsize_reindex;
3117 err = rdfstore_flat_store_store(me->p_connections, key, data);
3118 if (err != 0) {
3119 if (err != FLAT_STORE_E_KEYEXIST) {
3120 perror("rdfstore_insert");
3121 fprintf(stderr,"Could not store '%d' bytes for predicate in p_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
3122 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3123 rdfstore_iterator_close(reindex);
3124 #endif
3125 return -1;
3126 };
3127 };
3128
3129 #ifdef RDFSTORE_DEBUG_CONNECTIONS
3130 printf("(insert)REINDEXING object '%s' for connections to subjects('%s') node in st_id=%d\n",(neighbour->object->type==1) ? neighbour->object->value.literal.string : neighbour->object->value.resource.identifier,(statement->object->type==1) ? statement->object->value.literal.string : statement->object->value.resource.identifier,st_id);
3131 #endif
3132 neighbour->object->hashcode = rdfstore_digest_get_node_hashCode(neighbour->object, 0);
3133
3134 /* fetch o_connections(neighbour->object) */
3135 packInt(neighbour->object->hashcode, outbuf); /* wrong */
3136 key.data = outbuf;
3137 key.size = sizeof(int);
3138
3139 err = rdfstore_flat_store_fetch(me->o_connections, key, &data);
3140 if (err != 0) {
3141 if (err != FLAT_STORE_E_NOTFOUND) {
3142 perror("rdfstore_insert");
3143 fprintf(stderr,"Could not fetch key '%s' for object in o_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
3144 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3145 rdfstore_iterator_close(reindex);
3146 #endif
3147 return -1;
3148 } else {
3149 outsize_reindex = 0;
3150 };
3151 } else {
3152 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
3153 RDFSTORE_FREE(data.data);
3154 };
3155
3156 /* set the corresponding bit of this statement */
3157 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 1, sizeof(reindex_decode));
3158
3159 /* store it back */
3160 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
3161
3162 data.data = reindex_encode;
3163 data.size = outsize_reindex;
3164 err = rdfstore_flat_store_store(me->o_connections, key, data);
3165 if (err != 0) {
3166 if (err != FLAT_STORE_E_KEYEXIST) {
3167 perror("rdfstore_insert");
3168 fprintf(stderr,"Could not store '%d' bytes for object in o_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
3169 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3170 rdfstore_iterator_close(reindex);
3171 #endif
3172 return -1;
3173 };
3174 };
3175
3176 /* free neighbour */
3177 RDFSTORE_FREE( neighbour->subject->value.resource.identifier );
3178 RDFSTORE_FREE( neighbour->subject );
3179 RDFSTORE_FREE( neighbour->predicate->value.resource.identifier );
3180 RDFSTORE_FREE( neighbour->predicate );
3181 if ( neighbour->object->type == 1 ) {
3182 if ( neighbour->object->value.literal.dataType != NULL )
3183 RDFSTORE_FREE( neighbour->object->value.literal.dataType );
3184 RDFSTORE_FREE( neighbour->object->value.literal.string );
3185 } else {
3186 RDFSTORE_FREE( neighbour->object->value.resource.identifier );
3187 };
3188 RDFSTORE_FREE( neighbour->object );
3189 if ( neighbour->context != NULL ) {
3190 RDFSTORE_FREE( neighbour->context->value.resource.identifier );
3191 RDFSTORE_FREE( neighbour->context );
3192 };
3193 if ( neighbour->node != NULL ) {
3194 RDFSTORE_FREE( neighbour->node->value.resource.identifier );
3195 RDFSTORE_FREE( neighbour->node );
3196 };
3197 RDFSTORE_FREE( neighbour );
3198 };
3199 #endif
3200
3201 /* OR subjects(OBJECT) to s_connections(SUBJECT) */
3202 s_outsize = rdfstore_bits_or(outsize, me->bits_decode, s_outsize, s_connections, me->bits_encode);
3203 bcopy(me->bits_encode, s_connections, s_outsize); /* slow? */
3204
3205 /* OR subjects(OBJECT) to p_connections(PREDICATE) */
3206 p_outsize = rdfstore_bits_or(outsize, me->bits_decode, p_outsize, p_connections, me->bits_encode);
3207 bcopy(me->bits_encode, p_connections, p_outsize); /* slow? */
3208
3209 /* OR subjects(OBJECT) to o_connections(OBJECT) */
3210 o_outsize = rdfstore_bits_or(outsize, me->bits_decode, o_outsize, o_connections, me->bits_encode);
3211 bcopy(me->bits_encode, o_connections, o_outsize); /* slow? */
3212
3213 /* fetch predicates(SUBJECT) */
3214 packInt(statement->subject->hashcode, outbuf);
3215 key.data = outbuf;
3216 key.size = sizeof(int);
3217
3218 err = rdfstore_flat_store_fetch(me->predicates, key, &data);
3219 if (err != 0) {
3220 if (err != FLAT_STORE_E_NOTFOUND) {
3221 perror("rdfstore_insert");
3222 fprintf(stderr,"Could not fetch key '%s' for subject in predicates table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->predicates));
3223 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3224 rdfstore_iterator_close(reindex);
3225 #endif
3226 return -1;
3227 } else {
3228 outsize = 0;
3229 };
3230 } else {
3231 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
3232 RDFSTORE_FREE(data.data);
3233 };
3234
3235 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3236 /* 1.2) reindex st_id for connections to predicates(SUBJECT) node */
3237
3238 /* copy the predicates(SUBJECT) bits through the reindex iterator array */
3239 memcpy(reindex->ids, me->bits_decode, outsize);
3240 reindex->ids_size = outsize;
3241 /* set the size - inefficient!! */
3242 pos = 0;
3243 reindex->size = 0;
3244 /* count the ones (inefficient still) */
3245 while ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < 8 * outsize) {
3246 reindex->size++;
3247 pos++;
3248 };
3249
3250 /* scan the obtained iterator */
3251 while ( ( neighbour = rdfstore_iterator_each ( reindex ) ) != NULL ) {
3252
3253 #ifdef RDFSTORE_DEBUG_CONNECTIONS
3254 printf("(insert)REINDEXING subject '%s' for connections to predicates('%s') node in st_id=%d\n",neighbour->subject->value.resource.identifier,statement->subject->value.resource.identifier,st_id);
3255 #endif
3256 neighbour->subject->hashcode = rdfstore_digest_get_node_hashCode(neighbour->subject, 0);
3257
3258 /* fetch s_connections(neighbour->subject) */
3259 packInt(neighbour->subject->hashcode, outbuf); /* wrong */
3260 key.data = outbuf;
3261 key.size = sizeof(int);
3262
3263 err = rdfstore_flat_store_fetch(me->s_connections, key, &data);
3264 if (err != 0) {
3265 if (err != FLAT_STORE_E_NOTFOUND) {
3266 perror("rdfstore_insert");
3267 fprintf(stderr,"Could not fetch key '%s' for subject in s_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
3268 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3269 rdfstore_iterator_close(reindex);
3270 #endif
3271 return -1;
3272 } else {
3273 outsize_reindex = 0;
3274 };
3275 } else {
3276 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
3277 RDFSTORE_FREE(data.data);
3278 };
3279
3280 /* set the corresponding bit of this statement */
3281 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 1, sizeof(reindex_decode));
3282
3283 /* store it back */
3284 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
3285
3286 data.data = reindex_encode;
3287 data.size = outsize_reindex;
3288 err = rdfstore_flat_store_store(me->s_connections, key, data);
3289 if (err != 0) {
3290 if (err != FLAT_STORE_E_KEYEXIST) {
3291 perror("rdfstore_insert");
3292 fprintf(stderr,"Could not store '%d' bytes for subject in s_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
3293 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3294 rdfstore_iterator_close(reindex);
3295 #endif
3296 return -1;
3297 };
3298 };
3299
3300 #ifdef RDFSTORE_DEBUG_CONNECTIONS
3301 printf("(insert)REINDEXING object '%s' for connections to predicates('%s') node in st_id=%d\n",(neighbour->object->type==1) ? neighbour->object->value.literal.string : neighbour->object->value.resource.identifier,statement->subject->value.resource.identifier,st_id);
3302 #endif
3303 neighbour->object->hashcode = rdfstore_digest_get_node_hashCode(neighbour->object, 0);
3304
3305 /* fetch o_connections(neighbour->object) */
3306 packInt(neighbour->object->hashcode, outbuf); /* wrong */
3307 key.data = outbuf;
3308 key.size = sizeof(int);
3309
3310 err = rdfstore_flat_store_fetch(me->o_connections, key, &data);
3311 if (err != 0) {
3312 if (err != FLAT_STORE_E_NOTFOUND) {
3313 perror("rdfstore_insert");
3314 fprintf(stderr,"Could not fetch key '%s' for object in o_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
3315 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3316 rdfstore_iterator_close(reindex);
3317 #endif
3318 return -1;
3319 } else {
3320 outsize_reindex = 0;
3321 };
3322 } else {
3323 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
3324 RDFSTORE_FREE(data.data);
3325 };
3326
3327 /* set the corresponding bit of this statement */
3328 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 1, sizeof(reindex_decode));
3329
3330 /* store it back */
3331 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
3332
3333 data.data = reindex_encode;
3334 data.size = outsize_reindex;
3335 err = rdfstore_flat_store_store(me->o_connections, key, data);
3336 if (err != 0) {
3337 if (err != FLAT_STORE_E_KEYEXIST) {
3338 perror("rdfstore_insert");
3339 fprintf(stderr,"Could not store '%d' bytes for object in o_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
3340 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3341 rdfstore_iterator_close(reindex);
3342 #endif
3343 return -1;
3344 };
3345 };
3346
3347 /* free neighbour */
3348 RDFSTORE_FREE( neighbour->subject->value.resource.identifier );
3349 RDFSTORE_FREE( neighbour->subject );
3350 RDFSTORE_FREE( neighbour->predicate->value.resource.identifier );
3351 RDFSTORE_FREE( neighbour->predicate );
3352 if ( neighbour->object->type == 1 ) {
3353 if ( neighbour->object->value.literal.dataType != NULL )
3354 RDFSTORE_FREE( neighbour->object->value.literal.dataType );
3355 RDFSTORE_FREE( neighbour->object->value.literal.string );
3356 } else {
3357 RDFSTORE_FREE( neighbour->object->value.resource.identifier );
3358 };
3359 RDFSTORE_FREE( neighbour->object );
3360 if ( neighbour->context != NULL ) {
3361 RDFSTORE_FREE( neighbour->context->value.resource.identifier );
3362 RDFSTORE_FREE( neighbour->context );
3363 };
3364 if ( neighbour->node != NULL ) {
3365 RDFSTORE_FREE( neighbour->node->value.resource.identifier );
3366 RDFSTORE_FREE( neighbour->node );
3367 };
3368 RDFSTORE_FREE( neighbour );
3369 };
3370 #endif
3371
3372 /* OR predicates(SUBJECT) to s_connections(SUBJECT) */
3373 s_outsize = rdfstore_bits_or(outsize, me->bits_decode, s_outsize, s_connections, me->bits_encode);
3374 bcopy(me->bits_encode, s_connections, s_outsize); /* slow? */
3375
3376 /* OR predicates(SUBJECT) to p_connections(PREDICATE) */
3377 p_outsize = rdfstore_bits_or(outsize, me->bits_decode, p_outsize, p_connections, me->bits_encode);
3378 bcopy(me->bits_encode, p_connections, p_outsize); /* slow? */
3379
3380 /* OR predicates(SUBJECT) to o_connections(OBJECT) */
3381 o_outsize = rdfstore_bits_or(outsize, me->bits_decode, o_outsize, o_connections, me->bits_encode);
3382 bcopy(me->bits_encode, o_connections, o_outsize); /* slow? */
3383
3384 /* fetch predicates(OBJECT) */
3385 packInt(statement->object->hashcode, outbuf);
3386 key.data = outbuf;
3387 key.size = sizeof(int);
3388
3389 err = rdfstore_flat_store_fetch(me->predicates, key, &data);
3390 if (err != 0) {
3391 if (err != FLAT_STORE_E_NOTFOUND) {
3392 perror("rdfstore_insert");
3393 fprintf(stderr,"Could not fetch key '%s' for object in predicates table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->predicates));
3394 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3395 rdfstore_iterator_close(reindex);
3396 #endif
3397 return -1;
3398 } else {
3399 outsize = 0;
3400 };
3401 } else {
3402 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
3403 RDFSTORE_FREE(data.data);
3404 };
3405
3406 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3407 /* 3.2) reindex st_id for connections to predicates(OBJECT) node */
3408
3409 /* copy the predicates(OBJECT) bits through the reindex iterator array */
3410 memcpy(reindex->ids, me->bits_decode, outsize);
3411 reindex->ids_size = outsize;
3412 /* set the size - inefficient!! */
3413 pos = 0;
3414 reindex->size = 0;
3415 /* count the ones (inefficient still) */
3416 while ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < 8 * outsize) {
3417 reindex->size++;
3418 pos++;
3419 };
3420
3421 /* scan the obtained iterator */
3422 while ( ( neighbour = rdfstore_iterator_each ( reindex ) ) != NULL ) {
3423
3424 #ifdef RDFSTORE_DEBUG_CONNECTIONS
3425 printf("(insert)REINDEXING subject '%s' for connections to predicates('%s') node in st_id=%d\n",neighbour->subject->value.resource.identifier,(statement->object->type==1) ? statement->object->value.literal.string : statement->object->value.resource.identifier,st_id);
3426 #endif
3427 neighbour->subject->hashcode = rdfstore_digest_get_node_hashCode(neighbour->subject, 0);
3428
3429 /* fetch s_connections(neighbour->subject) */
3430 packInt(neighbour->subject->hashcode, outbuf); /* wrong */
3431 key.data = outbuf;
3432 key.size = sizeof(int);
3433
3434 err = rdfstore_flat_store_fetch(me->s_connections, key, &data);
3435 if (err != 0) {
3436 if (err != FLAT_STORE_E_NOTFOUND) {
3437 perror("rdfstore_insert");
3438 fprintf(stderr,"Could not fetch key '%s' for subject in s_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
3439 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3440 rdfstore_iterator_close(reindex);
3441 #endif
3442 return -1;
3443 } else {
3444 outsize_reindex = 0;
3445 };
3446 } else {
3447 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
3448 RDFSTORE_FREE(data.data);
3449 };
3450
3451 /* set the corresponding bit of this statement */
3452 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 1, sizeof(reindex_decode));
3453
3454 /* store it back */
3455 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
3456
3457 data.data = reindex_encode;
3458 data.size = outsize_reindex;
3459 err = rdfstore_flat_store_store(me->s_connections, key, data);
3460 if (err != 0) {
3461 if (err != FLAT_STORE_E_KEYEXIST) {
3462 perror("rdfstore_insert");
3463 fprintf(stderr,"Could not store '%d' bytes for subject in s_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
3464 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3465 rdfstore_iterator_close(reindex);
3466 #endif
3467 return -1;
3468 };
3469 };
3470
3471 #ifdef RDFSTORE_DEBUG_CONNECTIONS
3472 printf("(insert)REINDEXING object '%s' for connections to predicates('%s') node in st_id=%d\n",(neighbour->object->type==1) ? neighbour->object->value.literal.string : neighbour->object->value.resource.identifier,(statement->object->type==1) ? statement->object->value.literal.string : statement->object->value.resource.identifier,st_id);
3473 #endif
3474 neighbour->object->hashcode = rdfstore_digest_get_node_hashCode(neighbour->object, 0);
3475
3476 /* fetch o_connections(neighbour->object) */
3477 packInt(neighbour->object->hashcode, outbuf); /* wrong */
3478 key.data = outbuf;
3479 key.size = sizeof(int);
3480
3481 err = rdfstore_flat_store_fetch(me->o_connections, key, &data);
3482 if (err != 0) {
3483 if (err != FLAT_STORE_E_NOTFOUND) {
3484 perror("rdfstore_insert");
3485 fprintf(stderr,"Could not fetch key '%s' for object in o_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
3486 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3487 rdfstore_iterator_close(reindex);
3488 #endif
3489 return -1;
3490 } else {
3491 outsize_reindex = 0;
3492 };
3493 } else {
3494 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
3495 RDFSTORE_FREE(data.data);
3496 };
3497
3498 /* set the corresponding bit of this statement */
3499 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 1, sizeof(reindex_decode));
3500
3501 /* store it back */
3502 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
3503
3504 data.data = reindex_encode;
3505 data.size = outsize_reindex;
3506 err = rdfstore_flat_store_store(me->o_connections, key, data);
3507 if (err != 0) {
3508 if (err != FLAT_STORE_E_KEYEXIST) {
3509 perror("rdfstore_insert");
3510 fprintf(stderr,"Could not store '%d' bytes for object in o_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
3511 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3512 rdfstore_iterator_close(reindex);
3513 #endif
3514 return -1;
3515 };
3516 };
3517
3518 /* free neighbour */
3519 RDFSTORE_FREE( neighbour->subject->value.resource.identifier );
3520 RDFSTORE_FREE( neighbour->subject );
3521 RDFSTORE_FREE( neighbour->predicate->value.resource.identifier );
3522 RDFSTORE_FREE( neighbour->predicate );
3523 if ( neighbour->object->type == 1 ) {
3524 if ( neighbour->object->value.literal.dataType != NULL )
3525 RDFSTORE_FREE( neighbour->object->value.literal.dataType );
3526 RDFSTORE_FREE( neighbour->object->value.literal.string );
3527 } else {
3528 RDFSTORE_FREE( neighbour->object->value.resource.identifier );
3529 };
3530 RDFSTORE_FREE( neighbour->object );
3531 if ( neighbour->context != NULL ) {
3532 RDFSTORE_FREE( neighbour->context->value.resource.identifier );
3533 RDFSTORE_FREE( neighbour->context );
3534 };
3535 if ( neighbour->node != NULL ) {
3536 RDFSTORE_FREE( neighbour->node->value.resource.identifier );
3537 RDFSTORE_FREE( neighbour->node );
3538 };
3539 RDFSTORE_FREE( neighbour );
3540 };
3541 #endif
3542
3543 /* OR predicates(OBJECT) to s_connections(SUBJECT) */
3544 s_outsize = rdfstore_bits_or(outsize, me->bits_decode, s_outsize, s_connections, me->bits_encode);
3545 bcopy(me->bits_encode, s_connections, s_outsize); /* slow? */
3546
3547 /* OR predicates(OBJECT) to p_connections(PREDICATE) */
3548 p_outsize = rdfstore_bits_or(outsize, me->bits_decode, p_outsize, p_connections, me->bits_encode);
3549 bcopy(me->bits_encode, p_connections, p_outsize); /* slow? */
3550
3551 /* OR predicates(OBJECT) to o_connections(OBJECT) */
3552 o_outsize = rdfstore_bits_or(outsize, me->bits_decode, o_outsize, o_connections, me->bits_encode);
3553 bcopy(me->bits_encode, o_connections, o_outsize); /* slow? */
3554
3555 /* fetch objects(SUBJECT) */
3556 packInt(statement->subject->hashcode, outbuf);
3557 key.data = outbuf;
3558 key.size = sizeof(int);
3559
3560 err = rdfstore_flat_store_fetch(me->objects, key, &data);
3561 if (err != 0) {
3562 if (err != FLAT_STORE_E_NOTFOUND) {
3563 perror("rdfstore_insert");
3564 fprintf(stderr,"Could not fetch key '%s' for subject in objects table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->objects));
3565 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3566 rdfstore_iterator_close(reindex);
3567 #endif
3568 return -1;
3569 } else {
3570 outsize = 0;
3571 };
3572 } else {
3573 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
3574 RDFSTORE_FREE(data.data);
3575 };
3576
3577 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3578 /* 1.3) reindex st_id for connections to objects(SUBJECT) node */
3579
3580 /* copy the objects(SUBJECT) bits through the reindex iterator array */
3581 memcpy(reindex->ids, me->bits_decode, outsize);
3582 reindex->ids_size = outsize;
3583 /* set the size - inefficient!! */
3584 pos = 0;
3585 reindex->size = 0;
3586 /* count the ones (inefficient still) */
3587 while ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < 8 * outsize) {
3588 reindex->size++;
3589 pos++;
3590 };
3591
3592 /* scan the obtained iterator */
3593 while ( ( neighbour = rdfstore_iterator_each ( reindex ) ) != NULL ) {
3594
3595 #ifdef RDFSTORE_DEBUG_CONNECTIONS
3596 printf("(insert)REINDEXING subject '%s' for connections to objects('%s') node in st_id=%d\n",neighbour->subject->value.resource.identifier,statement->subject->value.resource.identifier,st_id);
3597 #endif
3598 neighbour->subject->hashcode = rdfstore_digest_get_node_hashCode(neighbour->subject, 0);
3599
3600 /* fetch s_connections(neighbour->subject) */
3601 packInt(neighbour->subject->hashcode, outbuf); /* wrong */
3602 key.data = outbuf;
3603 key.size = sizeof(int);
3604
3605 err = rdfstore_flat_store_fetch(me->s_connections, key, &data);
3606 if (err != 0) {
3607 if (err != FLAT_STORE_E_NOTFOUND) {
3608 perror("rdfstore_insert");
3609 fprintf(stderr,"Could not fetch key '%s' for subject in s_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
3610 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3611 rdfstore_iterator_close(reindex);
3612 #endif
3613 return -1;
3614 } else {
3615 outsize_reindex = 0;
3616 };
3617 } else {
3618 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
3619 RDFSTORE_FREE(data.data);
3620 };
3621
3622 /* set the corresponding bit of this statement */
3623 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 1, sizeof(reindex_decode));
3624
3625 /* store it back */
3626 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
3627
3628 data.data = reindex_encode;
3629 data.size = outsize_reindex;
3630 err = rdfstore_flat_store_store(me->s_connections, key, data);
3631 if (err != 0) {
3632 if (err != FLAT_STORE_E_KEYEXIST) {
3633 perror("rdfstore_insert");
3634 fprintf(stderr,"Could not store '%d' bytes for subject in s_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
3635 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3636 rdfstore_iterator_close(reindex);
3637 #endif
3638 return -1;
3639 };
3640 };
3641
3642 #ifdef RDFSTORE_DEBUG_CONNECTIONS
3643 printf("(insert)REINDEXING predicate '%s' for connections to objects('%s') node in st_id=%d\n",neighbour->predicate->value.resource.identifier,statement->subject->value.resource.identifier,st_id);
3644 #endif
3645 neighbour->predicate->hashcode = rdfstore_digest_get_node_hashCode(neighbour->predicate, 0);
3646
3647 /* fetch p_connections(neighbour->predicate) */
3648 packInt(neighbour->predicate->hashcode, outbuf); /* wrong */
3649 key.data = outbuf;
3650 key.size = sizeof(int);
3651
3652 err = rdfstore_flat_store_fetch(me->p_connections, key, &data);
3653 if (err != 0) {
3654 if (err != FLAT_STORE_E_NOTFOUND) {
3655 perror("rdfstore_insert");
3656 fprintf(stderr,"Could not fetch key '%s' for predicate in p_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
3657 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3658 rdfstore_iterator_close(reindex);
3659 #endif
3660 return -1;
3661 } else {
3662 outsize_reindex = 0;
3663 };
3664 } else {
3665 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
3666 RDFSTORE_FREE(data.data);
3667 };
3668
3669 /* set the corresponding bit of this statement */
3670 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 1, sizeof(reindex_decode));
3671
3672 /* store it back */
3673 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
3674
3675 data.data = reindex_encode;
3676 data.size = outsize_reindex;
3677 err = rdfstore_flat_store_store(me->p_connections, key, data);
3678 if (err != 0) {
3679 if (err != FLAT_STORE_E_KEYEXIST) {
3680 perror("rdfstore_insert");
3681 fprintf(stderr,"Could not store '%d' bytes for predicate in p_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
3682 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3683 rdfstore_iterator_close(reindex);
3684 #endif
3685 return -1;
3686 };
3687 };
3688
3689 /* free neighbour */
3690 RDFSTORE_FREE( neighbour->subject->value.resource.identifier );
3691 RDFSTORE_FREE( neighbour->subject );
3692 RDFSTORE_FREE( neighbour->predicate->value.resource.identifier );
3693 RDFSTORE_FREE( neighbour->predicate );
3694 if ( neighbour->object->type == 1 ) {
3695 if ( neighbour->object->value.literal.dataType != NULL )
3696 RDFSTORE_FREE( neighbour->object->value.literal.dataType );
3697 RDFSTORE_FREE( neighbour->object->value.literal.string );
3698 } else {
3699 RDFSTORE_FREE( neighbour->object->value.resource.identifier );
3700 };
3701 RDFSTORE_FREE( neighbour->object );
3702 if ( neighbour->context != NULL ) {
3703 RDFSTORE_FREE( neighbour->context->value.resource.identifier );
3704 RDFSTORE_FREE( neighbour->context );
3705 };
3706 if ( neighbour->node != NULL ) {
3707 RDFSTORE_FREE( neighbour->node->value.resource.identifier );
3708 RDFSTORE_FREE( neighbour->node );
3709 };
3710 RDFSTORE_FREE( neighbour );
3711 };
3712 #endif
3713
3714 /* OR objects(SUBJECT) to s_connections(SUBJECT) */
3715 s_outsize = rdfstore_bits_or(outsize, me->bits_decode, s_outsize, s_connections, me->bits_encode);
3716 bcopy(me->bits_encode, s_connections, s_outsize); /* slow? */
3717
3718 /* OR objects(SUBJECT) to p_connections(PREDICATE) */
3719 p_outsize = rdfstore_bits_or(outsize, me->bits_decode, p_outsize, p_connections, me->bits_encode);
3720 bcopy(me->bits_encode, p_connections, p_outsize); /* slow? */
3721
3722 /* OR objects(SUBJECT) to o_connections(OBJECT) */
3723 o_outsize = rdfstore_bits_or(outsize, me->bits_decode, o_outsize, o_connections, me->bits_encode);
3724 bcopy(me->bits_encode, o_connections, o_outsize); /* slow? */
3725
3726 /* fetch objects(PREDICATE) */
3727 packInt(statement->predicate->hashcode, outbuf);
3728 key.data = outbuf;
3729 key.size = sizeof(int);
3730
3731 err = rdfstore_flat_store_fetch(me->objects, key, &data);
3732 if (err != 0) {
3733 if (err != FLAT_STORE_E_NOTFOUND) {
3734 perror("rdfstore_insert");
3735 fprintf(stderr,"Could not fetch key '%s' for predicate in objects table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->objects));
3736 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3737 rdfstore_iterator_close(reindex);
3738 #endif
3739 return -1;
3740 } else {
3741 outsize = 0;
3742 };
3743 } else {
3744 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
3745 RDFSTORE_FREE(data.data);
3746 };
3747
3748 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3749 /* 2.3) reindex st_id for connections to objects(PREDICATE) node */
3750
3751 /* copy the objects(PREDICATE) bits through the reindex iterator array */
3752 memcpy(reindex->ids, me->bits_decode, outsize);
3753 reindex->ids_size = outsize;
3754 /* set the size - inefficient!! */
3755 pos = 0;
3756 reindex->size = 0;
3757 /* count the ones (inefficient still) */
3758 while ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < 8 * outsize) {
3759 reindex->size++;
3760 pos++;
3761 };
3762
3763 /* scan the obtained iterator */
3764 while ( ( neighbour = rdfstore_iterator_each ( reindex ) ) != NULL ) {
3765
3766 #ifdef RDFSTORE_DEBUG_CONNECTIONS
3767 printf("(insert)REINDEXING subject '%s' for connections to objects('%s') node in st_id=%d\n",neighbour->subject->value.resource.identifier,statement->predicate->value.resource.identifier,st_id);
3768 #endif
3769 neighbour->subject->hashcode = rdfstore_digest_get_node_hashCode(neighbour->subject, 0);
3770
3771 /* fetch s_connections(neighbour->subject) */
3772 packInt(neighbour->subject->hashcode, outbuf); /* wrong */
3773 key.data = outbuf;
3774 key.size = sizeof(int);
3775
3776 err = rdfstore_flat_store_fetch(me->s_connections, key, &data);
3777 if (err != 0) {
3778 if (err != FLAT_STORE_E_NOTFOUND) {
3779 perror("rdfstore_insert");
3780 fprintf(stderr,"Could not fetch key '%s' for subject in s_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
3781 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3782 rdfstore_iterator_close(reindex);
3783 #endif
3784 return -1;
3785 } else {
3786 outsize_reindex = 0;
3787 };
3788 } else {
3789 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
3790 RDFSTORE_FREE(data.data);
3791 };
3792
3793 /* set the corresponding bit of this statement */
3794 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 1, sizeof(reindex_decode));
3795
3796 /* store it back */
3797 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
3798
3799 data.data = reindex_encode;
3800 data.size = outsize_reindex;
3801 err = rdfstore_flat_store_store(me->s_connections, key, data);
3802 if (err != 0) {
3803 if (err != FLAT_STORE_E_KEYEXIST) {
3804 perror("rdfstore_insert");
3805 fprintf(stderr,"Could not store '%d' bytes for subject in s_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
3806 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3807 rdfstore_iterator_close(reindex);
3808 #endif
3809 return -1;
3810 };
3811 };
3812
3813 #ifdef RDFSTORE_DEBUG_CONNECTIONS
3814 printf("(insert)REINDEXING predicate '%s' for connections to objects('%s') node in st_id=%d\n",neighbour->predicate->value.resource.identifier,statement->predicate->value.resource.identifier,st_id);
3815 #endif
3816 neighbour->predicate->hashcode = rdfstore_digest_get_node_hashCode(neighbour->predicate, 0);
3817
3818 /* fetch p_connections(neighbour->predicate) */
3819 packInt(neighbour->predicate->hashcode, outbuf); /* wrong */
3820 key.data = outbuf;
3821 key.size = sizeof(int);
3822
3823 err = rdfstore_flat_store_fetch(me->p_connections, key, &data);
3824 if (err != 0) {
3825 if (err != FLAT_STORE_E_NOTFOUND) {
3826 perror("rdfstore_insert");
3827 fprintf(stderr,"Could not fetch key '%s' for predicate in p_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
3828 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3829 rdfstore_iterator_close(reindex);
3830 #endif
3831 return -1;
3832 } else {
3833 outsize_reindex = 0;
3834 };
3835 } else {
3836 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
3837 RDFSTORE_FREE(data.data);
3838 };
3839
3840 /* set the corresponding bit of this statement */
3841 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 1, sizeof(reindex_decode));
3842
3843 /* store it back */
3844 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
3845
3846 data.data = reindex_encode;
3847 data.size = outsize_reindex;
3848 err = rdfstore_flat_store_store(me->p_connections, key, data);
3849 if (err != 0) {
3850 if (err != FLAT_STORE_E_KEYEXIST) {
3851 perror("rdfstore_insert");
3852 fprintf(stderr,"Could not store '%d' bytes for predicate in p_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
3853 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3854 rdfstore_iterator_close(reindex);
3855 #endif
3856 return -1;
3857 };
3858 };
3859
3860 /* free neighbour */
3861 RDFSTORE_FREE( neighbour->subject->value.resource.identifier );
3862 RDFSTORE_FREE( neighbour->subject );
3863 RDFSTORE_FREE( neighbour->predicate->value.resource.identifier );
3864 RDFSTORE_FREE( neighbour->predicate );
3865 if ( neighbour->object->type == 1 ) {
3866 if ( neighbour->object->value.literal.dataType != NULL )
3867 RDFSTORE_FREE( neighbour->object->value.literal.dataType );
3868 RDFSTORE_FREE( neighbour->object->value.literal.string );
3869 } else {
3870 RDFSTORE_FREE( neighbour->object->value.resource.identifier );
3871 };
3872 RDFSTORE_FREE( neighbour->object );
3873 if ( neighbour->context != NULL ) {
3874 RDFSTORE_FREE( neighbour->context->value.resource.identifier );
3875 RDFSTORE_FREE( neighbour->context );
3876 };
3877 if ( neighbour->node != NULL ) {
3878 RDFSTORE_FREE( neighbour->node->value.resource.identifier );
3879 RDFSTORE_FREE( neighbour->node );
3880 };
3881 RDFSTORE_FREE( neighbour );
3882 };
3883 #endif
3884
3885 /* OR objects(PREDICATE) to s_connections(SUBJECT) */
3886 s_outsize = rdfstore_bits_or(outsize, me->bits_decode, s_outsize, s_connections, me->bits_encode);
3887 bcopy(me->bits_encode, s_connections, s_outsize); /* slow? */
3888
3889 /* OR objects(PREDICATE) to p_connections(PREDICATE) */
3890 p_outsize = rdfstore_bits_or(outsize, me->bits_decode, p_outsize, p_connections, me->bits_encode);
3891 bcopy(me->bits_encode, p_connections, p_outsize); /* slow? */
3892
3893 /* OR objects(PREDICATE) to o_connections(OBJECT) */
3894 o_outsize = rdfstore_bits_or(outsize, me->bits_decode, o_outsize, o_connections, me->bits_encode);
3895 bcopy(me->bits_encode, o_connections, o_outsize); /* slow? */
3896
3897 /* SUBJECT - we need to OR s_connections(SUBJECT) with generated s_connections and store */
3898
3899 /* fetch s_connections(SUBJECT) */
3900 packInt(statement->subject->hashcode, outbuf);
3901 key.data = outbuf;
3902 key.size = sizeof(int);
3903
3904 err = rdfstore_flat_store_fetch(me->s_connections, key, &data);
3905 if (err != 0) {
3906 if (err != FLAT_STORE_E_NOTFOUND) {
3907 perror("rdfstore_insert");
3908 fprintf(stderr,"Could not fetch key '%s' for subject in s_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
3909 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3910 rdfstore_iterator_close(reindex);
3911 #endif
3912 return -1;
3913 } else {
3914 outsize = 0;
3915 };
3916 } else {
3917 me->func_decode_connections(data.size, data.data, &outsize, me->bits_decode);
3918 RDFSTORE_FREE(data.data);
3919 };
3920
3921 /* OR s_connections(SUBJECT) to generated s_connections */
3922 s_outsize = rdfstore_bits_or(outsize, me->bits_decode, s_outsize, s_connections, me->bits_encode);
3923 bcopy(me->bits_encode, s_connections, s_outsize); /* slow? */
3924
3925 me->func_encode_connections(s_outsize, s_connections, &outsize, me->bits_encode);
3926 if (outsize) {
3927 data.data = me->bits_encode;
3928 data.size = outsize;
3929 err = rdfstore_flat_store_store(me->s_connections, key, data);
3930 if (err == 0) {
3931 #ifdef RDFSTORE_DEBUG_COMPRESSION
3932 fprintf(stderr,"Stored %d bytes for '%s' in s_connections table for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
3933 #endif
3934 } else {
3935 if (err != FLAT_STORE_E_KEYEXIST) {
3936 perror("rdfstore_insert");
3937 fprintf(stderr,"Could not store '%d' bytes for subject in s_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
3938 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3939 rdfstore_iterator_close(reindex);
3940 #endif
3941 return -1;
3942 };
3943 };
3944
3945 #ifdef RDFSTORE_DEBUG
3946 {
3947 int i=0;
3948 if ((rdfstore_flat_store_fetch(me->s_connections, key, &data)) == 0) {
3949 me->func_decode_connections(data.size, data.data, &outsize, me->bits_decode);
3950 RDFSTORE_FREE(data.data);
3951 };
3952 printf("ADDED st_num=%d bitno=%d s_connections for subject '%s' -->'", st_id, st_id, statement->subject->value.resource.identifier);
3953 for(i=0;i<8*outsize;i++) {
3954 printf("Rec %d %c\n", i, (me->bits_decode[i>>3] & (1<<(i&7))) ? '1':'0');
3955 };
3956 printf("'\n");
3957 }
3958 #endif
3959
3960 };
3961
3962 /* PREDICATE - we need to OR p_connections(PREDICATE) with generated p_connections and store */
3963
3964 /* fetch p_connections(PREDICATE) */
3965 packInt(statement->predicate->hashcode, outbuf);
3966 key.data = outbuf;
3967 key.size = sizeof(int);
3968
3969 err = rdfstore_flat_store_fetch(me->p_connections, key, &data);
3970 if (err != 0) {
3971 if (err != FLAT_STORE_E_NOTFOUND) {
3972 perror("rdfstore_insert");
3973 fprintf(stderr,"Could not fetch key '%s' for predicate in p_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
3974 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
3975 rdfstore_iterator_close(reindex);
3976 #endif
3977 return -1;
3978 } else {
3979 outsize = 0;
3980 };
3981 } else {
3982 me->func_decode_connections(data.size, data.data, &outsize, me->bits_decode);
3983 RDFSTORE_FREE(data.data);
3984 };
3985
3986 /* OR p_connections(PREDICATE) to generated p_connections */
3987 p_outsize = rdfstore_bits_or(outsize, me->bits_decode, p_outsize, p_connections, me->bits_encode);
3988 bcopy(me->bits_encode, p_connections, p_outsize); /* slow? */
3989
3990 me->func_encode_connections(p_outsize, p_connections, &outsize, me->bits_encode);
3991 if (outsize) {
3992 data.data = me->bits_encode;
3993 data.size = outsize;
3994 err = rdfstore_flat_store_store(me->p_connections, key, data);
3995 if (err == 0) {
3996 #ifdef RDFSTORE_DEBUG_COMPRESSION
3997 fprintf(stderr,"Stored %d bytes for '%s' in p_connections table for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
3998 #endif
3999 } else {
4000 if (err != FLAT_STORE_E_KEYEXIST) {
4001 perror("rdfstore_insert");
4002 fprintf(stderr,"Could not store '%d' bytes for predicate in p_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
4003 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4004 rdfstore_iterator_close(reindex);
4005 #endif
4006 return -1;
4007 };
4008 };
4009
4010 #ifdef RDFSTORE_DEBUG
4011 {
4012 int i=0;
4013 if ((rdfstore_flat_store_fetch(me->p_connections, key, &data)) == 0) {
4014 me->func_decode_connections(data.size, data.data, &outsize, me->bits_decode);
4015 RDFSTORE_FREE(data.data);
4016 };
4017 printf("ADDED st_num=%d bitno=%d p_connections for predicate '%s' -->'", st_id, st_id, statement->predicate->value.resource.identifier);
4018 for(i=0;i<8*outsize;i++) {
4019 printf("Rec %d %c\n", i, (me->bits_decode[i>>3] & (1<<(i&7))) ? '1':'0');
4020 };
4021 printf("'\n");
4022 }
4023 #endif
4024
4025 };
4026
4027 /* OBJECT - we need to OR o_connections(OBJECT) with generated o_connections and store */
4028
4029 /* fetch o_connections(OBJECT) */
4030 packInt(statement->object->hashcode, outbuf);
4031 key.data = outbuf;
4032 key.size = sizeof(int);
4033
4034 err = rdfstore_flat_store_fetch(me->o_connections, key, &data);
4035 if (err != 0) {
4036 if (err != FLAT_STORE_E_NOTFOUND) {
4037 perror("rdfstore_insert");
4038 fprintf(stderr,"Could not fetch key '%s' for object in o_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
4039 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4040 rdfstore_iterator_close(reindex);
4041 #endif
4042 return -1;
4043 } else {
4044 outsize = 0;
4045 };
4046 } else {
4047 me->func_decode_connections(data.size, data.data, &outsize, me->bits_decode);
4048 RDFSTORE_FREE(data.data);
4049 };
4050
4051 /* OR o_connections(OBJECT) to generated o_connections */
4052 o_outsize = rdfstore_bits_or(outsize, me->bits_decode, o_outsize, o_connections, me->bits_encode);
4053 bcopy(me->bits_encode, o_connections, o_outsize); /* slow? */
4054
4055 me->func_encode_connections(o_outsize, o_connections, &outsize, me->bits_encode);
4056 if (outsize) {
4057 data.data = me->bits_encode;
4058 data.size = outsize;
4059 err = rdfstore_flat_store_store(me->o_connections, key, data);
4060 if (err == 0) {
4061 #ifdef RDFSTORE_DEBUG_COMPRESSION
4062 fprintf(stderr,"Stored %d bytes for '%s' in o_connections table for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
4063 #endif
4064 } else {
4065 if (err != FLAT_STORE_E_KEYEXIST) {
4066 perror("rdfstore_insert");
4067 fprintf(stderr,"Could not store '%d' bytes for object in o_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
4068 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4069 rdfstore_iterator_close(reindex);
4070 #endif
4071 return -1;
4072 };
4073 };
4074
4075 #ifdef RDFSTORE_DEBUG
4076 {
4077 int i=0;
4078 if ((rdfstore_flat_store_fetch(me->o_connections, key, &data)) == 0) {
4079 me->func_decode_connections(data.size, data.data, &outsize, me->bits_decode);
4080 RDFSTORE_FREE(data.data);
4081 };
4082 printf("ADDED st_num=%d bitno=%d o_connections for object '%s' -->'", st_id, st_id, (statement->object->type != 1) ? statement->object->value.resource.identifier : statement->object->value.literal.string );
4083 for(i=0;i<8*outsize;i++) {
4084 printf("Rec %d %c\n", i, (me->bits_decode[i>>3] & (1<<(i&7))) ? '1':'0');
4085 };
4086 printf("'\n");
4087 }
4088 #endif
4089
4090 };
4091
4092 #endif /* RDFSTORE_CONNECTIONS */
4093
4094 /* contexts table */
4095
4096 if (context != NULL) {
4097 /* context */
4098 packInt(context->hashcode, outbuf);
4099 key.data = outbuf;
4100 key.size = sizeof(int);
4101
4102 /*
4103 * bzero(me->bits_encode,sizeof(me->bits_encode));
4104 * bzero(me->bits_decode,sizeof(me->bits_decode));
4105 */
4106
4107 err = rdfstore_flat_store_fetch(me->contexts, key, &data);
4108 if (err != 0) {
4109 if (err != FLAT_STORE_E_NOTFOUND) {
4110 perror("rdfstore_insert");
4111 fprintf(stderr,"Could not fetch key '%s' in contexts table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->contexts));
4112 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4113 rdfstore_iterator_close(reindex);
4114 #endif
4115 return -1;
4116 } else {
4117 outsize = 0;
4118 };
4119 } else {
4120 me->func_decode(data.size, data.data, &outsize, me->bits_decode); /* perhaps the
4121 * compression for
4122 * single bits could be
4123 * different */
4124 RDFSTORE_FREE(data.data);
4125 };
4126 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 1, sizeof(me->bits_decode));
4127
4128 me->func_encode(outsize, me->bits_decode, &outsize, me->bits_encode);
4129 if (outsize) {
4130 data.data = me->bits_encode;
4131 data.size = outsize;
4132 err = rdfstore_flat_store_store(me->contexts, key, data);
4133 if (err == 0) {
4134 #ifdef RDFSTORE_DEBUG_COMPRESSION
4135 fprintf(stderr,"Stored %d bytes for '%s' in contexts table for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
4136 #endif
4137 } else {
4138 if (err != FLAT_STORE_E_KEYEXIST) {
4139 perror("rdfstore_insert");
4140 fprintf(stderr,"Could not store '%d' bytes in contexts table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->contexts));
4141 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4142 rdfstore_iterator_close(reindex);
4143 #endif
4144 return -1;
4145 };
4146 };
4147
4148 #ifdef RDFSTORE_DEBUG
4149 {
4150 int i;
4151 if ((rdfstore_flat_store_fetch(me->contexts, key, &data)) == 0) {
4152 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
4153 RDFSTORE_FREE(data.data);
4154 };
4155 printf("ADDED st_num=%d bitno=%d contexts for C '%s' -->'", st_id, st_id, context->value.resource.identifier);
4156 for(i=0;i<8*outsize;i++) {
4157 printf("Rec %d %c\n", i, (me->bits_decode[i>>3] & (1<<(i&7))) ? '1':'0');
4158 };
4159 printf("'\n");
4160 }
4161 #endif
4162 };
4163 };
4164
4165 /* store the statement internal identifier */
4166 packInt(hc, outbuf);
4167 key.data = outbuf;
4168 key.size = sizeof(int);
4169
4170 packInt(st_id, outbuf1);
4171 data.data = outbuf1;
4172 data.size = sizeof(int);
4173
4174 err = rdfstore_flat_store_store(me->statements, key, data);
4175 if (err != 0) {
4176 perror("rdfstore_insert");
4177 fprintf(stderr,"Could not store statement internal identifier in statements for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->statements));
4178 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4179 rdfstore_iterator_close(reindex);
4180 #endif
4181 return -1;
4182 } else {
4183 /* touch DB last modified date */
4184 bzero(&thedateval_tm, sizeof( struct tm ) );
4185
4186 time(&now);
4187
4188 ptm = gmtime(&now);
4189 memcpy(&thedateval_tm, ptm, sizeof(struct tm));
4190
4191 rdfstore_xsd_serialize_dateTime( thedateval_tm, thedateval );
4192
4193 key.data = RDFSTORE_LASTMODIFIED_KEY;
4194 key.size = sizeof(RDFSTORE_LASTMODIFIED_KEY);
4195
4196 data.data = thedateval;
4197 data.size = strlen(thedateval) + 1;
4198
4199 err = rdfstore_flat_store_store(me->model, key, data);
4200 if ( (err != 0) &&
4201 (err != FLAT_STORE_E_KEYEXIST) ) {
4202 perror("rdfstore_insert");
4203 fprintf(stderr,"Could not store last modified date in model for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->model));
4204 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4205 rdfstore_iterator_close(reindex);
4206 #endif
4207 return -1;
4208 };
4209 };
4210
4211 if ((me->sync) &&
4212 (!(me->flag))) {
4213 /* sync :( */
4214 rdfstore_flat_store_sync(me->model);
4215 rdfstore_flat_store_sync(me->nodes);
4216 rdfstore_flat_store_sync(me->subjects);
4217 rdfstore_flat_store_sync(me->predicates);
4218 rdfstore_flat_store_sync(me->objects);
4219 if (context != NULL)
4220 rdfstore_flat_store_sync(me->contexts);
4221 #ifdef RDFSTORE_CONNECTIONS
4222 if (me->s_connections)
4223 rdfstore_flat_store_sync(me->s_connections);
4224 if (me->p_connections)
4225 rdfstore_flat_store_sync(me->p_connections);
4226 if (me->o_connections)
4227 rdfstore_flat_store_sync(me->o_connections);
4228 #endif
4229 if (me->languages)
4230 rdfstore_flat_store_sync(me->languages);
4231 if (me->datatypes)
4232 rdfstore_flat_store_sync(me->datatypes);
4233 if (me->xsd_integer)
4234 rdfstore_flat_store_sync(me->xsd_integer);
4235 if (me->xsd_double)
4236 rdfstore_flat_store_sync(me->xsd_double);
4237 if (me->xsd_date)
4238 rdfstore_flat_store_sync(me->xsd_date);
4239 if (me->freetext)
4240 rdfstore_flat_store_sync(me->windex);
4241 };
4242
4243 /*
4244 * gettideofday(&tnow,NULL); ttime = ( tnow.tv_eec - tstart.tv_sec ) *
4245 * 1000000 + ( tnow.tv_usec - tstart.tv_usec ) * 1;
4246 * printf("rdfstore_insert DONE [%d micro sec]\n",ttime);
4247 */
4248
4249 #ifdef RDFSTORE_FLAT_STORE_DEBUG /*&& RDFSTORE_COUNT_OPERATIONS_PER_STATEMENT*/
4250 fprintf(stderr,"rdfstore_insert DONE\n");
4251 #endif
4252
4253 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4254 rdfstore_iterator_close(reindex);
4255 #endif
4256
4257 return 0;
4258 };
4259
4260 int
rdfstore_remove(rdfstore * me,RDF_Statement * statement,RDF_Node * given_context)4261 rdfstore_remove(
4262 rdfstore * me,
4263 RDF_Statement * statement,
4264 RDF_Node * given_context
4265 )
4266 {
4267 RDF_Node *context = NULL;
4268 unsigned int outsize = 0;
4269 unsigned int st_id = 0;
4270 DBT key, data;
4271 unsigned char outbuf[256];
4272 unsigned char *word;
4273 unsigned char *utf8_casefolded_buff;
4274 unsigned int utf8_size = 0, pos = 0;
4275 char *sep = RDFSTORE_WORD_SPLITS;
4276 int err;
4277 rdf_store_digest_t hc = 0;
4278
4279 int islval=0;
4280 int isdval=0;
4281 long thelval;
4282 double thedval;
4283 struct tm thedateval_tm;
4284 struct tm* ptm;
4285 time_t now;
4286 char thedateval[RDFSTORE_XSD_DATETIME_FORMAT_SIZE];
4287
4288 #ifdef RDFSTORE_CONNECTIONS
4289 /* buffers for connections matrixes */
4290 static unsigned char s_connections[RDFSTORE_MAXRECORDS_BYTES_SIZE];
4291 static unsigned char p_connections[RDFSTORE_MAXRECORDS_BYTES_SIZE];
4292 static unsigned char o_connections[RDFSTORE_MAXRECORDS_BYTES_SIZE];
4293 unsigned int s_outsize = 0;
4294 unsigned int p_outsize = 0;
4295 unsigned int o_outsize = 0;
4296
4297 bzero(s_connections,sizeof(RDFSTORE_MAXRECORDS_BYTES_SIZE));
4298 bzero(p_connections,sizeof(RDFSTORE_MAXRECORDS_BYTES_SIZE));
4299 bzero(o_connections,sizeof(RDFSTORE_MAXRECORDS_BYTES_SIZE));
4300
4301 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4302 rdfstore_iterator *reindex;
4303 RDF_Statement * neighbour;
4304 unsigned int outsize_reindex = 0;
4305 static unsigned char reindex_encode[RDFSTORE_MAXRECORDS_BYTES_SIZE];
4306 static unsigned char reindex_decode[RDFSTORE_MAXRECORDS_BYTES_SIZE];
4307
4308 bzero(reindex_encode,sizeof(RDFSTORE_MAXRECORDS_BYTES_SIZE));
4309 bzero(reindex_decode,sizeof(RDFSTORE_MAXRECORDS_BYTES_SIZE));
4310 #endif
4311
4312 #endif
4313
4314 if ((statement == NULL) ||
4315 (statement->subject == NULL) ||
4316 (statement->predicate == NULL) ||
4317 (statement->subject->value.resource.identifier == NULL) ||
4318 (statement->predicate->value.resource.identifier == NULL) ||
4319 (statement->object == NULL) ||
4320 ((statement->object->type != 1) &&
4321 (statement->object->value.resource.identifier == NULL)) ||
4322 ((given_context != NULL) &&
4323 (given_context->value.resource.identifier == NULL)) ||
4324 ((statement->node != NULL) &&
4325 (statement->node->value.resource.identifier == NULL)))
4326 return -1;
4327
4328 if (given_context == NULL) {
4329 if (statement->context != NULL)
4330 context = statement->context;
4331 else {
4332 /* use default context */
4333 if (me->context != NULL)
4334 context = me->context;
4335 };
4336 } else {
4337 /* use given context instead */
4338 context = given_context;
4339 };
4340
4341 #ifdef RDFSTORE_DEBUG
4342 fprintf(stderr,"TO REMOVE:\n");
4343 fprintf(stderr,"\tS='%s'\n", statement->subject->value.resource.identifier);
4344 fprintf(stderr,"\tP='%s'\n", statement->predicate->value.resource.identifier);
4345 if (statement->object->type != 1) {
4346 fprintf(stderr,"\tO='%s'\n", statement->object->value.resource.identifier);
4347 } else {
4348 fprintf(stderr,"\tOLIT='%s'", statement->object->value.literal.string);
4349 fprintf(stderr," LANG='%s'", statement->object->value.literal.lang);
4350 fprintf(stderr," TYPE='%s'", statement->object->value.literal.dataType);
4351 fprintf(stderr," PARSETYPE='%d'", statement->object->value.literal.parseType);
4352 fprintf(stderr,"\n");
4353 };
4354 if (context != NULL) {
4355 fprintf(stderr,"\tC='%s'\n", context->value.resource.identifier);
4356 };
4357 if (statement->node != NULL)
4358 fprintf(stderr,"\tSRES='%s'\n", statement->node->value.resource.identifier);
4359 fprintf(stderr," with options freetext='%d'\n", me->freetext);
4360
4361 {
4362 char * buff = NULL;
4363 if ((buff = rdfstore_ntriples_statement(statement, context)) != NULL) {
4364 fprintf(stderr," N-triples: %s\n", buff);
4365 RDFSTORE_FREE(buff);
4366 };
4367 };
4368 #endif
4369
4370 /* look for the statement internal identifier */
4371
4372 memset(&key, 0, sizeof(key));
4373 memset(&data, 0, sizeof(data));
4374
4375 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4376 /* init re-index iterator (needed below when filling up adjacency matrixes) */
4377 reindex = (rdfstore_iterator *) RDFSTORE_MALLOC(sizeof(rdfstore_iterator));
4378 if (reindex == NULL) {
4379 perror("rdfstore_insert");
4380 fprintf(stderr,"Cannot create reindex cursor/iterator for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
4381 return -1;
4382 };
4383 reindex->store = me;
4384 reindex->store->attached++;
4385 reindex->remove_holes = 0; /* reset the total number of holes */
4386 reindex->st_counter = 0;
4387 reindex->pos = 0;
4388 reindex->ids_size = 0;
4389 reindex->size = 0;
4390 #endif
4391
4392 /* compute statement hashcode */
4393 hc = rdfstore_digest_get_statement_hashCode(statement, context);
4394
4395 /* cache the hashcode if the statement has a "proper" identity */
4396 if ((given_context == NULL) &&
4397 (me->context == NULL))
4398 statement->hashcode = hc;
4399
4400 packInt(hc, outbuf);
4401
4402 #ifdef RDFSTORE_DEBUG
4403 {
4404 int i = 0;
4405 printf("Statement hashcode is '%d' while packed is '", hc);
4406 for (i = 0; i < sizeof(int); i++) {
4407 printf("%02X", outbuf[i]);
4408 };
4409 printf("'\n");
4410 }
4411 #endif
4412
4413 key.data = outbuf;
4414 key.size = sizeof(int);
4415 if ((rdfstore_flat_store_fetch(me->statements, key, &data)) != 0) {
4416 #ifdef RDFSTORE_DEBUG
4417 {
4418 char * buff = NULL;
4419 if ((buff = rdfstore_ntriples_statement(statement, context)) != NULL) {
4420 fprintf(stderr,"Statement '%s' does not exists in store '%s'\n", buff, (me->name != NULL) ? me->name : "(in-memory)");
4421 RDFSTORE_FREE(buff);
4422 };
4423 };
4424 #endif
4425 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4426 rdfstore_iterator_close(reindex);
4427 #endif
4428 return 1;
4429 };
4430 /* sort out statement id */
4431 unpackInt(data.data, &st_id);
4432 RDFSTORE_FREE(data.data);
4433
4434 /*
4435 * remove statement components (also the statement as resource stuff???)
4436 */
4437 packInt(st_id, outbuf);
4438 key.data = outbuf;
4439 key.size = sizeof(int);
4440 err = rdfstore_flat_store_delete(me->nodes, key);
4441 if (err != 0) {
4442 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4443 rdfstore_iterator_close(reindex);
4444 #endif
4445 if (err != FLAT_STORE_E_NOTFOUND) {
4446 perror("rdfstore_remove");
4447 fprintf(stderr,"Could not delete statement for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->nodes));
4448 return -1;
4449 } else {
4450 return 1;
4451 };
4452 };
4453
4454 /* remove adjacency matrixes stuff */
4455
4456 /*
4457 * compute other hashcodes (the should be cached because the
4458 * underlying digest is carried out also for the statement->hashcode
4459 * above)
4460 */
4461 statement->subject->hashcode = rdfstore_digest_get_node_hashCode(statement->subject, 0);
4462 statement->predicate->hashcode = rdfstore_digest_get_node_hashCode(statement->predicate, 0);
4463 statement->object->hashcode = rdfstore_digest_get_node_hashCode(statement->object, 0);
4464 if (context != NULL)
4465 context->hashcode = rdfstore_digest_get_node_hashCode(context, 0);
4466
4467 /*
4468 *
4469 * Anoatomy of connections removal
4470 *
4471 * here are all the possible connections an existing statement might get into (i.e. "swiss army knife problem"):
4472 *
4473 * a4 a6 a8
4474 * \ \ \
4475 * \ * * \ * * \
4476 * \---> A =====*=======> B ======*======> C------>b9----->c9
4477 * / ^\ * * /^\ * * ^\
4478 * / | \ / | \ | \
4479 * b5<---/ | \--->c4 / | \--->c6 | \--->c8
4480 * / b1 / b2 b3
4481 * / ^ b7<---/ ^ ^
4482 * c5<---/ | \ | |
4483 * | \ | |
4484 * a1 \--->c7 a2 a3
4485 *
4486 *
4487 * where A======>B======>C is the statement to remove and '*' flags edges/arcs to zap
4488 *
4489 * when a statement is removed e.g. (A,B,C) the corresponding connections tables need to be updated; together with the
4490 * ones of its neighbours. First, the two graph edges connecting the statement components (see '*' signs in the above pic)
4491 * need to be pruned; then each other connection to neighbours need to be reset accordingly for the statement (st_id) being
4492 * removed. By removing the connection arcs for the statements the corresponding connections to the connected components
4493 * need to be removed from each node connection too; this means if a specific node is being a component of more than one
4494 * statement e.g. C in the above pic - we need for example to reset each connection due to each other component of the statement
4495 * being removed. For example, by removing the above statement the C nods needs to reset its connections to other statemnts
4496 * due to A and B nodes (which WERE its subject and object before the statement was removed) - clear enough???!
4497 * In practice, when carrying out the connections tables for the statement components being removed we just keep the connections
4498 * due to each node self (e.g. for C its subjects(C), predicates(C) and object(C) - of course if not empty - clear?) and do not
4499 * consider (reset) all the other set during insertion/updation - which now are not more used.
4500 *
4501 */
4502
4503 /* subjects */
4504 packInt(statement->subject->hashcode, outbuf);
4505 key.data = outbuf;
4506 key.size = sizeof(int);
4507
4508 /*
4509 * bzero(me->bits_encode,sizeof(me->bits_encode));
4510 * bzero(me->bits_decode,sizeof(me->bits_decode));
4511 */
4512 err = rdfstore_flat_store_fetch(me->subjects, key, &data);
4513 if (err != 0) {
4514 if (err != FLAT_STORE_E_NOTFOUND) {
4515 perror("rdfstore_remove");
4516 fprintf(stderr,"Could not fetch key '%s' for subject in subjects for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->subjects));
4517 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4518 rdfstore_iterator_close(reindex);
4519 #endif
4520 return -1;
4521 } else {
4522 outsize = 0;
4523 };
4524 } else {
4525 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
4526 RDFSTORE_FREE(data.data);
4527 };
4528
4529 /* reset the right bit to zero */
4530 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 0, sizeof(me->bits_decode));
4531
4532 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4533 /*
4534 We need to re-index quite a lot for each new statement component now - hope caching will
4535 help here!! i.e. the swiss army nife problem (see SWAD-E paper and preso)
4536
4537 1.1) remove this new statement (st_id) from p_connections(neighbour->predicate) and o_connections(neighbour->object)
4538 tables of each other statement (neighbour) connected to this one via subjects(SUBJECT) node
4539 1.2) remove this new statement (st_id) from s_connections(neighbour->subject) and o_connections(neighbour->object)
4540 tables of each other statement (neighbour) connected to this one via predicates(SUBJECT) node
4541 1.3) remove this new statement (st_id) from s_connections(neighbour->subject) and p_connections(neighbour->predicate)
4542 tables of each other statement (neighbour) connected to this one via objects(SUBJECT) node
4543 */
4544
4545 /* 1.1) reindex st_id for connections to subjects(SUBJECT) node */
4546
4547 /* copy the subjects(SUBJECT) bits through the reindex iterator array */
4548 memcpy(reindex->ids, me->bits_decode, outsize);
4549 reindex->ids_size = outsize;
4550 /* set the size - inefficient!! */
4551 pos = 0;
4552 reindex->size = 0;
4553 /* count the ones (inefficient still) */
4554 while ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < 8 * outsize) {
4555 reindex->size++;
4556 pos++;
4557 };
4558
4559 /* scan the obtained iterator */
4560 while ( ( neighbour = rdfstore_iterator_each ( reindex ) ) != NULL ) {
4561
4562 #ifdef RDFSTORE_DEBUG_CONNECTIONS
4563 printf("(remove)REINDEXING predicate '%s' for connections to subjects('%s') node in st_id=%d\n",neighbour->predicate->value.resource.identifier,statement->subject->value.resource.identifier,st_id);
4564 #endif
4565 neighbour->predicate->hashcode = rdfstore_digest_get_node_hashCode(neighbour->predicate, 0);
4566
4567 /* fetch p_connections(neighbour->predicate) */
4568 packInt(neighbour->predicate->hashcode, outbuf); /* wrong */
4569 key.data = outbuf;
4570 key.size = sizeof(int);
4571
4572 err = rdfstore_flat_store_fetch(me->p_connections, key, &data);
4573 if (err != 0) {
4574 if (err != FLAT_STORE_E_NOTFOUND) {
4575 perror("rdfstore_remove");
4576 fprintf(stderr,"Could not fetch key '%s' for predicate in p_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
4577 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4578 rdfstore_iterator_close(reindex);
4579 #endif
4580 return -1;
4581 } else {
4582 outsize_reindex = 0;
4583 };
4584 } else {
4585 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
4586 RDFSTORE_FREE(data.data);
4587 };
4588
4589 /* reset the corresponding bit of this statement */
4590 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 0, sizeof(reindex_decode));
4591
4592 /* store it back */
4593 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
4594
4595 data.data = reindex_encode;
4596 data.size = outsize_reindex;
4597 err = rdfstore_flat_store_store(me->p_connections, key, data);
4598 if (err != 0) {
4599 if (err != FLAT_STORE_E_KEYEXIST) {
4600 perror("rdfstore_remove");
4601 fprintf(stderr,"Could not store '%d' bytes for predicate in p_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
4602 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4603 rdfstore_iterator_close(reindex);
4604 #endif
4605 return -1;
4606 };
4607 };
4608
4609 #ifdef RDFSTORE_DEBUG_CONNECTIONS
4610 printf("(remove)REINDEXING object '%s' for connections to subjects('%s') node in st_id=%d\n",(neighbour->object->type==1) ? neighbour->object->value.literal.string : neighbour->object->value.resource.identifier,statement->subject->value.resource.identifier,st_id);
4611 #endif
4612 neighbour->object->hashcode = rdfstore_digest_get_node_hashCode(neighbour->object, 0);
4613
4614 /* fetch o_connections(neighbour->object) */
4615 packInt(neighbour->object->hashcode, outbuf); /* wrong */
4616 key.data = outbuf;
4617 key.size = sizeof(int);
4618
4619 err = rdfstore_flat_store_fetch(me->o_connections, key, &data);
4620 if (err != 0) {
4621 if (err != FLAT_STORE_E_NOTFOUND) {
4622 perror("rdfstore_remove");
4623 fprintf(stderr,"Could not fetch key '%s' for object in o_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
4624 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4625 rdfstore_iterator_close(reindex);
4626 #endif
4627 return -1;
4628 } else {
4629 outsize_reindex = 0;
4630 };
4631 } else {
4632 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
4633 RDFSTORE_FREE(data.data);
4634 };
4635
4636 /* reset the corresponding bit of this statement */
4637 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 0, sizeof(reindex_decode));
4638
4639 /* store it back */
4640 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
4641
4642 /* now: we do not need/must check whther or not to remove this key because the other statement is sitll there */
4643
4644 data.data = reindex_encode;
4645 data.size = outsize_reindex;
4646 err = rdfstore_flat_store_store(me->o_connections, key, data);
4647 if (err != 0) {
4648 if (err != FLAT_STORE_E_KEYEXIST) {
4649 perror("rdfstore_remove");
4650 fprintf(stderr,"Could not store '%d' bytes for object in o_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
4651 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4652 rdfstore_iterator_close(reindex);
4653 #endif
4654 return -1;
4655 };
4656 };
4657
4658 /* free neighbour */
4659 RDFSTORE_FREE( neighbour->subject->value.resource.identifier );
4660 RDFSTORE_FREE( neighbour->subject );
4661 RDFSTORE_FREE( neighbour->predicate->value.resource.identifier );
4662 RDFSTORE_FREE( neighbour->predicate );
4663 if ( neighbour->object->type == 1 ) {
4664 if ( neighbour->object->value.literal.dataType != NULL )
4665 RDFSTORE_FREE( neighbour->object->value.literal.dataType );
4666 RDFSTORE_FREE( neighbour->object->value.literal.string );
4667 } else {
4668 RDFSTORE_FREE( neighbour->object->value.resource.identifier );
4669 };
4670 RDFSTORE_FREE( neighbour->object );
4671 if ( neighbour->context != NULL ) {
4672 RDFSTORE_FREE( neighbour->context->value.resource.identifier );
4673 RDFSTORE_FREE( neighbour->context );
4674 };
4675 if ( neighbour->node != NULL ) {
4676 RDFSTORE_FREE( neighbour->node->value.resource.identifier );
4677 RDFSTORE_FREE( neighbour->node );
4678 };
4679 RDFSTORE_FREE( neighbour );
4680 };
4681 #endif
4682
4683 /* regenerate it due to the re-indexing above which uses key already */
4684 packInt(statement->subject->hashcode, outbuf);
4685 key.data = outbuf;
4686 key.size = sizeof(int);
4687
4688 outsize = rdfstore_bits_shorten(outsize, me->bits_decode);
4689
4690 if ( outsize > 0 ) {
4691 me->func_encode(outsize, me->bits_decode, &outsize, me->bits_encode);
4692 if (outsize) {
4693 data.data = me->bits_encode;
4694 data.size = outsize;
4695 err = rdfstore_flat_store_store(me->subjects, key, data);
4696 if (err == 0) {
4697 #ifdef RDFSTORE_DEBUG_COMPRESSION
4698 fprintf(stderr,"Stored %d bytes for '%s' in subjects for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
4699 #endif
4700 } else {
4701 if (err != FLAT_STORE_E_KEYEXIST) {
4702 perror("rdfstore_remove");
4703 fprintf(stderr,"Could not store '%d' bytes for subject in subjects for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->subjects));
4704 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4705 rdfstore_iterator_close(reindex);
4706 #endif
4707 return -1;
4708 };
4709 };
4710
4711 #ifdef RDFSTORE_DEBUG
4712 {
4713 int i=0;
4714 if ((rdfstore_flat_store_fetch(me->subjects, key, &data)) == 0) {
4715 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
4716 RDFSTORE_FREE(data.data);
4717 };
4718 printf("REMOVED st_num=%d bitno=%d subjects for S -->'", st_id, st_id);
4719 for(i=0;i<8*outsize;i++) {
4720 printf("Rec %d %c\n", i, (me->bits_decode[i>>3] & (1<<(i&7))) ? '1':'0');
4721 };
4722 printf("'\n");
4723 }
4724 #endif
4725
4726 };
4727
4728 #ifdef RDFSTORE_CONNECTIONS
4729 /* COPY subjects(SUBJECT) to s_connections(SUBJECT) */
4730 bcopy(me->bits_decode, s_connections, outsize); /* slow? */
4731 s_outsize = outsize;
4732 #endif
4733 } else {
4734 err = rdfstore_flat_store_delete(me->subjects, key);
4735 if (err != 0) {
4736 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4737 rdfstore_iterator_close(reindex);
4738 #endif
4739 if (err != FLAT_STORE_E_NOTFOUND) {
4740 perror("rdfstore_remove");
4741 fprintf(stderr,"Could not delete statement for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->subjects));
4742 return -1;
4743 } else {
4744 return 1;
4745 };
4746 };
4747 #ifdef RDFSTORE_DEBUG
4748 printf("DELETED (%d) subjects for S\n", st_id);
4749 #endif
4750 };
4751
4752 MX;
4753 /* predicates */
4754 packInt(statement->predicate->hashcode, outbuf);
4755 key.data = outbuf;
4756 key.size = sizeof(int);
4757 MX;
4758
4759 /*
4760 * bzero(me->bits_encode,sizeof(me->bits_encode));
4761 * bzero(me->bits_decode,sizeof(me->bits_decode));
4762 */
4763 err = rdfstore_flat_store_fetch(me->predicates, key, &data);
4764 if (err != 0) {
4765 if (err != FLAT_STORE_E_NOTFOUND) {
4766 perror("rdfstore_remove");
4767 fprintf(stderr,"Could not fetch key '%s' for predicate in predicates for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->predicates));
4768 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4769 rdfstore_iterator_close(reindex);
4770 #endif
4771 return -1;
4772 } else {
4773 outsize = 0;
4774 };
4775 } else {
4776 me->func_decode(data.size, data.data, &outsize, me->bits_decode); /* perhaps the
4777 * compression for
4778 * single bits could be
4779 * different */
4780 RDFSTORE_FREE(data.data);
4781 };
4782
4783 MX;
4784 /* reset the right bits to zero */
4785 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 0, sizeof(me->bits_decode));
4786
4787 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4788 /* 2.2) reindex st_id for connections to predicates(PREDICATE) node */
4789
4790 /* copy the predicates(PREDICATE) bits through the reindex iterator array */
4791 memcpy(reindex->ids, me->bits_decode, outsize);
4792 reindex->ids_size = outsize;
4793 /* set the size - inefficient!! */
4794 pos = 0;
4795 reindex->size = 0;
4796 /* count the ones (inefficient still) */
4797 while ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < 8 * outsize) {
4798 reindex->size++;
4799 pos++;
4800 };
4801
4802 /* scan the obtained iterator */
4803 while ( ( neighbour = rdfstore_iterator_each ( reindex ) ) != NULL ) {
4804
4805 #ifdef RDFSTORE_DEBUG_CONNECTIONS
4806 printf("(remove)REINDEXING subject '%s' for connections to predicates('%s') node in st_id=%d\n",neighbour->subject->value.resource.identifier,statement->predicate->value.resource.identifier,st_id);
4807 #endif
4808 neighbour->subject->hashcode = rdfstore_digest_get_node_hashCode(neighbour->subject, 0);
4809
4810 /* fetch s_connections(neighbour->subject) */
4811 packInt(neighbour->subject->hashcode, outbuf); /* wrong */
4812 key.data = outbuf;
4813 key.size = sizeof(int);
4814
4815 err = rdfstore_flat_store_fetch(me->s_connections, key, &data);
4816 if (err != 0) {
4817 if (err != FLAT_STORE_E_NOTFOUND) {
4818 perror("rdfstore_remove");
4819 fprintf(stderr,"Could not fetch key '%s' for subject in s_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
4820 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4821 rdfstore_iterator_close(reindex);
4822 #endif
4823 return -1;
4824 } else {
4825 outsize_reindex = 0;
4826 };
4827 } else {
4828 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
4829 RDFSTORE_FREE(data.data);
4830 };
4831
4832 /* reset the corresponding bit of this statement */
4833 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 0, sizeof(reindex_decode));
4834
4835 /* store it back */
4836 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
4837
4838 data.data = reindex_encode;
4839 data.size = outsize_reindex;
4840 err = rdfstore_flat_store_store(me->s_connections, key, data);
4841 if (err != 0) {
4842 if (err != FLAT_STORE_E_KEYEXIST) {
4843 perror("rdfstore_remove");
4844 fprintf(stderr,"Could not store '%d' bytes for subject in s_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
4845 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4846 rdfstore_iterator_close(reindex);
4847 #endif
4848 return -1;
4849 };
4850 };
4851
4852 #ifdef RDFSTORE_DEBUG_CONNECTIONS
4853 printf("(remove)REINDEXING object '%s' for connections to predicates('%s') node in st_id=%d\n",(neighbour->object->type==1) ? neighbour->object->value.literal.string : neighbour->object->value.resource.identifier,statement->predicate->value.resource.identifier,st_id);
4854 #endif
4855 neighbour->object->hashcode = rdfstore_digest_get_node_hashCode(neighbour->object, 0);
4856
4857 /* fetch o_connections(neighbour->object) */
4858 packInt(neighbour->object->hashcode, outbuf); /* wrong */
4859 key.data = outbuf;
4860 key.size = sizeof(int);
4861
4862 err = rdfstore_flat_store_fetch(me->o_connections, key, &data);
4863 if (err != 0) {
4864 if (err != FLAT_STORE_E_NOTFOUND) {
4865 perror("rdfstore_remove");
4866 fprintf(stderr,"Could not fetch key '%s' for object in o_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
4867 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4868 rdfstore_iterator_close(reindex);
4869 #endif
4870 return -1;
4871 } else {
4872 outsize_reindex = 0;
4873 };
4874 } else {
4875 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
4876 RDFSTORE_FREE(data.data);
4877 };
4878
4879 /* reset the corresponding bit of this statement */
4880 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 0, sizeof(reindex_decode));
4881
4882 /* store it back */
4883 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
4884
4885 data.data = reindex_encode;
4886 data.size = outsize_reindex;
4887 err = rdfstore_flat_store_store(me->o_connections, key, data);
4888 if (err != 0) {
4889 if (err != FLAT_STORE_E_KEYEXIST) {
4890 perror("rdfstore_remove");
4891 fprintf(stderr,"Could not store '%d' bytes for object in o_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
4892 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4893 rdfstore_iterator_close(reindex);
4894 #endif
4895 return -1;
4896 };
4897 };
4898
4899 /* free neighbour */
4900 RDFSTORE_FREE( neighbour->subject->value.resource.identifier );
4901 RDFSTORE_FREE( neighbour->subject );
4902 RDFSTORE_FREE( neighbour->predicate->value.resource.identifier );
4903 RDFSTORE_FREE( neighbour->predicate );
4904 if ( neighbour->object->type == 1 ) {
4905 if ( neighbour->object->value.literal.dataType != NULL )
4906 RDFSTORE_FREE( neighbour->object->value.literal.dataType );
4907 RDFSTORE_FREE( neighbour->object->value.literal.string );
4908 } else {
4909 RDFSTORE_FREE( neighbour->object->value.resource.identifier );
4910 };
4911 RDFSTORE_FREE( neighbour->object );
4912 if ( neighbour->context != NULL ) {
4913 RDFSTORE_FREE( neighbour->context->value.resource.identifier );
4914 RDFSTORE_FREE( neighbour->context );
4915 };
4916 if ( neighbour->node != NULL ) {
4917 RDFSTORE_FREE( neighbour->node->value.resource.identifier );
4918 RDFSTORE_FREE( neighbour->node );
4919 };
4920 RDFSTORE_FREE( neighbour );
4921 };
4922 #endif
4923
4924 /* regenerate it due to the re-indexing above which uses key already */
4925 packInt(statement->predicate->hashcode, outbuf);
4926 key.data = outbuf;
4927 key.size = sizeof(int);
4928
4929 outsize = rdfstore_bits_shorten(outsize, me->bits_decode);
4930 if ( outsize > 0 ) {
4931 me->func_encode(outsize, me->bits_decode, &outsize, me->bits_encode);
4932 if (outsize) {
4933 data.data = me->bits_encode;
4934 data.size = outsize;
4935 err = rdfstore_flat_store_store(me->predicates, key, data);
4936 if (err == 0) {
4937 #ifdef RDFSTORE_DEBUG_COMPRESSION
4938 fprintf(stderr,"Stored %d bytes for '%s' in predicates for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
4939 #endif
4940 } else {
4941 if (err != FLAT_STORE_E_KEYEXIST) {
4942 perror("rdfstore_remove");
4943 fprintf(stderr,"Could not store '%d' bytes for predicate in predicates for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->predicates));
4944 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4945 rdfstore_iterator_close(reindex);
4946 #endif
4947 return -1;
4948 };
4949 };
4950
4951 #ifdef RDFSTORE_DEBUG
4952 {
4953 int i=0;
4954 if ((rdfstore_flat_store_fetch(me->predicates, key, &data)) == 0) {
4955 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
4956 RDFSTORE_FREE(data.data);
4957 };
4958 printf("REMOVED st_num=%d bitno=%d predicates for P -->'", st_id,st_id);
4959 for(i=0;i<8*outsize;i++) {
4960 printf("Rec %d %c\n", i, (me->bits_decode[i>>3] & (1<<(i&7))) ? '1':'0');
4961 };
4962 printf("'\n");
4963 }
4964 #endif
4965
4966 };
4967 #ifdef RDFSTORE_CONNECTIONS
4968 /* OR predicates(PREDICATE) to p_connections(PREDICATE) */
4969 p_outsize = rdfstore_bits_or(outsize, me->bits_decode, p_outsize, p_connections, me->bits_encode);
4970 bcopy(me->bits_encode, p_connections, p_outsize); /* slow? */
4971 #endif
4972 } else {
4973 err = rdfstore_flat_store_delete(me->predicates, key);
4974 if (err != 0) {
4975 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
4976 rdfstore_iterator_close(reindex);
4977 #endif
4978 if (err != FLAT_STORE_E_NOTFOUND) {
4979 perror("rdfstore_remove");
4980 fprintf(stderr,"Could not delete statement for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->predicates));
4981 return -1;
4982 } else {
4983 return 1;
4984 };
4985 };
4986 #ifdef RDFSTORE_DEBUG
4987 printf("DELETED (%d) predicates for P\n", st_id);
4988 #endif
4989 };
4990
4991 MX;
4992
4993 /* objects */
4994 packInt(statement->object->hashcode, outbuf);
4995 key.data = outbuf;
4996 key.size = sizeof(int);
4997
4998 /*
4999 * bzero(me->bits_encode,sizeof(me->bits_encode));
5000 * bzero(me->bits_decode,sizeof(me->bits_decode));
5001 */
5002 err = rdfstore_flat_store_fetch(me->objects, key, &data);
5003 if (err != 0) {
5004 if (err != FLAT_STORE_E_NOTFOUND) {
5005 perror("rdfstore_remove");
5006 fprintf(stderr,"Could not fetch key '%s' for object in objects for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->objects));
5007 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5008 rdfstore_iterator_close(reindex);
5009 #endif
5010 return -1;
5011 } else {
5012 outsize = 0;
5013 };
5014 } else {
5015 me->func_decode(data.size, data.data, &outsize, me->bits_decode); /* perhaps the
5016 * compression for
5017 * single bits could be
5018 * different */
5019 RDFSTORE_FREE(data.data);
5020 };
5021
5022 /* reset the right bit to zero */
5023 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 0, sizeof(me->bits_decode));
5024
5025 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5026 /* 3.3) reindex st_id for connections to objects(OBJECT) node */
5027
5028 /* copy the objects(OBJECT) bits through the reindex iterator array */
5029 memcpy(reindex->ids, me->bits_decode, outsize);
5030 reindex->ids_size = outsize;
5031 /* set the size - inefficient!! */
5032 pos = 0;
5033 reindex->size = 0;
5034 /* count the ones (inefficient still) */
5035 while ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < 8 * outsize) {
5036 reindex->size++;
5037 pos++;
5038 };
5039
5040 /* scan the obtained iterator */
5041 while ( ( neighbour = rdfstore_iterator_each ( reindex ) ) != NULL ) {
5042
5043 #ifdef RDFSTORE_DEBUG_CONNECTIONS
5044 printf("(remove)REINDEXING subject '%s' for connections to objects('%s') node in st_id=%d\n",neighbour->subject->value.resource.identifier,(statement->object->type==1) ? statement->object->value.literal.string : statement->object->value.resource.identifier,st_id);
5045 #endif
5046 neighbour->subject->hashcode = rdfstore_digest_get_node_hashCode(neighbour->subject, 0);
5047
5048 /* fetch s_connections(neighbour->subject) */
5049 packInt(neighbour->subject->hashcode, outbuf); /* wrong */
5050 key.data = outbuf;
5051 key.size = sizeof(int);
5052
5053 err = rdfstore_flat_store_fetch(me->s_connections, key, &data);
5054 if (err != 0) {
5055 if (err != FLAT_STORE_E_NOTFOUND) {
5056 perror("rdfstore_remove");
5057 fprintf(stderr,"Could not fetch key '%s' for subject in s_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
5058 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5059 rdfstore_iterator_close(reindex);
5060 #endif
5061 return -1;
5062 } else {
5063 outsize_reindex = 0;
5064 };
5065 } else {
5066 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
5067 RDFSTORE_FREE(data.data);
5068 };
5069
5070 /* reset the corresponding bit of this statement */
5071 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 0, sizeof(reindex_decode));
5072
5073 /* store it back */
5074 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
5075
5076 data.data = reindex_encode;
5077 data.size = outsize_reindex;
5078 err = rdfstore_flat_store_store(me->s_connections, key, data);
5079 if (err != 0) {
5080 if (err != FLAT_STORE_E_KEYEXIST) {
5081 perror("rdfstore_remove");
5082 fprintf(stderr,"Could not store '%d' bytes for subject in s_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
5083 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5084 rdfstore_iterator_close(reindex);
5085 #endif
5086 return -1;
5087 };
5088 };
5089
5090 #ifdef RDFSTORE_DEBUG_CONNECTIONS
5091 printf("(remove)REINDEXING predicate '%s' for connections to objects('%s') node in st_id=%d\n",neighbour->predicate->value.resource.identifier,(statement->object->type==1) ? statement->object->value.literal.string : statement->object->value.resource.identifier,st_id);
5092 #endif
5093 neighbour->predicate->hashcode = rdfstore_digest_get_node_hashCode(neighbour->predicate, 0);
5094
5095 /* fetch p_connections(neighbour->predicate) */
5096 packInt(neighbour->predicate->hashcode, outbuf); /* wrong */
5097 key.data = outbuf;
5098 key.size = sizeof(int);
5099
5100 err = rdfstore_flat_store_fetch(me->p_connections, key, &data);
5101 if (err != 0) {
5102 if (err != FLAT_STORE_E_NOTFOUND) {
5103 perror("rdfstore_remove");
5104 fprintf(stderr,"Could not fetch key '%s' for predicate in p_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
5105 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5106 rdfstore_iterator_close(reindex);
5107 #endif
5108 return -1;
5109 } else {
5110 outsize_reindex = 0;
5111 };
5112 } else {
5113 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
5114 RDFSTORE_FREE(data.data);
5115 };
5116
5117 /* reset the corresponding bit of this statement */
5118 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 0, sizeof(reindex_decode));
5119
5120 /* store it back */
5121 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
5122
5123 data.data = reindex_encode;
5124 data.size = outsize_reindex;
5125 err = rdfstore_flat_store_store(me->p_connections, key, data);
5126 if (err != 0) {
5127 if (err != FLAT_STORE_E_KEYEXIST) {
5128 perror("rdfstore_remove");
5129 fprintf(stderr,"Could not store '%d' bytes for predicate in p_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
5130 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5131 rdfstore_iterator_close(reindex);
5132 #endif
5133 return -1;
5134 };
5135 };
5136
5137 /* free neighbour */
5138 RDFSTORE_FREE( neighbour->subject->value.resource.identifier );
5139 RDFSTORE_FREE( neighbour->subject );
5140 RDFSTORE_FREE( neighbour->predicate->value.resource.identifier );
5141 RDFSTORE_FREE( neighbour->predicate );
5142 if ( neighbour->object->type == 1 ) {
5143 if ( neighbour->object->value.literal.dataType != NULL )
5144 RDFSTORE_FREE( neighbour->object->value.literal.dataType );
5145 RDFSTORE_FREE( neighbour->object->value.literal.string );
5146 } else {
5147 RDFSTORE_FREE( neighbour->object->value.resource.identifier );
5148 };
5149 RDFSTORE_FREE( neighbour->object );
5150 if ( neighbour->context != NULL ) {
5151 RDFSTORE_FREE( neighbour->context->value.resource.identifier );
5152 RDFSTORE_FREE( neighbour->context );
5153 };
5154 if ( neighbour->node != NULL ) {
5155 RDFSTORE_FREE( neighbour->node->value.resource.identifier );
5156 RDFSTORE_FREE( neighbour->node );
5157 };
5158 RDFSTORE_FREE( neighbour );
5159 };
5160 #endif
5161
5162 /* regenerate it due to the re-indexing above which uses key already */
5163 packInt(statement->object->hashcode, outbuf);
5164 key.data = outbuf;
5165 key.size = sizeof(int);
5166
5167 outsize = rdfstore_bits_shorten(outsize, me->bits_decode);
5168 if ( outsize > 0 ) {
5169 me->func_encode(outsize, me->bits_decode, &outsize, me->bits_encode);
5170 if (outsize) {
5171 data.data = me->bits_encode;
5172 data.size = outsize;
5173 err = rdfstore_flat_store_store(me->objects, key, data);
5174 if (err == 0) {
5175 #ifdef RDFSTORE_DEBUG_COMPRESSION
5176 fprintf(stderr,"Stored %d bytes for '%s' in objects for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
5177 #endif
5178 } else {
5179 if (err != FLAT_STORE_E_KEYEXIST) {
5180 perror("rdfstore_remove");
5181 fprintf(stderr,"Could not store '%d' bytes for object in objects for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->objects));
5182 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5183 rdfstore_iterator_close(reindex);
5184 #endif
5185 return -1;
5186 };
5187 };
5188
5189 #ifdef RDFSTORE_DEBUG
5190 {
5191 int i=0;
5192 if ((rdfstore_flat_store_fetch(me->objects, key, &data)) == 0) {
5193 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
5194 RDFSTORE_FREE(data.data);
5195 };
5196 printf("REMOVED st_num=%d bitno=%d objects for O -->'", st_id, st_id);
5197 for(i=0;i<8*outsize;i++) {
5198 printf("Rec %d %c\n", i, (me->bits_decode[i>>3] & (1<<(i&7))) ? '1':'0');
5199 };
5200 printf("'\n");
5201 }
5202 #endif
5203
5204 };
5205 #ifdef RDFSTORE_CONNECTIONS
5206 /* OR objects(OBJECT) to o_connections(OBJECT) */
5207 o_outsize = rdfstore_bits_or(outsize, me->bits_decode, o_outsize, o_connections, me->bits_encode);
5208 bcopy(me->bits_encode, o_connections, o_outsize); /* slow? */
5209 #endif
5210 } else {
5211 err = rdfstore_flat_store_delete(me->objects, key);
5212 if (err != 0) {
5213 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5214 rdfstore_iterator_close(reindex);
5215 #endif
5216 if (err != FLAT_STORE_E_NOTFOUND) {
5217 perror("rdfstore_remove");
5218 fprintf(stderr,"Could not delete statement for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->objects));
5219 return -1;
5220 } else {
5221 return 1;
5222 };
5223 };
5224 #ifdef RDFSTORE_DEBUG
5225 printf("DELETED (%d) objects for O\n", st_id);
5226 #endif
5227 };
5228
5229 #ifdef RDFSTORE_CONNECTIONS
5230 /* fill up all the rest of s_connections, p_connections and o_connections i.e. carry out remaining permutations of each component */
5231
5232 /* fetch subjects(PREDICATE) i.e. statements which has PREDICATE as subject */
5233 packInt(statement->predicate->hashcode, outbuf);
5234 key.data = outbuf;
5235 key.size = sizeof(int);
5236
5237 err = rdfstore_flat_store_fetch(me->subjects, key, &data);
5238 if (err != 0) {
5239 if (err != FLAT_STORE_E_NOTFOUND) {
5240 perror("rdfstore_remove");
5241 fprintf(stderr,"Could not fetch key '%s' for predicate in subjects table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->subjects));
5242 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5243 rdfstore_iterator_close(reindex);
5244 #endif
5245 return -1;
5246 } else {
5247 outsize = 0;
5248 };
5249 } else {
5250 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
5251 RDFSTORE_FREE(data.data);
5252 };
5253
5254 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5255 /*
5256 We need to re-index quite a lot for each new statement component now - hope caching will
5257 help here!! i.e. the swiss army nife problem (see SWAD-E paper and preso)
5258
5259 2.1) remove this new statement (st_id) from p_connections(neighbour->predicate) and o_connections(neighbour->object)
5260 tables of each other statement (neighbour) connected to this one via subjects(PREDICATE) node
5261 2.2) remove this new statement (st_id) from s_connections(neighbour->subject) and o_connections(neighbour->object)
5262 tables of each other statement (neighbour) connected to this one via predicates(PREDICATE) node
5263 2.3) remove this new statement (st_id) from s_connections(neighbour->subject) and p_connections(neighbour->predicate)
5264 tables of each other statement (neighbour) connected to this one via objects(PREDICATE) node
5265 */
5266
5267 /* 2.1) reindex st_id for connections to subjects(PREDICATE) node */
5268
5269 /* copy the subjects(PREDICATE) bits through the reindex iterator array */
5270 memcpy(reindex->ids, me->bits_decode, outsize);
5271 reindex->ids_size = outsize;
5272 /* set the size - inefficient!! */
5273 pos = 0;
5274 reindex->size = 0;
5275 /* count the ones (inefficient still) */
5276 while ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < 8 * outsize) {
5277 reindex->size++;
5278 pos++;
5279 };
5280
5281 /* scan the obtained iterator */
5282 while ( ( neighbour = rdfstore_iterator_each ( reindex ) ) != NULL ) {
5283
5284 #ifdef RDFSTORE_DEBUG_CONNECTIONS
5285 printf("(remove)REINDEXING predicate '%s' for connections to subjects('%s') node in st_id=%d\n",neighbour->predicate->value.resource.identifier,statement->predicate->value.resource.identifier,st_id);
5286 #endif
5287 neighbour->predicate->hashcode = rdfstore_digest_get_node_hashCode(neighbour->predicate, 0);
5288
5289 /* fetch p_connections(neighbour->predicate) */
5290 packInt(neighbour->predicate->hashcode, outbuf); /* wrong */
5291 key.data = outbuf;
5292 key.size = sizeof(int);
5293
5294 err = rdfstore_flat_store_fetch(me->p_connections, key, &data);
5295 if (err != 0) {
5296 if (err != FLAT_STORE_E_NOTFOUND) {
5297 perror("rdfstore_remove");
5298 fprintf(stderr,"Could not fetch key '%s' for predicate in p_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
5299 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5300 rdfstore_iterator_close(reindex);
5301 #endif
5302 return -1;
5303 } else {
5304 outsize_reindex = 0;
5305 };
5306 } else {
5307 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
5308 RDFSTORE_FREE(data.data);
5309 };
5310
5311 /* reset the corresponding bit of this statement */
5312 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 0, sizeof(reindex_decode));
5313
5314 /* store it back */
5315 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
5316
5317 data.data = reindex_encode;
5318 data.size = outsize_reindex;
5319 err = rdfstore_flat_store_store(me->p_connections, key, data);
5320 if (err != 0) {
5321 if (err != FLAT_STORE_E_KEYEXIST) {
5322 perror("rdfstore_remove");
5323 fprintf(stderr,"Could not store '%d' bytes for predicate in p_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
5324 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5325 rdfstore_iterator_close(reindex);
5326 #endif
5327 return -1;
5328 };
5329 };
5330
5331 #ifdef RDFSTORE_DEBUG_CONNECTIONS
5332 printf("(remove)REINDEXING object '%s' for connections to subjects('%s') node in st_id=%d\n",(neighbour->object->type==1) ? neighbour->object->value.literal.string : neighbour->object->value.resource.identifier,statement->predicate->value.resource.identifier,st_id);
5333 #endif
5334 neighbour->object->hashcode = rdfstore_digest_get_node_hashCode(neighbour->object, 0);
5335
5336 /* fetch o_connections(neighbour->object) */
5337 packInt(neighbour->object->hashcode, outbuf); /* wrong */
5338 key.data = outbuf;
5339 key.size = sizeof(int);
5340
5341 err = rdfstore_flat_store_fetch(me->o_connections, key, &data);
5342 if (err != 0) {
5343 if (err != FLAT_STORE_E_NOTFOUND) {
5344 perror("rdfstore_remove");
5345 fprintf(stderr,"Could not fetch key '%s' for object in o_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
5346 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5347 rdfstore_iterator_close(reindex);
5348 #endif
5349 return -1;
5350 } else {
5351 outsize_reindex = 0;
5352 };
5353 } else {
5354 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
5355 RDFSTORE_FREE(data.data);
5356 };
5357
5358 /* reset the corresponding bit of this statement */
5359 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 0, sizeof(reindex_decode));
5360
5361 /* store it back */
5362 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
5363
5364 /* now: we do not need/must check whther or not to remove this key because the other statement is sitll there */
5365
5366 data.data = reindex_encode;
5367 data.size = outsize_reindex;
5368 err = rdfstore_flat_store_store(me->o_connections, key, data);
5369 if (err != 0) {
5370 if (err != FLAT_STORE_E_KEYEXIST) {
5371 perror("rdfstore_remove");
5372 fprintf(stderr,"Could not store '%d' bytes for object in o_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
5373 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5374 rdfstore_iterator_close(reindex);
5375 #endif
5376 return -1;
5377 };
5378 };
5379
5380 /* free neighbour */
5381 RDFSTORE_FREE( neighbour->subject->value.resource.identifier );
5382 RDFSTORE_FREE( neighbour->subject );
5383 RDFSTORE_FREE( neighbour->predicate->value.resource.identifier );
5384 RDFSTORE_FREE( neighbour->predicate );
5385 if ( neighbour->object->type == 1 ) {
5386 if ( neighbour->object->value.literal.dataType != NULL )
5387 RDFSTORE_FREE( neighbour->object->value.literal.dataType );
5388 RDFSTORE_FREE( neighbour->object->value.literal.string );
5389 } else {
5390 RDFSTORE_FREE( neighbour->object->value.resource.identifier );
5391 };
5392 RDFSTORE_FREE( neighbour->object );
5393 if ( neighbour->context != NULL ) {
5394 RDFSTORE_FREE( neighbour->context->value.resource.identifier );
5395 RDFSTORE_FREE( neighbour->context );
5396 };
5397 if ( neighbour->node != NULL ) {
5398 RDFSTORE_FREE( neighbour->node->value.resource.identifier );
5399 RDFSTORE_FREE( neighbour->node );
5400 };
5401 RDFSTORE_FREE( neighbour );
5402 };
5403 #endif
5404
5405 /* OR subjects(PREDICATE) to s_connections(SUBJECT) */
5406 s_outsize = rdfstore_bits_or(outsize, me->bits_decode, s_outsize, s_connections, me->bits_encode);
5407 bcopy(me->bits_encode, s_connections, s_outsize); /* slow? */
5408
5409 /* fetch subjects(OBJECT) */
5410 packInt(statement->object->hashcode, outbuf);
5411 key.data = outbuf;
5412 key.size = sizeof(int);
5413
5414 err = rdfstore_flat_store_fetch(me->subjects, key, &data);
5415 if (err != 0) {
5416 if (err != FLAT_STORE_E_NOTFOUND) {
5417 perror("rdfstore_remove");
5418 fprintf(stderr,"Could not fetch key '%s' for object in subjects table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->subjects));
5419 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5420 rdfstore_iterator_close(reindex);
5421 #endif
5422 return -1;
5423 } else {
5424 outsize = 0;
5425 };
5426 } else {
5427 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
5428 RDFSTORE_FREE(data.data);
5429 };
5430
5431 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5432 /*
5433 We need to re-index quite a lot for each new statement component now - hope caching will
5434 help here!! i.e. the swiss army nife problem (see SWAD-E paper and preso)
5435
5436 3.1) remove this new statement (st_id) from p_connections(neighbour->predicate) and o_connections(neighbour->object)
5437 tables of each other statement (neighbour) connected to this one via subjects(OBJECT) node
5438 3.2) remove this new statement (st_id) from s_connections(neighbour->subject) and o_connections(neighbour->object)
5439 tables of each other statement (neighbour) connected to this one via predicates(OBJECT) node
5440 3.3) remove this new statement (st_id) from s_connections(neighbour->subject) and p_connections(neighbour->predicate)
5441 tables of each other statement (neighbour) connected to this one via objects(OBJECT) node
5442 */
5443
5444 /* 3.1) reindex st_id for connections to subjects(OBJECT) node */
5445
5446 /* copy the subjects(OBJECT) bits through the reindex iterator array */
5447 memcpy(reindex->ids, me->bits_decode, outsize);
5448 reindex->ids_size = outsize;
5449 /* set the size - inefficient!! */
5450 pos = 0;
5451 reindex->size = 0;
5452 /* count the ones (inefficient still) */
5453 while ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < 8 * outsize) {
5454 reindex->size++;
5455 pos++;
5456 };
5457
5458 /* scan the obtained iterator */
5459 while ( ( neighbour = rdfstore_iterator_each ( reindex ) ) != NULL ) {
5460
5461 #ifdef RDFSTORE_DEBUG_CONNECTIONS
5462 printf("(remove)REINDEXING predicate '%s' for connections to subjects('%s') node in st_id=%d\n",neighbour->predicate->value.resource.identifier,(statement->object->type==1) ? statement->object->value.literal.string : statement->object->value.resource.identifier,st_id);
5463 #endif
5464 neighbour->predicate->hashcode = rdfstore_digest_get_node_hashCode(neighbour->predicate, 0);
5465
5466 /* fetch p_connections(neighbour->predicate) */
5467 packInt(neighbour->predicate->hashcode, outbuf); /* wrong */
5468 key.data = outbuf;
5469 key.size = sizeof(int);
5470
5471 err = rdfstore_flat_store_fetch(me->p_connections, key, &data);
5472 if (err != 0) {
5473 if (err != FLAT_STORE_E_NOTFOUND) {
5474 perror("rdfstore_remove");
5475 fprintf(stderr,"Could not fetch key '%s' for predicate in p_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
5476 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5477 rdfstore_iterator_close(reindex);
5478 #endif
5479 return -1;
5480 } else {
5481 outsize_reindex = 0;
5482 };
5483 } else {
5484 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
5485 RDFSTORE_FREE(data.data);
5486 };
5487
5488 /* reset the corresponding bit of this statement */
5489 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 0, sizeof(reindex_decode));
5490
5491 /* store it back */
5492 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
5493
5494 data.data = reindex_encode;
5495 data.size = outsize_reindex;
5496 err = rdfstore_flat_store_store(me->p_connections, key, data);
5497 if (err != 0) {
5498 if (err != FLAT_STORE_E_KEYEXIST) {
5499 perror("rdfstore_remove");
5500 fprintf(stderr,"Could not store '%d' bytes for predicate in p_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
5501 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5502 rdfstore_iterator_close(reindex);
5503 #endif
5504 return -1;
5505 };
5506 };
5507
5508 #ifdef RDFSTORE_DEBUG_CONNECTIONS
5509 printf("(remove)REINDEXING object '%s' for connections to subjects('%s') node in st_id=%d\n",(neighbour->object->type==1) ? neighbour->object->value.literal.string : neighbour->object->value.resource.identifier,(statement->object->type==1) ? statement->object->value.literal.string : statement->object->value.resource.identifier,st_id);
5510 #endif
5511 neighbour->object->hashcode = rdfstore_digest_get_node_hashCode(neighbour->object, 0);
5512
5513 /* fetch o_connections(neighbour->object) */
5514 packInt(neighbour->object->hashcode, outbuf); /* wrong */
5515 key.data = outbuf;
5516 key.size = sizeof(int);
5517
5518 err = rdfstore_flat_store_fetch(me->o_connections, key, &data);
5519 if (err != 0) {
5520 if (err != FLAT_STORE_E_NOTFOUND) {
5521 perror("rdfstore_remove");
5522 fprintf(stderr,"Could not fetch key '%s' for object in o_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
5523 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5524 rdfstore_iterator_close(reindex);
5525 #endif
5526 return -1;
5527 } else {
5528 outsize_reindex = 0;
5529 };
5530 } else {
5531 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
5532 RDFSTORE_FREE(data.data);
5533 };
5534
5535 /* reset the corresponding bit of this statement */
5536 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 0, sizeof(reindex_decode));
5537
5538 /* store it back */
5539 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
5540
5541 /* now: we do not need/must check whther or not to remove this key because the other statement is sitll there */
5542
5543 data.data = reindex_encode;
5544 data.size = outsize_reindex;
5545 err = rdfstore_flat_store_store(me->o_connections, key, data);
5546 if (err != 0) {
5547 if (err != FLAT_STORE_E_KEYEXIST) {
5548 perror("rdfstore_remove");
5549 fprintf(stderr,"Could not store '%d' bytes for object in o_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
5550 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5551 rdfstore_iterator_close(reindex);
5552 #endif
5553 return -1;
5554 };
5555 };
5556
5557 /* free neighbour */
5558 RDFSTORE_FREE( neighbour->subject->value.resource.identifier );
5559 RDFSTORE_FREE( neighbour->subject );
5560 RDFSTORE_FREE( neighbour->predicate->value.resource.identifier );
5561 RDFSTORE_FREE( neighbour->predicate );
5562 if ( neighbour->object->type == 1 ) {
5563 if ( neighbour->object->value.literal.dataType != NULL )
5564 RDFSTORE_FREE( neighbour->object->value.literal.dataType );
5565 RDFSTORE_FREE( neighbour->object->value.literal.string );
5566 } else {
5567 RDFSTORE_FREE( neighbour->object->value.resource.identifier );
5568 };
5569 RDFSTORE_FREE( neighbour->object );
5570 if ( neighbour->context != NULL ) {
5571 RDFSTORE_FREE( neighbour->context->value.resource.identifier );
5572 RDFSTORE_FREE( neighbour->context );
5573 };
5574 if ( neighbour->node != NULL ) {
5575 RDFSTORE_FREE( neighbour->node->value.resource.identifier );
5576 RDFSTORE_FREE( neighbour->node );
5577 };
5578 RDFSTORE_FREE( neighbour );
5579 };
5580 #endif
5581
5582 /* OR subjects(OBJECT) to s_connections(SUBJECT) */
5583 s_outsize = rdfstore_bits_or(outsize, me->bits_decode, s_outsize, s_connections, me->bits_encode);
5584 bcopy(me->bits_encode, s_connections, s_outsize); /* slow? */
5585
5586 /* fetch predicates(SUBJECT) */
5587 packInt(statement->subject->hashcode, outbuf);
5588 key.data = outbuf;
5589 key.size = sizeof(int);
5590
5591 err = rdfstore_flat_store_fetch(me->predicates, key, &data);
5592 if (err != 0) {
5593 if (err != FLAT_STORE_E_NOTFOUND) {
5594 perror("rdfstore_remove");
5595 fprintf(stderr,"Could not fetch key '%s' for subject in predicates table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->predicates));
5596 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5597 rdfstore_iterator_close(reindex);
5598 #endif
5599 return -1;
5600 } else {
5601 outsize = 0;
5602 };
5603 } else {
5604 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
5605 RDFSTORE_FREE(data.data);
5606 };
5607
5608 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5609 /* 1.2) reindex st_id for connections to predicates(SUBJECT) node */
5610
5611 /* copy the predicates(SUBJECT) bits through the reindex iterator array */
5612 memcpy(reindex->ids, me->bits_decode, outsize);
5613 reindex->ids_size = outsize;
5614 /* set the size - inefficient!! */
5615 pos = 0;
5616 reindex->size = 0;
5617 /* count the ones (inefficient still) */
5618 while ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < 8 * outsize) {
5619 reindex->size++;
5620 pos++;
5621 };
5622
5623 /* scan the obtained iterator */
5624 while ( ( neighbour = rdfstore_iterator_each ( reindex ) ) != NULL ) {
5625
5626 #ifdef RDFSTORE_DEBUG_CONNECTIONS
5627 printf("(remove)REINDEXING subject '%s' for connections to predicates('%s') node in st_id=%d\n",neighbour->subject->value.resource.identifier,statement->subject->value.resource.identifier,st_id);
5628 #endif
5629 neighbour->subject->hashcode = rdfstore_digest_get_node_hashCode(neighbour->subject, 0);
5630
5631 /* fetch s_connections(neighbour->subject) */
5632 packInt(neighbour->subject->hashcode, outbuf); /* wrong */
5633 key.data = outbuf;
5634 key.size = sizeof(int);
5635
5636 err = rdfstore_flat_store_fetch(me->s_connections, key, &data);
5637 if (err != 0) {
5638 if (err != FLAT_STORE_E_NOTFOUND) {
5639 perror("rdfstore_remove");
5640 fprintf(stderr,"Could not fetch key '%s' for subject in s_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
5641 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5642 rdfstore_iterator_close(reindex);
5643 #endif
5644 return -1;
5645 } else {
5646 outsize_reindex = 0;
5647 };
5648 } else {
5649 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
5650 RDFSTORE_FREE(data.data);
5651 };
5652
5653 /* reset the corresponding bit of this statement */
5654 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 0, sizeof(reindex_decode));
5655
5656 /* store it back */
5657 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
5658
5659 data.data = reindex_encode;
5660 data.size = outsize_reindex;
5661 err = rdfstore_flat_store_store(me->s_connections, key, data);
5662 if (err != 0) {
5663 if (err != FLAT_STORE_E_KEYEXIST) {
5664 perror("rdfstore_remove");
5665 fprintf(stderr,"Could not store '%d' bytes for subject in s_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
5666 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5667 rdfstore_iterator_close(reindex);
5668 #endif
5669 return -1;
5670 };
5671 };
5672
5673 #ifdef RDFSTORE_DEBUG_CONNECTIONS
5674 printf("(remove)REINDEXING object '%s' for connections to predicates('%s') node in st_id=%d\n",(neighbour->object->type==1) ? neighbour->object->value.literal.string : neighbour->object->value.resource.identifier,statement->subject->value.resource.identifier,st_id);
5675 #endif
5676 neighbour->object->hashcode = rdfstore_digest_get_node_hashCode(neighbour->object, 0);
5677
5678 /* fetch o_connections(neighbour->object) */
5679 packInt(neighbour->object->hashcode, outbuf); /* wrong */
5680 key.data = outbuf;
5681 key.size = sizeof(int);
5682
5683 err = rdfstore_flat_store_fetch(me->o_connections, key, &data);
5684 if (err != 0) {
5685 if (err != FLAT_STORE_E_NOTFOUND) {
5686 perror("rdfstore_remove");
5687 fprintf(stderr,"Could not fetch key '%s' for object in o_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
5688 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5689 rdfstore_iterator_close(reindex);
5690 #endif
5691 return -1;
5692 } else {
5693 outsize_reindex = 0;
5694 };
5695 } else {
5696 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
5697 RDFSTORE_FREE(data.data);
5698 };
5699
5700 /* reset the corresponding bit of this statement */
5701 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 0, sizeof(reindex_decode));
5702
5703 /* store it back */
5704 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
5705
5706 data.data = reindex_encode;
5707 data.size = outsize_reindex;
5708 err = rdfstore_flat_store_store(me->o_connections, key, data);
5709 if (err != 0) {
5710 if (err != FLAT_STORE_E_KEYEXIST) {
5711 perror("rdfstore_remove");
5712 fprintf(stderr,"Could not store '%d' bytes for object in o_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
5713 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5714 rdfstore_iterator_close(reindex);
5715 #endif
5716 return -1;
5717 };
5718 };
5719
5720 /* free neighbour */
5721 RDFSTORE_FREE( neighbour->subject->value.resource.identifier );
5722 RDFSTORE_FREE( neighbour->subject );
5723 RDFSTORE_FREE( neighbour->predicate->value.resource.identifier );
5724 RDFSTORE_FREE( neighbour->predicate );
5725 if ( neighbour->object->type == 1 ) {
5726 if ( neighbour->object->value.literal.dataType != NULL )
5727 RDFSTORE_FREE( neighbour->object->value.literal.dataType );
5728 RDFSTORE_FREE( neighbour->object->value.literal.string );
5729 } else {
5730 RDFSTORE_FREE( neighbour->object->value.resource.identifier );
5731 };
5732 RDFSTORE_FREE( neighbour->object );
5733 if ( neighbour->context != NULL ) {
5734 RDFSTORE_FREE( neighbour->context->value.resource.identifier );
5735 RDFSTORE_FREE( neighbour->context );
5736 };
5737 if ( neighbour->node != NULL ) {
5738 RDFSTORE_FREE( neighbour->node->value.resource.identifier );
5739 RDFSTORE_FREE( neighbour->node );
5740 };
5741 RDFSTORE_FREE( neighbour );
5742 };
5743 #endif
5744
5745 /* OR predicates(SUBJECT) to p_connections(PREDICATE) */
5746 p_outsize = rdfstore_bits_or(outsize, me->bits_decode, p_outsize, p_connections, me->bits_encode);
5747 bcopy(me->bits_encode, p_connections, p_outsize); /* slow? */
5748
5749 /* fetch predicates(OBJECT) */
5750 packInt(statement->object->hashcode, outbuf);
5751 key.data = outbuf;
5752 key.size = sizeof(int);
5753
5754 err = rdfstore_flat_store_fetch(me->predicates, key, &data);
5755 if (err != 0) {
5756 if (err != FLAT_STORE_E_NOTFOUND) {
5757 perror("rdfstore_remove");
5758 fprintf(stderr,"Could not fetch key '%s' for object in predicates table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->predicates));
5759 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5760 rdfstore_iterator_close(reindex);
5761 #endif
5762 return -1;
5763 } else {
5764 outsize = 0;
5765 };
5766 } else {
5767 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
5768 RDFSTORE_FREE(data.data);
5769 };
5770
5771 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5772 /* 3.2) reindex st_id for connections to predicates(OBJECT) node */
5773
5774 /* copy the predicates(OBJECT) bits through the reindex iterator array */
5775 memcpy(reindex->ids, me->bits_decode, outsize);
5776 reindex->ids_size = outsize;
5777 /* set the size - inefficient!! */
5778 pos = 0;
5779 reindex->size = 0;
5780 /* count the ones (inefficient still) */
5781 while ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < 8 * outsize) {
5782 reindex->size++;
5783 pos++;
5784 };
5785
5786 /* scan the obtained iterator */
5787 while ( ( neighbour = rdfstore_iterator_each ( reindex ) ) != NULL ) {
5788
5789 #ifdef RDFSTORE_DEBUG_CONNECTIONS
5790 printf("(remove)REINDEXING subject '%s' for connections to predicates('%s') node in st_id=%d\n",neighbour->subject->value.resource.identifier,(statement->object->type==1) ? statement->object->value.literal.string : statement->object->value.resource.identifier,st_id);
5791 #endif
5792 neighbour->subject->hashcode = rdfstore_digest_get_node_hashCode(neighbour->subject, 0);
5793
5794 /* fetch s_connections(neighbour->subject) */
5795 packInt(neighbour->subject->hashcode, outbuf); /* wrong */
5796 key.data = outbuf;
5797 key.size = sizeof(int);
5798
5799 err = rdfstore_flat_store_fetch(me->s_connections, key, &data);
5800 if (err != 0) {
5801 if (err != FLAT_STORE_E_NOTFOUND) {
5802 perror("rdfstore_remove");
5803 fprintf(stderr,"Could not fetch key '%s' for subject in s_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
5804 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5805 rdfstore_iterator_close(reindex);
5806 #endif
5807 return -1;
5808 } else {
5809 outsize_reindex = 0;
5810 };
5811 } else {
5812 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
5813 RDFSTORE_FREE(data.data);
5814 };
5815
5816 /* reset the corresponding bit of this statement */
5817 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 0, sizeof(reindex_decode));
5818
5819 /* store it back */
5820 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
5821
5822 data.data = reindex_encode;
5823 data.size = outsize_reindex;
5824 err = rdfstore_flat_store_store(me->s_connections, key, data);
5825 if (err != 0) {
5826 if (err != FLAT_STORE_E_KEYEXIST) {
5827 perror("rdfstore_remove");
5828 fprintf(stderr,"Could not store '%d' bytes for subject in s_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
5829 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5830 rdfstore_iterator_close(reindex);
5831 #endif
5832 return -1;
5833 };
5834 };
5835
5836 #ifdef RDFSTORE_DEBUG_CONNECTIONS
5837 printf("(remove)REINDEXING object '%s' for connections to predicates('%s') node in st_id=%d\n",(neighbour->object->type==1) ? neighbour->object->value.literal.string : neighbour->object->value.resource.identifier,(statement->object->type==1) ? statement->object->value.literal.string : statement->object->value.resource.identifier,st_id);
5838 #endif
5839 neighbour->object->hashcode = rdfstore_digest_get_node_hashCode(neighbour->object, 0);
5840
5841 /* fetch o_connections(neighbour->object) */
5842 packInt(neighbour->object->hashcode, outbuf); /* wrong */
5843 key.data = outbuf;
5844 key.size = sizeof(int);
5845
5846 err = rdfstore_flat_store_fetch(me->o_connections, key, &data);
5847 if (err != 0) {
5848 if (err != FLAT_STORE_E_NOTFOUND) {
5849 perror("rdfstore_remove");
5850 fprintf(stderr,"Could not fetch key '%s' for object in o_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
5851 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5852 rdfstore_iterator_close(reindex);
5853 #endif
5854 return -1;
5855 } else {
5856 outsize_reindex = 0;
5857 };
5858 } else {
5859 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
5860 RDFSTORE_FREE(data.data);
5861 };
5862
5863 /* reset the corresponding bit of this statement */
5864 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 0, sizeof(reindex_decode));
5865
5866 /* store it back */
5867 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
5868
5869 data.data = reindex_encode;
5870 data.size = outsize_reindex;
5871 err = rdfstore_flat_store_store(me->o_connections, key, data);
5872 if (err != 0) {
5873 if (err != FLAT_STORE_E_KEYEXIST) {
5874 perror("rdfstore_remove");
5875 fprintf(stderr,"Could not store '%d' bytes for object in o_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
5876 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5877 rdfstore_iterator_close(reindex);
5878 #endif
5879 return -1;
5880 };
5881 };
5882
5883 /* free neighbour */
5884 RDFSTORE_FREE( neighbour->subject->value.resource.identifier );
5885 RDFSTORE_FREE( neighbour->subject );
5886 RDFSTORE_FREE( neighbour->predicate->value.resource.identifier );
5887 RDFSTORE_FREE( neighbour->predicate );
5888 if ( neighbour->object->type == 1 ) {
5889 if ( neighbour->object->value.literal.dataType != NULL )
5890 RDFSTORE_FREE( neighbour->object->value.literal.dataType );
5891 RDFSTORE_FREE( neighbour->object->value.literal.string );
5892 } else {
5893 RDFSTORE_FREE( neighbour->object->value.resource.identifier );
5894 };
5895 RDFSTORE_FREE( neighbour->object );
5896 if ( neighbour->context != NULL ) {
5897 RDFSTORE_FREE( neighbour->context->value.resource.identifier );
5898 RDFSTORE_FREE( neighbour->context );
5899 };
5900 if ( neighbour->node != NULL ) {
5901 RDFSTORE_FREE( neighbour->node->value.resource.identifier );
5902 RDFSTORE_FREE( neighbour->node );
5903 };
5904 RDFSTORE_FREE( neighbour );
5905 };
5906 #endif
5907
5908 /* OR predicates(OBJECT) to p_connections(PREDICATE) */
5909 p_outsize = rdfstore_bits_or(outsize, me->bits_decode, p_outsize, p_connections, me->bits_encode);
5910 bcopy(me->bits_encode, p_connections, p_outsize); /* slow? */
5911
5912 /* fetch objects(SUBJECT) */
5913 packInt(statement->subject->hashcode, outbuf);
5914 key.data = outbuf;
5915 key.size = sizeof(int);
5916
5917 err = rdfstore_flat_store_fetch(me->objects, key, &data);
5918 if (err != 0) {
5919 if (err != FLAT_STORE_E_NOTFOUND) {
5920 perror("rdfstore_remove");
5921 fprintf(stderr,"Could not fetch key '%s' for subject in objects table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->objects));
5922 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5923 rdfstore_iterator_close(reindex);
5924 #endif
5925 return -1;
5926 } else {
5927 outsize = 0;
5928 };
5929 } else {
5930 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
5931 RDFSTORE_FREE(data.data);
5932 };
5933
5934 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5935 /* 1.3) reindex st_id for connections to objects(SUBJECT) node */
5936
5937 /* copy the objects(SUBJECT) bits through the reindex iterator array */
5938 memcpy(reindex->ids, me->bits_decode, outsize);
5939 reindex->ids_size = outsize;
5940 /* set the size - inefficient!! */
5941 pos = 0;
5942 reindex->size = 0;
5943 /* count the ones (inefficient still) */
5944 while ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < 8 * outsize) {
5945 reindex->size++;
5946 pos++;
5947 };
5948
5949 /* scan the obtained iterator */
5950 while ( ( neighbour = rdfstore_iterator_each ( reindex ) ) != NULL ) {
5951
5952 #ifdef RDFSTORE_DEBUG_CONNECTIONS
5953 printf("(remove)REINDEXING subject '%s' for connections to objects('%s') node in st_id=%d\n",neighbour->subject->value.resource.identifier,statement->subject->value.resource.identifier,st_id);
5954 #endif
5955 neighbour->subject->hashcode = rdfstore_digest_get_node_hashCode(neighbour->subject, 0);
5956
5957 /* fetch s_connections(neighbour->subject) */
5958 packInt(neighbour->subject->hashcode, outbuf); /* wrong */
5959 key.data = outbuf;
5960 key.size = sizeof(int);
5961
5962 err = rdfstore_flat_store_fetch(me->s_connections, key, &data);
5963 if (err != 0) {
5964 if (err != FLAT_STORE_E_NOTFOUND) {
5965 perror("rdfstore_remove");
5966 fprintf(stderr,"Could not fetch key '%s' for subject in s_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
5967 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5968 rdfstore_iterator_close(reindex);
5969 #endif
5970 return -1;
5971 } else {
5972 outsize_reindex = 0;
5973 };
5974 } else {
5975 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
5976 RDFSTORE_FREE(data.data);
5977 };
5978
5979 /* reset the corresponding bit of this statement */
5980 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 0, sizeof(reindex_decode));
5981
5982 /* store it back */
5983 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
5984
5985 data.data = reindex_encode;
5986 data.size = outsize_reindex;
5987 err = rdfstore_flat_store_store(me->s_connections, key, data);
5988 if (err != 0) {
5989 if (err != FLAT_STORE_E_KEYEXIST) {
5990 perror("rdfstore_remove");
5991 fprintf(stderr,"Could not store '%d' bytes for subject in s_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
5992 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
5993 rdfstore_iterator_close(reindex);
5994 #endif
5995 return -1;
5996 };
5997 };
5998
5999 #ifdef RDFSTORE_DEBUG_CONNECTIONS
6000 printf("(remove)REINDEXING predicate '%s' for connections to objects('%s') node in st_id=%d\n",neighbour->predicate->value.resource.identifier,statement->subject->value.resource.identifier,st_id);
6001 #endif
6002 neighbour->predicate->hashcode = rdfstore_digest_get_node_hashCode(neighbour->predicate, 0);
6003
6004 /* fetch p_connections(neighbour->predicate) */
6005 packInt(neighbour->predicate->hashcode, outbuf); /* wrong */
6006 key.data = outbuf;
6007 key.size = sizeof(int);
6008
6009 err = rdfstore_flat_store_fetch(me->p_connections, key, &data);
6010 if (err != 0) {
6011 if (err != FLAT_STORE_E_NOTFOUND) {
6012 perror("rdfstore_remove");
6013 fprintf(stderr,"Could not fetch key '%s' for predicate in p_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
6014 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6015 rdfstore_iterator_close(reindex);
6016 #endif
6017 return -1;
6018 } else {
6019 outsize_reindex = 0;
6020 };
6021 } else {
6022 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
6023 RDFSTORE_FREE(data.data);
6024 };
6025
6026 /* reset the corresponding bit of this statement */
6027 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 0, sizeof(reindex_decode));
6028
6029 /* store it back */
6030 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
6031
6032 data.data = reindex_encode;
6033 data.size = outsize_reindex;
6034 err = rdfstore_flat_store_store(me->p_connections, key, data);
6035 if (err != 0) {
6036 if (err != FLAT_STORE_E_KEYEXIST) {
6037 perror("rdfstore_remove");
6038 fprintf(stderr,"Could not store '%d' bytes for predicate in p_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
6039 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6040 rdfstore_iterator_close(reindex);
6041 #endif
6042 return -1;
6043 };
6044 };
6045
6046 /* free neighbour */
6047 RDFSTORE_FREE( neighbour->subject->value.resource.identifier );
6048 RDFSTORE_FREE( neighbour->subject );
6049 RDFSTORE_FREE( neighbour->predicate->value.resource.identifier );
6050 RDFSTORE_FREE( neighbour->predicate );
6051 if ( neighbour->object->type == 1 ) {
6052 if ( neighbour->object->value.literal.dataType != NULL )
6053 RDFSTORE_FREE( neighbour->object->value.literal.dataType );
6054 RDFSTORE_FREE( neighbour->object->value.literal.string );
6055 } else {
6056 RDFSTORE_FREE( neighbour->object->value.resource.identifier );
6057 };
6058 RDFSTORE_FREE( neighbour->object );
6059 if ( neighbour->context != NULL ) {
6060 RDFSTORE_FREE( neighbour->context->value.resource.identifier );
6061 RDFSTORE_FREE( neighbour->context );
6062 };
6063 if ( neighbour->node != NULL ) {
6064 RDFSTORE_FREE( neighbour->node->value.resource.identifier );
6065 RDFSTORE_FREE( neighbour->node );
6066 };
6067 RDFSTORE_FREE( neighbour );
6068 };
6069 #endif
6070
6071 /* OR objects(SUBJECT) to o_connections(OBJECT) */
6072 o_outsize = rdfstore_bits_or(outsize, me->bits_decode, o_outsize, o_connections, me->bits_encode);
6073 bcopy(me->bits_encode, o_connections, o_outsize); /* slow? */
6074
6075 /* fetch objects(PREDICATE) */
6076 packInt(statement->predicate->hashcode, outbuf);
6077 key.data = outbuf;
6078 key.size = sizeof(int);
6079
6080 err = rdfstore_flat_store_fetch(me->objects, key, &data);
6081 if (err != 0) {
6082 if (err != FLAT_STORE_E_NOTFOUND) {
6083 perror("rdfstore_remove");
6084 fprintf(stderr,"Could not fetch key '%s' for predicate in objects table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->objects));
6085 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6086 rdfstore_iterator_close(reindex);
6087 #endif
6088 return -1;
6089 } else {
6090 outsize = 0;
6091 };
6092 } else {
6093 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
6094 RDFSTORE_FREE(data.data);
6095 };
6096
6097 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6098 /* 2.3) reindex st_id for connections to objects(PREDICATE) node */
6099
6100 /* copy the objects(PREDICATE) bits through the reindex iterator array */
6101 memcpy(reindex->ids, me->bits_decode, outsize);
6102 reindex->ids_size = outsize;
6103 /* set the size - inefficient!! */
6104 pos = 0;
6105 reindex->size = 0;
6106 /* count the ones (inefficient still) */
6107 while ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < 8 * outsize) {
6108 reindex->size++;
6109 pos++;
6110 };
6111
6112 /* scan the obtained iterator */
6113 while ( ( neighbour = rdfstore_iterator_each ( reindex ) ) != NULL ) {
6114
6115 #ifdef RDFSTORE_DEBUG_CONNECTIONS
6116 printf("(remove)REINDEXING subject '%s' for connections to objects('%s') node in st_id=%d\n",neighbour->subject->value.resource.identifier,statement->predicate->value.resource.identifier,st_id);
6117 #endif
6118 neighbour->subject->hashcode = rdfstore_digest_get_node_hashCode(neighbour->subject, 0);
6119
6120 /* fetch s_connections(neighbour->subject) */
6121 packInt(neighbour->subject->hashcode, outbuf); /* wrong */
6122 key.data = outbuf;
6123 key.size = sizeof(int);
6124
6125 err = rdfstore_flat_store_fetch(me->s_connections, key, &data);
6126 if (err != 0) {
6127 if (err != FLAT_STORE_E_NOTFOUND) {
6128 perror("rdfstore_remove");
6129 fprintf(stderr,"Could not fetch key '%s' for subject in s_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
6130 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6131 rdfstore_iterator_close(reindex);
6132 #endif
6133 return -1;
6134 } else {
6135 outsize_reindex = 0;
6136 };
6137 } else {
6138 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
6139 RDFSTORE_FREE(data.data);
6140 };
6141
6142 /* reset the corresponding bit of this statement */
6143 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 0, sizeof(reindex_decode));
6144
6145 /* store it back */
6146 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
6147
6148 data.data = reindex_encode;
6149 data.size = outsize_reindex;
6150 err = rdfstore_flat_store_store(me->s_connections, key, data);
6151 if (err != 0) {
6152 if (err != FLAT_STORE_E_KEYEXIST) {
6153 perror("rdfstore_remove");
6154 fprintf(stderr,"Could not store '%d' bytes for subject in s_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
6155 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6156 rdfstore_iterator_close(reindex);
6157 #endif
6158 return -1;
6159 };
6160 };
6161
6162 #ifdef RDFSTORE_DEBUG_CONNECTIONS
6163 printf("(remove)REINDEXING predicate '%s' for connections to objects('%s') node in st_id=%d\n",neighbour->predicate->value.resource.identifier,statement->predicate->value.resource.identifier,st_id);
6164 #endif
6165 neighbour->predicate->hashcode = rdfstore_digest_get_node_hashCode(neighbour->predicate, 0);
6166
6167 /* fetch p_connections(neighbour->predicate) */
6168 packInt(neighbour->predicate->hashcode, outbuf); /* wrong */
6169 key.data = outbuf;
6170 key.size = sizeof(int);
6171
6172 err = rdfstore_flat_store_fetch(me->p_connections, key, &data);
6173 if (err != 0) {
6174 if (err != FLAT_STORE_E_NOTFOUND) {
6175 perror("rdfstore_remove");
6176 fprintf(stderr,"Could not fetch key '%s' for predicate in p_connections table for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
6177 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6178 rdfstore_iterator_close(reindex);
6179 #endif
6180 return -1;
6181 } else {
6182 outsize_reindex = 0;
6183 };
6184 } else {
6185 me->func_decode_connections(data.size, data.data, &outsize_reindex, reindex_decode);
6186 RDFSTORE_FREE(data.data);
6187 };
6188
6189 /* reset the corresponding bit of this statement */
6190 rdfstore_bits_setmask(&outsize_reindex, reindex_decode, st_id, 1, 0, sizeof(reindex_decode));
6191
6192 /* store it back */
6193 me->func_encode_connections(outsize_reindex, reindex_decode, &outsize_reindex, reindex_encode);
6194
6195 data.data = reindex_encode;
6196 data.size = outsize_reindex;
6197 err = rdfstore_flat_store_store(me->p_connections, key, data);
6198 if (err != 0) {
6199 if (err != FLAT_STORE_E_KEYEXIST) {
6200 perror("rdfstore_remove");
6201 fprintf(stderr,"Could not store '%d' bytes for predicate in p_connections table for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
6202 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6203 rdfstore_iterator_close(reindex);
6204 #endif
6205 return -1;
6206 };
6207 };
6208
6209 /* free neighbour */
6210 RDFSTORE_FREE( neighbour->subject->value.resource.identifier );
6211 RDFSTORE_FREE( neighbour->subject );
6212 RDFSTORE_FREE( neighbour->predicate->value.resource.identifier );
6213 RDFSTORE_FREE( neighbour->predicate );
6214 if ( neighbour->object->type == 1 ) {
6215 if ( neighbour->object->value.literal.dataType != NULL )
6216 RDFSTORE_FREE( neighbour->object->value.literal.dataType );
6217 RDFSTORE_FREE( neighbour->object->value.literal.string );
6218 } else {
6219 RDFSTORE_FREE( neighbour->object->value.resource.identifier );
6220 };
6221 RDFSTORE_FREE( neighbour->object );
6222 if ( neighbour->context != NULL ) {
6223 RDFSTORE_FREE( neighbour->context->value.resource.identifier );
6224 RDFSTORE_FREE( neighbour->context );
6225 };
6226 if ( neighbour->node != NULL ) {
6227 RDFSTORE_FREE( neighbour->node->value.resource.identifier );
6228 RDFSTORE_FREE( neighbour->node );
6229 };
6230 RDFSTORE_FREE( neighbour );
6231 };
6232 #endif
6233
6234 /* OR objects(PREDICATE) to o_connections(OBJECT) */
6235 o_outsize = rdfstore_bits_or(outsize, me->bits_decode, o_outsize, o_connections, me->bits_encode);
6236 bcopy(me->bits_encode, o_connections, o_outsize); /* slow? */
6237
6238 /* SUBJECT - reset the right bits for s_connections - we need to AND s_connections(SUBJECT) with generated s_connections and store */
6239
6240 /* fetch s_connections(SUBJECT) */
6241 packInt(statement->subject->hashcode, outbuf);
6242 key.data = outbuf;
6243 key.size = sizeof(int);
6244
6245 err = rdfstore_flat_store_fetch(me->s_connections, key, &data);
6246 if (err != 0) {
6247 if (err != FLAT_STORE_E_NOTFOUND) {
6248 perror("rdfstore_remove");
6249 fprintf(stderr,"Could not fetch key '%s' for subject in s_connections for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
6250 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6251 rdfstore_iterator_close(reindex);
6252 #endif
6253 return -1;
6254 } else {
6255 outsize = 0;
6256 };
6257 } else {
6258 me->func_decode_connections(data.size, data.data, &outsize, me->bits_decode);
6259 RDFSTORE_FREE(data.data);
6260 };
6261
6262 /* AND s_connections(SUBJECT) to generated s_connections */
6263 outsize = rdfstore_bits_and(outsize, me->bits_decode, s_outsize, s_connections, me->bits_encode);
6264 bcopy(me->bits_encode, me->bits_decode, outsize); /* slow? */
6265
6266 outsize = rdfstore_bits_shorten(outsize, me->bits_decode);
6267 if ( outsize > 0 ) {
6268 me->func_encode_connections(outsize, me->bits_decode, &outsize, me->bits_encode);
6269 if (outsize) {
6270 data.data = me->bits_encode;
6271 data.size = outsize;
6272 err = rdfstore_flat_store_store(me->s_connections, key, data);
6273 if (err == 0) {
6274 #ifdef RDFSTORE_DEBUG_COMPRESSION
6275 fprintf(stderr,"Stored %d bytes for '%s' in s_connections for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
6276 #endif
6277 } else {
6278 if (err != FLAT_STORE_E_KEYEXIST) {
6279 perror("rdfstore_remove");
6280 fprintf(stderr,"Could not store '%d' bytes for subject in s_connections for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
6281 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6282 rdfstore_iterator_close(reindex);
6283 #endif
6284 return -1;
6285 };
6286 };
6287
6288 #ifdef RDFSTORE_DEBUG
6289 {
6290 int i=0;
6291 if ((rdfstore_flat_store_fetch(me->s_connections, key, &data)) == 0) {
6292 me->func_decode_connections(data.size, data.data, &outsize, me->bits_decode);
6293 RDFSTORE_FREE(data.data);
6294 };
6295 printf("REMOVED st_num=%d bitno=%d s_connections for S '%s' -->'", st_id, st_id,statement->subject->value.resource.identifier);
6296 for(i=0;i<8*outsize;i++) {
6297 printf("Rec %d %c\n", i, (me->bits_decode[i>>3] & (1<<(i&7))) ? '1':'0');
6298 };
6299 printf("'\n");
6300 }
6301 #endif
6302
6303 };
6304 } else {
6305 err = rdfstore_flat_store_delete(me->s_connections, key);
6306 if (err != 0) {
6307 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6308 rdfstore_iterator_close(reindex);
6309 #endif
6310 if (err != FLAT_STORE_E_NOTFOUND) {
6311 perror("rdfstore_remove");
6312 fprintf(stderr,"Could not delete statement for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->s_connections));
6313 return -1;
6314 } else {
6315 return 1;
6316 };
6317 };
6318 #ifdef RDFSTORE_DEBUG
6319 printf("DELETED (%d) s_connections for S '%s'\n", st_id,statement->subject->value.resource.identifier);
6320 #endif
6321 };
6322
6323 /* PREDICATE - reset the right bits for p_connections - we need to AND p_connections(PREDICATE) with generated p_connections and store */
6324
6325 /* fetch p_connections(PREDICATE) */
6326 packInt(statement->predicate->hashcode, outbuf);
6327 key.data = outbuf;
6328 key.size = sizeof(int);
6329
6330 err = rdfstore_flat_store_fetch(me->p_connections, key, &data);
6331 if (err != 0) {
6332 if (err != FLAT_STORE_E_NOTFOUND) {
6333 perror("rdfstore_remove");
6334 fprintf(stderr,"Could not fetch key '%s' for predicate in p_connections for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
6335 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6336 rdfstore_iterator_close(reindex);
6337 #endif
6338 return -1;
6339 } else {
6340 outsize = 0;
6341 };
6342 } else {
6343 me->func_decode_connections(data.size, data.data, &outsize, me->bits_decode);
6344 RDFSTORE_FREE(data.data);
6345 };
6346
6347 /* AND p_connections(PREDICATE) to generated p_connections */
6348 outsize = rdfstore_bits_and(outsize, me->bits_decode, p_outsize, p_connections, me->bits_encode);
6349 bcopy(me->bits_encode, me->bits_decode, outsize); /* slow? */
6350
6351 outsize = rdfstore_bits_shorten(outsize, me->bits_decode);
6352 if ( outsize > 0 ) {
6353 me->func_encode_connections(outsize, me->bits_decode, &outsize, me->bits_encode);
6354 if (outsize) {
6355 data.data = me->bits_encode;
6356 data.size = outsize;
6357 err = rdfstore_flat_store_store(me->p_connections, key, data);
6358 if (err == 0) {
6359 #ifdef RDFSTORE_DEBUG_COMPRESSION
6360 fprintf(stderr,"Stored %d bytes for '%s' in p_connections for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
6361 #endif
6362 } else {
6363 if (err != FLAT_STORE_E_KEYEXIST) {
6364 perror("rdfstore_remove");
6365 fprintf(stderr,"Could not store '%d' bytes for predicate in p_connections for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
6366 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6367 rdfstore_iterator_close(reindex);
6368 #endif
6369 return -1;
6370 };
6371 };
6372
6373 #ifdef RDFSTORE_DEBUG
6374 {
6375 int i=0;
6376 if ((rdfstore_flat_store_fetch(me->p_connections, key, &data)) == 0) {
6377 me->func_decode_connections(data.size, data.data, &outsize, me->bits_decode);
6378 RDFSTORE_FREE(data.data);
6379 };
6380 printf("REMOVED st_num=%d bitno=%d p_connections for P '%s' -->'", st_id, st_id, statement->predicate->value.resource.identifier);
6381 for(i=0;i<8*outsize;i++) {
6382 printf("Rec %d %c\n", i, (me->bits_decode[i>>3] & (1<<(i&7))) ? '1':'0');
6383 };
6384 printf("'\n");
6385 }
6386 #endif
6387
6388 };
6389 } else {
6390 err = rdfstore_flat_store_delete(me->p_connections, key);
6391 if (err != 0) {
6392 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6393 rdfstore_iterator_close(reindex);
6394 #endif
6395 if (err != FLAT_STORE_E_NOTFOUND) {
6396 perror("rdfstore_remove");
6397 fprintf(stderr,"Could not delete statement for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->p_connections));
6398 return -1;
6399 } else {
6400 return 1;
6401 };
6402 };
6403 #ifdef RDFSTORE_DEBUG
6404 printf("DELETED (%d) p_connections for P '%s'\n", st_id,statement->predicate->value.resource.identifier);
6405 #endif
6406 };
6407
6408 /* OBJECT - reset the right bits for o_connections - we need to AND o_connections(OBJECT) with generated o_connections and store */
6409
6410 /* fetch o_connections(OBJECT) */
6411 packInt(statement->object->hashcode, outbuf);
6412 key.data = outbuf;
6413 key.size = sizeof(int);
6414
6415 err = rdfstore_flat_store_fetch_compressed(me->o_connections, me->func_decode_connections, key, &outsize, me->bits_decode);
6416 if (err != 0) {
6417 if (err != FLAT_STORE_E_NOTFOUND) {
6418 perror("rdfstore_remove");
6419 fprintf(stderr,"Could not fetch key '%s' for object in o_connections for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
6420 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6421 rdfstore_iterator_close(reindex);
6422 #endif
6423 return -1;
6424 } else {
6425 outsize = 0;
6426 };
6427 };
6428
6429 /* AND o_connections(OBJECT) to generated o_connections */
6430 outsize = rdfstore_bits_and(outsize, me->bits_decode, o_outsize, o_connections, me->bits_encode);
6431 bcopy(me->bits_encode, me->bits_decode, outsize); /* slow? */
6432
6433 outsize = rdfstore_bits_shorten(outsize, me->bits_decode);
6434 if ( outsize > 0 ) {
6435 if (outsize) {
6436 err = rdfstore_flat_store_store_compressed(me->o_connections, me->func_encode_connections,
6437 key, outsize, me->bits_decode, me->bits_encode);
6438
6439 if (err == 0) {
6440 #ifdef RDFSTORE_DEBUG_COMPRESSION
6441 fprintf(stderr,"Stored %d bytes for '%s' in o_connections for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
6442 #endif
6443 } else {
6444 if (err != FLAT_STORE_E_KEYEXIST) {
6445 perror("rdfstore_remove");
6446 fprintf(stderr,"Could not store '%d' bytes for object in o_connections for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
6447 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6448 rdfstore_iterator_close(reindex);
6449 #endif
6450 return -1;
6451 };
6452 };
6453
6454 #ifdef RDFSTORE_DEBUG
6455 {
6456 int i=0;
6457 if ((rdfstore_flat_store_fetch(me->o_connections, key, &data)) == 0) {
6458 me->func_decode_connections(data.size, data.data, &outsize, me->bits_decode);
6459 RDFSTORE_FREE(data.data);
6460 };
6461 printf("REMOVED st_num=%d bitno=%d o_connections for O '%s' -->'", st_id, st_id, (statement->object->type != 1) ? statement->object->value.resource.identifier : statement->object->value.literal.string);
6462 for(i=0;i<8*outsize;i++) {
6463 printf("Rec %d %c\n", i, (me->bits_decode[i>>3] & (1<<(i&7))) ? '1':'0');
6464 };
6465 printf("'\n");
6466 }
6467 #endif
6468
6469 };
6470 } else {
6471 err = rdfstore_flat_store_delete(me->o_connections, key);
6472 if (err != 0) {
6473 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6474 rdfstore_iterator_close(reindex);
6475 #endif
6476 if (err != FLAT_STORE_E_NOTFOUND) {
6477 perror("rdfstore_remove");
6478 fprintf(stderr,"Could not delete statement for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->o_connections));
6479 return -1;
6480 } else {
6481 return 1;
6482 };
6483 };
6484 #ifdef RDFSTORE_DEBUG
6485 printf("DELETED (%d) o_connections for O '%s'\n", st_id, (statement->object->type != 1) ? statement->object->value.resource.identifier : statement->object->value.literal.string);
6486 #endif
6487 };
6488
6489 #endif /* RDFSTORE_CONNECTIONS */
6490
6491 if (context != NULL) {
6492 /* context */
6493 packInt(context->hashcode, outbuf);
6494 key.data = outbuf;
6495 key.size = sizeof(int);
6496
6497 /*
6498 * bzero(me->bits_encode,sizeof(me->bits_encode));
6499 * bzero(me->bits_decode,sizeof(me->bits_decode));
6500 */
6501
6502 err = rdfstore_flat_store_fetch_compressed(me->contexts, me->func_decode, key, &outsize, me->bits_decode);
6503 if (err != 0) {
6504 if (err != FLAT_STORE_E_NOTFOUND) {
6505 perror("rdfstore_remove");
6506 fprintf(stderr,"Could not fetch key '%s' in contexts for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->contexts));
6507 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6508 rdfstore_iterator_close(reindex);
6509 #endif
6510 return -1;
6511 } else {
6512 outsize = 0;
6513 };
6514 };
6515
6516 /* reset the right bit to zero */
6517 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 0, sizeof(me->bits_decode));
6518 outsize = rdfstore_bits_shorten(outsize, me->bits_decode);
6519 if ( outsize > 0 ) {
6520 err = rdfstore_flat_store_store_compressed(me->contexts, me->func_encode,
6521 key, outsize,me->bits_decode,me->bits_encode);
6522 if (err == 0) {
6523 #ifdef RDFSTORE_DEBUG_COMPRESSION
6524 fprintf(stderr,"Stored %d bytes for '%s' in contexts for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
6525 #endif
6526 } else {
6527 if (err != FLAT_STORE_E_KEYEXIST) {
6528 perror("rdfstore_remove");
6529 fprintf(stderr,"Could not store '%d' bytes in contexts for store '%s': %s\n", (int)data.size, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->contexts));
6530 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6531 rdfstore_iterator_close(reindex);
6532 #endif
6533 return -1;
6534 };
6535 };
6536
6537 #ifdef RDFSTORE_DEBUG
6538 {
6539 int i;
6540 if ((rdfstore_flat_store_fetch(me->contexts, key, &data)) == 0) {
6541 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
6542 RDFSTORE_FREE(data.data);
6543 };
6544 printf("REMOVED st_num=%d bitno=%d contexts for C -->'", st_id, st_id);
6545 for(i=0;i<8*outsize;i++) {
6546 printf("Rec %d %c\n", i, (me->bits_decode[i>>3] & (1<<(i&7))) ? '1':'0');
6547 };
6548 printf("'\n");
6549 }
6550 #endif
6551 } else {
6552 err = rdfstore_flat_store_delete(me->contexts, key);
6553 if (err != 0) {
6554 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6555 rdfstore_iterator_close(reindex);
6556 #endif
6557 if (err != FLAT_STORE_E_NOTFOUND) {
6558 perror("rdfstore_remove");
6559 fprintf(stderr,"Could not delete statement for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->contexts));
6560 return -1;
6561 } else {
6562 return 1;
6563 };
6564 };
6565 #ifdef RDFSTORE_DEBUG
6566 printf("DELETED (%d) contexts for C\n", st_id);
6567 #endif
6568 };
6569 };
6570
6571 /* remove special literal stuff */
6572 if (statement->object->type == 1) {
6573 if ( (me->freetext) &&
6574 (statement->object->value.literal.string != NULL) &&
6575 (statement->object->value.literal.string_len > 0) ) {
6576 utf8_casefolded_buff = (unsigned char *)RDFSTORE_MALLOC(statement->object->value.literal.string_len * sizeof(unsigned char) * (RDFSTORE_UTF8_MAXLEN_FOLD + 1)); /* what about the ending '\0' here ?? */
6577 if (utf8_casefolded_buff == NULL) {
6578 perror("rdfstore_remove");
6579 fprintf(stderr,"Cannot compute case-folded string out of input literal for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
6580 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6581 rdfstore_iterator_close(reindex);
6582 #endif
6583 return -1;
6584 };
6585 if (rdfstore_utf8_string_to_utf8_foldedcase(statement->object->value.literal.string_len, statement->object->value.literal.string, &utf8_size, utf8_casefolded_buff)) {
6586 perror("rdfstore_remove");
6587 fprintf(stderr,"Cannot compute case-folded string out of input literal for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
6588 RDFSTORE_FREE(utf8_casefolded_buff);
6589 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6590 rdfstore_iterator_close(reindex);
6591 #endif
6592 return -1;
6593 };
6594
6595 for ( word = strtok(utf8_casefolded_buff, sep);
6596 word;
6597 word = strtok(NULL, sep) ) {
6598 int jj=0;
6599 int kk=0;
6600
6601 key.data = word;
6602 key.size = strlen(word);
6603 err = rdfstore_flat_store_fetch_compressed(me->windex, me->func_decode, key, &outsize, me->bits_decode);
6604 if (err != 0) {
6605 if (err != FLAT_STORE_E_NOTFOUND) {
6606 RDFSTORE_FREE(utf8_casefolded_buff);
6607 perror("rdfstore_remove");
6608 fprintf(stderr,"Could not fetch windex of word '%s' for store '%s': %s\n", word, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->windex));
6609 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6610 rdfstore_iterator_close(reindex);
6611 #endif
6612 return -1;
6613 } else {
6614 outsize = 0;
6615 };
6616 };
6617
6618 /*
6619 NOTE: perhaps the code below should be substituted as in the above other single-bit tables with
6620
6621 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 0, sizeof(me->bits_decode));
6622
6623 outsize = rdfstore_bits_shorten(outsize, me->bits_decode);
6624 */
6625
6626 /*
6627 * match stuff for literal words - we have one bit
6628 * only for free-text then we use
6629 * rdfstore_bits_getfirstsetafter()
6630 */
6631 pos = 0;
6632 if ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < outsize * 8) /* matched once */
6633 pos++; /* hop to the next record */
6634 if ((pos < outsize * 8) &&
6635 ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < outsize * 8)) { /* matched more the one
6636 * record */
6637 #ifdef RDFSTORE_DEBUG
6638 fprintf(stderr,"object literal word '%s' matched TWICE at pos=%d\n", word, pos);
6639 #endif
6640 /* reset the right bit to zero */
6641 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 0, sizeof(me->bits_decode));
6642 if (outsize) {
6643 err = rdfstore_flat_store_store_compressed(me->windex, me->func_encode,key, outsize, me->bits_decode,me->bits_encode);
6644 if (err == 0) {
6645 #ifdef RDFSTORE_DEBUG_COMPRESSION
6646 fprintf(stderr,"Stored %d bytes for '%s' in windex for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
6647 #endif
6648 } else {
6649 if (err != FLAT_STORE_E_KEYEXIST) {
6650 RDFSTORE_FREE(utf8_casefolded_buff);
6651 perror("rdfstore_remove");
6652 fprintf(stderr,"Could not store '%d' bytes for word '%s' in windex for store '%s': %s\n", (int)data.size, word, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->windex));
6653 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6654 rdfstore_iterator_close(reindex);
6655 #endif
6656 return -1;
6657 };
6658 };
6659
6660 #ifdef RDFSTORE_DEBUG
6661 {
6662 int i;
6663 if ((rdfstore_flat_store_fetch(me->windex, key, &data)) == 0) {
6664 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
6665 RDFSTORE_FREE(data.data);
6666 };
6667 printf("REMOVED (%d) windex for case-folded word '%s' -->'", st_id, word);
6668 for(i=0;i<8*outsize;i++) {
6669 printf("Rec %d %c\n", i, (me->bits_decode[i>>3] & (1<<(i&7))) ? '1':'0');
6670 };
6671 printf("'\n");
6672 }
6673 #endif
6674
6675 };
6676 } else {
6677 err = rdfstore_flat_store_delete(me->windex, key);
6678 /* due that words and stems can be duplicated into the same literal we
6679 do not check if FLAT_STORE_E_NOTFOUND which means several delete operation might
6680 be failing for the same literal - this could be avoided by checking duplicates
6681 of words and stems into the input string */
6682 if (err != 0) {
6683 if (err != FLAT_STORE_E_NOTFOUND) {
6684 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6685 rdfstore_iterator_close(reindex);
6686 #endif
6687 perror("rdfstore_remove");
6688 fprintf(stderr,"Could not delete statement for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->windex));
6689 return -1;
6690 };
6691 };
6692 #ifdef RDFSTORE_DEBUG
6693 printf("DELETED (%d) windex for case-folded word '%s'\n", st_id, word);
6694 #endif
6695 };
6696
6697 #if RDFSTORE_WORD_STEMMING > 0
6698
6699 if( ( rdfstore_xsd_deserialize_integer( word, &thelval ) ) ||
6700 ( rdfstore_xsd_deserialize_double( word, &thedval ) ) ||
6701 ( rdfstore_xsd_deserialize_dateTime( word,
6702 &thedateval_tm ) ) ||
6703 ( rdfstore_xsd_deserialize_date( word,
6704 &thedateval_tm ) ) || /* dates are skipped, even if rdf:datatype is not set */
6705 (strlen(word)<=1) )
6706 continue;
6707
6708 /* for efficency we should check if the given partial stem has been already indexed for the same word!!! */
6709 jj=1;
6710 while ( ( jj < strlen(word) ) &&
6711 ( kk < RDFSTORE_WORD_STEMMING ) ) {
6712 char stem[MIN((RDFSTORE_WORD_STEMMING*RDFSTORE_UTF8_MAXLEN_FOLD),strlen(word))+1];
6713
6714 bzero(stem,MIN((RDFSTORE_WORD_STEMMING*RDFSTORE_UTF8_MAXLEN_FOLD),strlen(word))+1);
6715
6716 /* look for next utf8 char to add to stemming string */
6717 utf8_size=0;
6718 while ( ( jj < strlen(word) ) &&
6719 (!( rdfstore_utf8_is_utf8( word+jj, &utf8_size ) )) ) {
6720 jj++;
6721 };
6722
6723 if (jj>strlen(word)) {
6724 strncpy(stem, word, jj-1);
6725 } else {
6726 strncpy(stem, word, jj);
6727 };
6728
6729 key.data = stem;
6730 key.size = strlen(stem);
6731
6732 err = rdfstore_flat_store_fetch_compressed(me->windex, me->func_decode, key, &outsize, me->bits_decode);
6733 if (err != 0) {
6734 if (err != FLAT_STORE_E_NOTFOUND) {
6735 RDFSTORE_FREE(utf8_casefolded_buff);
6736 perror("rdfstore_remove");
6737 fprintf(stderr,"Could not fetch windex for stemming '%s' of word '%s' for store '%s': %s\n", stem, word, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->windex));
6738 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6739 rdfstore_iterator_close(reindex);
6740 #endif
6741 return -1;
6742 } else {
6743 outsize = 0;
6744 };
6745 };
6746 /*
6747 NOTE: perhaps the code below should be substituted as in the above other single-bit tables with
6748
6749 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 0, sizeof(me->bits_decode));
6750
6751 outsize = rdfstore_bits_shorten(outsize, me->bits_decode);
6752 */
6753
6754 /*
6755 * match stuff for literal words - we have one bit
6756 * only for free-text then we use
6757 * rdfstore_bits_getfirstsetafter()
6758 */
6759 pos = 0;
6760 if ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < outsize * 8) /* matched once */
6761 pos++; /* hop to the next record */
6762 if ((pos < outsize * 8) &&
6763 ((pos = rdfstore_bits_getfirstsetafter(outsize, me->bits_decode, pos)) < outsize * 8)) { /* matched more the one
6764 * record */
6765 #ifdef RDFSTORE_DEBUG
6766 fprintf(stderr,"object literal stem '%s' matched TWICE at pos=%d\n", word, pos);
6767 #endif
6768 /* reset the right bit to zero */
6769 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 0, sizeof(me->bits_decode));
6770 if (outsize) {
6771 err = rdfstore_flat_store_store_compressed(me->windex, me->func_encode,
6772 key, outsize, me->bits_decode, me->bits_encode);
6773 if (err == 0) {
6774 #ifdef RDFSTORE_DEBUG_COMPRESSION
6775 fprintf(stderr,"Stored %d bytes for stemming '%s' in windex for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
6776 #endif
6777 } else {
6778 if (err != FLAT_STORE_E_KEYEXIST) {
6779 RDFSTORE_FREE(utf8_casefolded_buff);
6780 perror("rdfstore_remove");
6781 fprintf(stderr,"Could not store '%d' bytes for stemming '%s' of word '%s' in windex for store '%s': %s\n", (int)data.size, stem, word, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->windex));
6782 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6783 rdfstore_iterator_close(reindex);
6784 #endif
6785 return -1;
6786 };
6787 };
6788
6789 #ifdef RDFSTORE_DEBUG
6790 {
6791 int i;
6792 if ((rdfstore_flat_store_fetch(me->windex, key, &data)) == 0) {
6793 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
6794 RDFSTORE_FREE(data.data);
6795 };
6796 printf("REMOVED (%d) windex for case-folded stemming '%s' of word '%s' -->'", st_id, stem, word);
6797 for (i = 0; i < outsize; i++) {
6798 printf("%02X", me->bits_decode[i]);
6799 };
6800 printf("'\n");
6801 }
6802 #endif
6803
6804 };
6805 } else {
6806 err = rdfstore_flat_store_delete(me->windex, key);
6807 if (err != 0) {
6808 /* due that words and stems can be duplicated into the same literal we
6809 do not check if FLAT_STORE_E_NOTFOUND which means several delete operation might
6810 be failing for the same literal - this could be avoided by checking duplicates
6811 of words and stems into the input string */
6812 if (err != FLAT_STORE_E_NOTFOUND) {
6813 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6814 rdfstore_iterator_close(reindex);
6815 #endif
6816 perror("rdfstore_remove");
6817 fprintf(stderr,"Could not delete statement for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->windex));
6818 return -1;
6819 };
6820 };
6821 #ifdef RDFSTORE_DEBUG
6822 printf("DELETED (%d) windex for case-folded stem '%s'\n", st_id, word);
6823 #endif
6824 };
6825 jj++;
6826 kk++;
6827 };
6828 #endif
6829
6830 };
6831 RDFSTORE_FREE(utf8_casefolded_buff);
6832 };
6833
6834 /* languages table */
6835 if ( (statement->object->value.literal.lang != NULL) &&
6836 (strlen(statement->object->value.literal.lang) > 0) ) {
6837 utf8_casefolded_buff = (unsigned char *)RDFSTORE_MALLOC(strlen(statement->object->value.literal.lang) * sizeof(unsigned char) * (RDFSTORE_UTF8_MAXLEN_FOLD + 1));
6838 if (utf8_casefolded_buff == NULL) {
6839 perror("rdfstore_remove");
6840 fprintf(stderr,"Cannot compute case-folded string out of input literal language for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
6841 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6842 rdfstore_iterator_close(reindex);
6843 #endif
6844 return -1;
6845 };
6846 if (rdfstore_utf8_string_to_utf8_foldedcase(strlen(statement->object->value.literal.lang), statement->object->value.literal.lang, &utf8_size, utf8_casefolded_buff)) {
6847 perror("rdfstore_remove");
6848 fprintf(stderr,"Cannot compute case-folded string out of input literal language for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
6849 RDFSTORE_FREE(utf8_casefolded_buff);
6850 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6851 rdfstore_iterator_close(reindex);
6852 #endif
6853 return -1;
6854 };
6855
6856 key.data = utf8_casefolded_buff;
6857 key.size = utf8_size;
6858
6859 err = rdfstore_flat_store_fetch_compressed(me->languages, me->func_decode, key, &outsize, me->bits_decode);
6860 if (err != 0) {
6861 if (err != FLAT_STORE_E_NOTFOUND) {
6862 RDFSTORE_FREE(utf8_casefolded_buff);
6863 perror("rdfstore_remove");
6864 fprintf(stderr,"Could not fetch language '%s' of literal '%s' for store '%s': %s\n", statement->object->value.literal.lang, statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->languages));
6865 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6866 rdfstore_iterator_close(reindex);
6867 #endif
6868 return -1;
6869 } else {
6870 outsize = 0;
6871 };
6872 };
6873
6874 /* reset the right bit to zero */
6875 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 0, sizeof(me->bits_decode));
6876
6877 outsize = rdfstore_bits_shorten(outsize, me->bits_decode);
6878 if (outsize) {
6879 err = rdfstore_flat_store_store_compressed(me->languages, me->func_encode,
6880 key, outsize, me->bits_decode, me->bits_encode);
6881 if (err == 0) {
6882 #ifdef RDFSTORE_DEBUG_COMPRESSION
6883 fprintf(stderr,"Stored %d bytes for language '%s' in languages for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
6884 #endif
6885 } else {
6886 if (err != FLAT_STORE_E_KEYEXIST) {
6887 RDFSTORE_FREE(utf8_casefolded_buff);
6888 perror("rdfstore_remove");
6889 fprintf(stderr,"Could not store '%d' bytes for language '%s' of literal '%s' in languages for store '%s': %s\n", (int)data.size, statement->object->value.literal.lang, statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->languages));
6890 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6891 rdfstore_iterator_close(reindex);
6892 #endif
6893 return -1;
6894 };
6895 };
6896
6897 #ifdef RDFSTORE_DEBUG
6898 {
6899 int i;
6900 if ((rdfstore_flat_store_fetch(me->languages, key, &data)) == 0) {
6901 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
6902 RDFSTORE_FREE(data.data);
6903 };
6904 printf("REMOVED (%d) language '%s' of literal '%s' -->'", st_id, statement->object->value.literal.lang, statement->object->value.literal.string);
6905 for (i = 0; i < outsize; i++) {
6906 printf("%02X", me->bits_decode[i]);
6907 };
6908 printf("'\n");
6909 }
6910 #endif
6911 } else {
6912 err = rdfstore_flat_store_delete(me->languages, key);
6913 if (err != 0) {
6914 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6915 rdfstore_iterator_close(reindex);
6916 #endif
6917 if (err != FLAT_STORE_E_NOTFOUND) {
6918 perror("rdfstore_remove");
6919 fprintf(stderr,"Could not delete statement for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->languages));
6920 return -1;
6921 } else {
6922 return 1;
6923 };
6924 };
6925 #ifdef RDFSTORE_DEBUG
6926 printf("DELETED (%d) languages for case-folded literal language '%s'\n", st_id, statement->object->value.literal.lang);
6927 #endif
6928 };
6929
6930 RDFSTORE_FREE(utf8_casefolded_buff);
6931 };
6932
6933 /* datatypes table */
6934 if ( (statement->object->value.literal.dataType != NULL) &&
6935 (strlen(statement->object->value.literal.dataType) > 0) ) {
6936 key.data = statement->object->value.literal.dataType;
6937 key.size = strlen(statement->object->value.literal.dataType);
6938
6939 err = rdfstore_flat_store_fetch_compressed(me->datatypes, me->func_decode, key, &outsize, me->bits_decode);
6940 if (err != 0) {
6941 if (err != FLAT_STORE_E_NOTFOUND) {
6942 perror("rdfstore_remove");
6943 fprintf(stderr,"Could not fetch datatype '%s' of literal '%s' for store '%s': %s\n", statement->object->value.literal.dataType, statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->datatypes));
6944 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6945 rdfstore_iterator_close(reindex);
6946 #endif
6947 return -1;
6948 } else {
6949 outsize = 0;
6950 };
6951 };
6952
6953 /* reset the right bit to zero */
6954 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 0, sizeof(me->bits_decode));
6955
6956 outsize = rdfstore_bits_shorten(outsize, me->bits_decode);
6957 if (outsize) {
6958 err = rdfstore_flat_store_store_compressed(me->datatypes, me->func_encode,
6959 key, outsize, me->bits_decode, me->bits_encode);
6960 if (err == 0) {
6961 #ifdef RDFSTORE_DEBUG_COMPRESSION
6962 fprintf(stderr,"Stored %d bytes for datatype '%s' in datatypes for store '%s'\n", outsize, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)");
6963 #endif
6964 } else {
6965 if (err != FLAT_STORE_E_KEYEXIST) {
6966 perror("rdfstore_remove");
6967 fprintf(stderr,"Could not store '%d' bytes for datatype '%s' of literal '%s' in datatypes for store '%s': %s\n", (int)data.size, statement->object->value.literal.dataType, statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->datatypes));
6968 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6969 rdfstore_iterator_close(reindex);
6970 #endif
6971 return -1;
6972 };
6973 };
6974
6975 #ifdef RDFSTORE_DEBUG
6976 {
6977 int i;
6978 if ((rdfstore_flat_store_fetch(me->datatypes, key, &data)) == 0) {
6979 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
6980 RDFSTORE_FREE(data.data);
6981 };
6982 printf("REMOVED (%d) datatype '%s' of literal '%s' -->'", st_id, statement->object->value.literal.dataType, statement->object->value.literal.string);
6983 for (i = 0; i < outsize; i++) {
6984 printf("%02X", me->bits_decode[i]);
6985 };
6986 printf("'\n");
6987 }
6988 #endif
6989 } else {
6990 err = rdfstore_flat_store_delete(me->datatypes, key);
6991 if (err != 0) {
6992 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
6993 rdfstore_iterator_close(reindex);
6994 #endif
6995 if (err != FLAT_STORE_E_NOTFOUND) {
6996 perror("rdfstore_remove");
6997 fprintf(stderr,"Could not delete statement for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->datatypes));
6998 return -1;
6999 } else {
7000 return 1;
7001 };
7002 };
7003 #ifdef RDFSTORE_DEBUG
7004 printf("DELETED (%d) datatypes literal datatype '%s'\n", st_id, statement->object->value.literal.dataType);
7005 #endif
7006 };
7007
7008 /* date type indexing only if rdf:datatype is set accordingly to xsd:date or xsd:dateTime */
7009 if( (strcmp(statement->object->value.literal.dataType,RDFSTORE_MS_XSD_DATE)==0) ||
7010 (strcmp(statement->object->value.literal.dataType,RDFSTORE_MS_XSD_DATETIME)==0) ) {
7011 if( ( rdfstore_xsd_deserialize_dateTime( statement->object->value.literal.string,
7012 &thedateval_tm ) ) ||
7013 ( rdfstore_xsd_deserialize_date( statement->object->value.literal.string,
7014 &thedateval_tm ) ) ) {
7015
7016 rdfstore_xsd_serialize_dateTime( thedateval_tm, thedateval ); /* we index xsd:dataTime version anyway */
7017
7018 key.data = thedateval;
7019 key.size = strlen(thedateval)+1;
7020
7021 #ifdef RDFSTORE_DEBUG
7022 fprintf(stderr, "REMOVE DATE '%s' for LITERAL '%s' \n", thedateval, statement->object->value.literal.string);
7023 #endif
7024
7025 err = rdfstore_flat_store_fetch_compressed(me->xsd_date, me->func_decode, key, &outsize, me->bits_decode);
7026 if (err != 0) {
7027 if (err != FLAT_STORE_E_NOTFOUND) {
7028 perror("rdfstore_remove");
7029 fprintf(stderr,"Could not fetch date '%ld' of literal '%s' for store '%s': %s\n", thedateval, statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->xsd_date));
7030 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
7031 rdfstore_iterator_close(reindex);
7032 #endif
7033 return -1;
7034 } else {
7035 outsize = 0;
7036 };
7037 };
7038
7039 /* reset the right bit to zero */
7040 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 0, sizeof(me->bits_decode));
7041
7042 outsize = rdfstore_bits_shorten(outsize, me->bits_decode);
7043 if (outsize) {
7044 err = rdfstore_flat_store_store_compressed(me->xsd_date, me->func_encode,
7045 key, outsize, me->bits_decode, me->bits_encode);
7046 if (err == 0) {
7047 #ifdef RDFSTORE_DEBUG_COMPRESSION
7048 fprintf(stderr,"Stored %d bytes for date '%s' in date table for store '%s'\n", outsize, thedateval, (me->name != NULL) ? me->name : "(in-memory)");
7049 #endif
7050 } else {
7051 if (err != FLAT_STORE_E_KEYEXIST) {
7052 perror("rdfstore_remove");
7053 fprintf(stderr,"Could not store '%d' bytes for date '%s' of literal '%s' in date table for store '%s': %s\n", (int)data.size, thedateval, statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->xsd_date));
7054 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
7055 rdfstore_iterator_close(reindex);
7056 #endif
7057 return -1;
7058 };
7059 };
7060
7061 #ifdef RDFSTORE_DEBUG
7062 {
7063 int i;
7064 if ((rdfstore_flat_store_fetch(me->xsd_date, key, &data)) == 0) {
7065 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
7066 RDFSTORE_FREE(data.data);
7067 };
7068 printf("REMOVED (%d) date '%s' of literal '%s' -->'", st_id, thedateval, statement->object->value.literal.string);
7069 for (i = 0; i < outsize; i++) {
7070 printf("%02X", me->bits_decode[i]);
7071 };
7072 printf("'\n");
7073 }
7074 #endif
7075 } else {
7076 err = rdfstore_flat_store_delete(me->xsd_date, key);
7077 if (err != 0) {
7078 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
7079 rdfstore_iterator_close(reindex);
7080 #endif
7081 if (err != FLAT_STORE_E_NOTFOUND) {
7082 perror("rdfstore_remove");
7083 fprintf(stderr,"Could not delete statement for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->xsd_date));
7084 return -1;
7085 } else {
7086 return 1;
7087 };
7088 };
7089 #ifdef RDFSTORE_DEBUG
7090 printf("DELETED (%d) date table date '%s'\n", st_id, thedateval);
7091 #endif
7092 };
7093 };
7094 }; /* end of date indexing */
7095
7096 };
7097
7098 /* for xsd:integer alike literals use special b-tree sorted index if strtol() works.... */
7099 if( ( islval = rdfstore_xsd_deserialize_integer( statement->object->value.literal.string, &thelval ) ) != 0 ) {
7100 key.data = (long*) &thelval; /* should pack int perhaps... */
7101 key.size = sizeof(long);
7102
7103 #ifdef RDFSTORE_DEBUG
7104 fprintf(stderr, "REMOVE INTEGER '%ld' for LITERAL '%s' \n",(long)thelval, statement->object->value.literal.string);
7105 #endif
7106
7107 err = rdfstore_flat_store_fetch_compressed(me->xsd_integer, me->func_decode, key, &outsize, me->bits_decode);
7108 if (err != 0) {
7109 if (err != FLAT_STORE_E_NOTFOUND) {
7110 perror("rdfstore_remove");
7111 fprintf(stderr,"Could not fetch integer '%ld' of literal '%s' for store '%s': %s\n", (long)thelval, statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->xsd_integer));
7112 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
7113 rdfstore_iterator_close(reindex);
7114 #endif
7115 return -1;
7116 } else {
7117 outsize = 0;
7118 };
7119 };
7120
7121 /* reset the right bit to zero */
7122 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 0, sizeof(me->bits_decode));
7123
7124 outsize = rdfstore_bits_shorten(outsize, me->bits_decode);
7125 if (outsize) {
7126 err = rdfstore_flat_store_store_compressed(me->xsd_integer, me->func_encode,
7127 key, outsize, me->bits_decode, me->bits_encode);
7128 if (err == 0) {
7129 #ifdef RDFSTORE_DEBUG_COMPRESSION
7130 fprintf(stderr,"Stored %d bytes for integer '%ld' in integer table for store '%s'\n", outsize, (long)thelval, (me->name != NULL) ? me->name : "(in-memory)");
7131 #endif
7132 } else {
7133 if (err != FLAT_STORE_E_KEYEXIST) {
7134 perror("rdfstore_remove");
7135 fprintf(stderr,"Could not store '%d' bytes for integer '%ld' of literal '%s' in integer table for store '%s': %s\n", (int)data.size, (long)thelval, statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->xsd_integer));
7136 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
7137 rdfstore_iterator_close(reindex);
7138 #endif
7139 return -1;
7140 };
7141 };
7142
7143 #ifdef RDFSTORE_DEBUG
7144 {
7145 int i;
7146 if ((rdfstore_flat_store_fetch(me->xsd_integer, key, &data)) == 0) {
7147 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
7148 RDFSTORE_FREE(data.data);
7149 };
7150 printf("REMOVED (%d) integer '%ld' of literal '%s' -->'", st_id, (long)thelval, statement->object->value.literal.string);
7151 for (i = 0; i < outsize; i++) {
7152 printf("%02X", me->bits_decode[i]);
7153 };
7154 printf("'\n");
7155 }
7156 #endif
7157 } else {
7158 err = rdfstore_flat_store_delete(me->xsd_integer, key);
7159 if (err != 0) {
7160 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
7161 rdfstore_iterator_close(reindex);
7162 #endif
7163 if (err != FLAT_STORE_E_NOTFOUND) {
7164 perror("rdfstore_remove");
7165 fprintf(stderr,"Could not delete statement for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->xsd_integer));
7166 return -1;
7167 } else {
7168 return 1;
7169 };
7170 };
7171 #ifdef RDFSTORE_DEBUG
7172 printf("DELETED (%d) integer table integer '%ld'\n", st_id, (long)thelval);
7173 #endif
7174 };
7175 };
7176
7177 /* for xsd:double or xsd:float alike literals use special b-tree sorted index if strtod() works.... */
7178 if( ( islval == 0 ) && /* do not index xsd:integer(s) twice also as xsd:double */
7179 ( ( isdval = rdfstore_xsd_deserialize_double( statement->object->value.literal.string, &thedval ) ) != 0 ) ) {
7180 key.data = (double*) &thedval; /* should pack int perhaps... */
7181 key.size = sizeof(double);
7182
7183 #ifdef RDFSTORE_DEBUG
7184 fprintf(stderr, "REMOVE DOUBLE '%f' for LITERAL '%s' \n",thedval, statement->object->value.literal.string);
7185 #endif
7186
7187 err = rdfstore_flat_store_fetch_compressed(me->xsd_double, me->func_decode, key, &outsize, me->bits_decode);
7188 if (err != 0) {
7189 if (err != FLAT_STORE_E_NOTFOUND) {
7190 perror("rdfstore_remove");
7191 fprintf(stderr,"Could not fetch double '%f' of literal '%s' for store '%s': %s\n", thedval, statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->xsd_double));
7192 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
7193 rdfstore_iterator_close(reindex);
7194 #endif
7195 return -1;
7196 } else {
7197 outsize = 0;
7198 };
7199 };
7200
7201 /* reset the right bit to zero */
7202 rdfstore_bits_setmask(&outsize, me->bits_decode, st_id, 1, 0, sizeof(me->bits_decode));
7203
7204 outsize = rdfstore_bits_shorten(outsize, me->bits_decode);
7205 if (outsize) {
7206 err = rdfstore_flat_store_store_compressed(me->xsd_double, me->func_encode,
7207 key, outsize, me->bits_decode, me->bits_encode);
7208 if (err == 0) {
7209 #ifdef RDFSTORE_DEBUG_COMPRESSION
7210 fprintf(stderr,"Stored %d bytes for double '%f' in double table for store '%s'\n", outsize, thedval, (me->name != NULL) ? me->name : "(in-memory)");
7211 #endif
7212 } else {
7213 if (err != FLAT_STORE_E_KEYEXIST) {
7214 perror("rdfstore_remove");
7215 fprintf(stderr,"Could not store '%d' bytes for double '%f' of literal '%s' in double table for store '%s': %s\n", (int)data.size, thedval, statement->object->value.literal.string, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->xsd_double));
7216 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
7217 rdfstore_iterator_close(reindex);
7218 #endif
7219 return -1;
7220 };
7221 };
7222
7223 #ifdef RDFSTORE_DEBUG
7224 {
7225 int i;
7226 if ((rdfstore_flat_store_fetch(me->xsd_double, key, &data)) == 0) {
7227 me->func_decode(data.size, data.data, &outsize, me->bits_decode);
7228 RDFSTORE_FREE(data.data);
7229 };
7230 printf("REMOVED (%d) double '%f' of literal '%s' -->'", st_id, thedval, statement->object->value.literal.string);
7231 for (i = 0; i < outsize; i++) {
7232 printf("%02X", me->bits_decode[i]);
7233 };
7234 printf("'\n");
7235 }
7236 #endif
7237 } else {
7238 err = rdfstore_flat_store_delete(me->xsd_double, key);
7239 if (err != 0) {
7240 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
7241 rdfstore_iterator_close(reindex);
7242 #endif
7243 if (err != FLAT_STORE_E_NOTFOUND) {
7244 perror("rdfstore_remove");
7245 fprintf(stderr,"Could not delete statement for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->xsd_double));
7246 return -1;
7247 } else {
7248 return 1;
7249 };
7250 };
7251 #ifdef RDFSTORE_DEBUG
7252 printf("DELETED (%d) double table double '%f'\n", st_id, thedval);
7253 #endif
7254 };
7255 };
7256
7257 }; /* end remove special literal stuff */
7258
7259 /* removed one statement */
7260 key.data = RDFSTORE_COUNTER_REMOVED_KEY;
7261 key.size = sizeof(RDFSTORE_COUNTER_REMOVED_KEY);
7262 if ((rdfstore_flat_store_inc(me->model, key, &data)) != 0) {
7263 perror("rdfstore_remove");
7264 fprintf(stderr,"Could not decrement statement counter for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->model));
7265 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
7266 rdfstore_iterator_close(reindex);
7267 #endif
7268 return -1;
7269 };
7270 RDFSTORE_FREE(data.data);
7271
7272 /* delete the statement internal identifier */
7273 packInt(hc, outbuf);
7274 key.data = outbuf;
7275 key.size = sizeof(int);
7276 err = rdfstore_flat_store_delete(me->statements, key);
7277 if (err != 0) {
7278 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
7279 rdfstore_iterator_close(reindex);
7280 #endif
7281 if (err != FLAT_STORE_E_NOTFOUND) {
7282 perror("rdfstore_remove");
7283 fprintf(stderr,"Could not delete statement for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->statements));
7284 return -1;
7285 } else {
7286 return 1;
7287 };
7288 } else {
7289 /* touch DB last modified date */
7290 bzero(&thedateval_tm, sizeof( struct tm ) );
7291
7292 time(&now);
7293
7294 ptm = gmtime(&now);
7295 memcpy(&thedateval_tm, ptm, sizeof(struct tm));
7296
7297 rdfstore_xsd_serialize_dateTime( thedateval_tm, thedateval );
7298
7299 key.data = RDFSTORE_LASTMODIFIED_KEY;
7300 key.size = sizeof(RDFSTORE_LASTMODIFIED_KEY);
7301
7302 data.data = thedateval;
7303 data.size = strlen(thedateval) + 1;
7304
7305 err = rdfstore_flat_store_store(me->model, key, data);
7306 if ( (err != 0) &&
7307 (err != FLAT_STORE_E_KEYEXIST) ) {
7308 perror("rdfstore_remove");
7309 fprintf(stderr,"Could not store last modified date in model for store '%s': %s\n", (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->model));
7310 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
7311 rdfstore_iterator_close(reindex);
7312 #endif
7313 return -1;
7314 };
7315 };
7316
7317 if ((me->sync) &&
7318 (!(me->flag))) {
7319 /* sync :( */
7320 rdfstore_flat_store_sync(me->model);
7321 rdfstore_flat_store_sync(me->nodes);
7322 rdfstore_flat_store_sync(me->subjects);
7323 rdfstore_flat_store_sync(me->predicates);
7324 rdfstore_flat_store_sync(me->objects);
7325 if (context != NULL)
7326 rdfstore_flat_store_sync(me->contexts);
7327 #ifdef RDFSTORE_CONNECTIONS
7328 if (me->s_connections)
7329 rdfstore_flat_store_sync(me->s_connections);
7330 if (me->p_connections)
7331 rdfstore_flat_store_sync(me->p_connections);
7332 if (me->o_connections)
7333 rdfstore_flat_store_sync(me->o_connections);
7334 #endif
7335 if (me->languages)
7336 rdfstore_flat_store_sync(me->languages);
7337 if (me->datatypes)
7338 rdfstore_flat_store_sync(me->datatypes);
7339 if (me->xsd_integer)
7340 rdfstore_flat_store_sync(me->xsd_integer);
7341 if (me->xsd_double)
7342 rdfstore_flat_store_sync(me->xsd_double);
7343 if (me->xsd_date)
7344 rdfstore_flat_store_sync(me->xsd_date);
7345 if (me->freetext)
7346 rdfstore_flat_store_sync(me->windex);
7347 };
7348
7349 #if defined(RDFSTORE_CONNECTIONS) && defined(RDFSTORE_CONNECTIONS_REINDEXING)
7350 rdfstore_iterator_close(reindex);
7351 #endif
7352
7353 return 0;
7354 };
7355
7356 rdfstore_iterator *
rdfstore_search(rdfstore * me,RDF_Triple_Pattern * tp,int search_type)7357 rdfstore_search(rdfstore * me, RDF_Triple_Pattern * tp, int search_type) {
7358 RDF_Triple_Pattern_Part * tpj=NULL;
7359 rdfstore_iterator *results;
7360 DBT key, data;
7361 int err = 0;
7362 unsigned char *utf8_casefolded_buff; /* dyn alloc for saving
7363 * memory */
7364 unsigned int utf8_size = 0;
7365
7366 /* bear in mind that with a single nindex table these index tables should be bigger than this! (RDFSTORE_MAXRECORDS*NUM_BITS_IN_TABLE) */
7367 static unsigned char bits[RDFSTORE_MAXRECORDS_BYTES_SIZE]; /* for logical
7368 * operations -
7369 * expensive to
7370 * allocate??? */
7371 static unsigned char bits1[RDFSTORE_MAXRECORDS_BYTES_SIZE]; /* general temporary */
7372 static unsigned char bits2[RDFSTORE_MAXRECORDS_BYTES_SIZE]; /* temporary for OR of s,p,o,c */
7373 unsigned int outsize1 = 0;
7374 unsigned int outsize2 = 0;
7375 unsigned int outsize3 = 0;
7376 unsigned int pos = 0;
7377 unsigned char outbuf[256];
7378
7379 /* expensive :-(( - calloc() would help here perhaps */
7380 bzero(bits, sizeof(bits));
7381 bzero(bits1, sizeof(bits1));
7382 bzero(bits2, sizeof(bits2));
7383
7384 /* check inputs */
7385 if (tp != NULL) {
7386 if ( tp->subjects != NULL ) {
7387 tpj = tp->subjects;
7388 do {
7389 if ( tpj->type != RDFSTORE_TRIPLE_PATTERN_PART_RESOURCE_NODE )
7390 return NULL;
7391 } while ( ( tpj = tpj->next ) != NULL );
7392
7393 if ( (tp->subjects_operator < 0) ||
7394 (tp->subjects_operator > 2) )
7395 return NULL;
7396 };
7397 if ( tp->predicates != NULL ) {
7398 tpj = tp->predicates;
7399 do {
7400 if ( tpj->type != RDFSTORE_TRIPLE_PATTERN_PART_RESOURCE_NODE )
7401 return NULL;
7402 } while ( ( tpj = tpj->next ) != NULL );
7403
7404 if ( (tp->predicates_operator < 0) ||
7405 (tp->predicates_operator > 2) )
7406 return NULL;
7407 };
7408 if ( tp->objects != NULL ) {
7409 tpj = tp->objects;
7410 do {
7411 if ( ! ( ( tpj->type == RDFSTORE_TRIPLE_PATTERN_PART_LITERAL_NODE ) ||
7412 ( tpj->type == RDFSTORE_TRIPLE_PATTERN_PART_RESOURCE_NODE ) ) )
7413 return NULL;
7414 } while ( ( tpj = tpj->next ) != NULL );
7415
7416 if ( (tp->objects_operator < 0) ||
7417 (tp->objects_operator > 2) )
7418 return NULL;
7419 };
7420 if ( tp->contexts != NULL ) {
7421 tpj = tp->contexts;
7422 do {
7423 if ( tpj->type != RDFSTORE_TRIPLE_PATTERN_PART_RESOURCE_NODE )
7424 return NULL;
7425 } while ( ( tpj = tpj->next ) != NULL );
7426
7427 if ( (tp->contexts_operator < 0) ||
7428 (tp->contexts_operator > 2) )
7429 return NULL;
7430 };
7431 if ( tp->langs != NULL ) {
7432 tpj = tp->langs;
7433 do {
7434 if ( tpj->type != RDFSTORE_TRIPLE_PATTERN_PART_STRING )
7435 return NULL;
7436 } while ( ( tpj = tpj->next ) != NULL );
7437
7438 if ( (tp->langs_operator < 0) ||
7439 (tp->langs_operator > 2) )
7440 return NULL;
7441 };
7442 if ( tp->dts != NULL ) {
7443 tpj = tp->dts;
7444 do {
7445 if ( tpj->type != RDFSTORE_TRIPLE_PATTERN_PART_STRING )
7446 return NULL;
7447 } while ( ( tpj = tpj->next ) != NULL );
7448
7449 if ( (tp->dts_operator < 0) ||
7450 (tp->dts_operator > 2) )
7451 return NULL;
7452 };
7453 if ( tp->words != NULL ) {
7454 tpj = tp->words;
7455 do {
7456 if ( tpj->type != RDFSTORE_TRIPLE_PATTERN_PART_STRING )
7457 return NULL;
7458 } while ( ( tpj = tpj->next ) != NULL );
7459
7460 if ( (tp->words_operator < 0) ||
7461 (tp->words_operator > 2) )
7462 return NULL;
7463 };
7464 if ( tp->ranges != NULL ) {
7465 tpj = tp->ranges;
7466 do {
7467 if ( tpj->type != RDFSTORE_TRIPLE_PATTERN_PART_STRING )
7468 return NULL;
7469 } while ( ( tpj = tpj->next ) != NULL );
7470
7471 if ( (tp->ranges_operator < 0 ) || /* it is unsigned int anyway... */
7472 (tp->ranges_operator > 10) )
7473 return NULL;
7474 };
7475 };
7476
7477 if ( ( me->freetext ) &&
7478 ( tp != NULL ) &&
7479 ( tp->words != NULL ) &&
7480 ( tp->objects != NULL ) ) {
7481 perror("rdfstore_search");
7482 fprintf(stderr,"Could search literal and free-text word at the same time for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
7483 return NULL;
7484 };
7485
7486 memset(&key, 0, sizeof(key));
7487 memset(&data, 0, sizeof(data));
7488
7489 #ifdef RDFSTORE_DEBUG
7490 fprintf(stderr,"TO SEARCH:\n");
7491 fprintf(stderr,"search type=%d\n",search_type);
7492 rdfstore_triple_pattern_dump( tp );
7493 fprintf(stderr," with options freetext='%d'\n", me->freetext);
7494 #endif
7495
7496 /* if the query was empty return the whole thing */
7497 if ( (tp == NULL) ||
7498 ((tp != NULL) &&
7499 (tp->subjects == NULL) &&
7500 (tp->predicates == NULL) &&
7501 (tp->objects == NULL) &&
7502 (tp->contexts == NULL) &&
7503 (tp->langs == NULL) &&
7504 (tp->dts == NULL) &&
7505 (tp->words == NULL) &&
7506 (tp->ranges == NULL) ) ) {
7507 return rdfstore_elements(me);
7508 };
7509
7510 /* note: due we do not distinguish hash keys for literals with same value byt different xml:lang or rdf:datatype and we keep special
7511 indexes for those literal components - we should re-write the query accordingly but for the moment we just warn the user */
7512 #ifdef RDFSTORE_VERBOSE
7513 if ( (tp->words != NULL) &&
7514 (tp->objects != NULL) ) {
7515 tpj = tp->objects;
7516 do {
7517 if( tpj->part.node->type == 1 ) {
7518 if( ( strlen(tpj->part.node->value.literal.lang) > 0 ) ||
7519 ( tpj->part.node->value.literal.dataType != NULL ) )
7520 fprintf(stderr,"WARNING: rdfstore_search() - RDF literal ");
7521 if( strlen(tpj->part.node->value.literal.lang) > 0 )
7522 fprintf(stderr,"xml:lang='%s' ",tpj->part.node->value.literal.lang);
7523
7524 if( tpj->part.node->value.literal.dataType != NULL )
7525 fprintf(stderr,"rdf:datatype='%s' ",tpj->part.node->value.literal.dataType);
7526 if( ( strlen(tpj->part.node->value.literal.lang) > 0 ) ||
7527 ( tpj->part.node->value.literal.dataType != NULL ) )
7528 fprintf(stderr,"component(s) can no be searched as part of the literal - please use the explicit rdfstore_search() syntax modifiers languages and datatypes.\n");
7529 };
7530 } while ( ( tpj = tpj->next ) != NULL );
7531 };
7532 #endif
7533
7534 results = (rdfstore_iterator *) RDFSTORE_MALLOC(sizeof(rdfstore_iterator));
7535 if (results == NULL) {
7536 perror("rdfstore_search");
7537 fprintf(stderr,"Cannot create results cursor/iterator for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
7538 return NULL;
7539 };
7540 results->store = me;
7541 results->store->attached++;
7542 /* bzero(results->ids,sizeof(unsigned char)*(RDFSTORE_MAXRECORDS_BYTES_SIZE)); */
7543 results->remove_holes = 0; /* reset the total number of holes */
7544 results->st_counter = 0;
7545 results->pos = 0;
7546 results->ids_size = 0;
7547 results->size = 0;
7548
7549 /* do any words combination first */
7550 if ( ( me->freetext ) &&
7551 ( tp->words != NULL ) ) {
7552 tpj = tp->words;
7553 do {
7554 utf8_casefolded_buff = (unsigned char *)RDFSTORE_MALLOC(strlen(tpj->part.string) * sizeof(unsigned char) *
7555 (RDFSTORE_UTF8_MAXLEN_FOLD + 1)); /* what about the ending '\0' here ?? */
7556 if (utf8_casefolded_buff == NULL) {
7557 perror("rdfstore_search");
7558 fprintf(stderr,"Cannot compute case-folded string out of input word for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
7559 rdfstore_iterator_close(results);
7560 return NULL;
7561 };
7562 /* not UTF-8 safe strlen() anyway... */
7563 if (rdfstore_utf8_string_to_utf8_foldedcase(strlen(tpj->part.string), tpj->part.string, &utf8_size, utf8_casefolded_buff)) {
7564 perror("rdfstore_search");
7565 fprintf(stderr,"Cannot compute case-folded string out of input word for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
7566 RDFSTORE_FREE(utf8_casefolded_buff);
7567 rdfstore_iterator_close(results);
7568 return NULL;
7569 };
7570 key.data = utf8_casefolded_buff;
7571 key.size = utf8_size;
7572 err = rdfstore_flat_store_fetch(me->windex, key, &data);
7573 if (err != 0) {
7574 RDFSTORE_FREE(utf8_casefolded_buff);
7575 if (err != FLAT_STORE_E_NOTFOUND) {
7576 perror("rdfstore_search");
7577 fprintf(stderr,"Could not fetch key '%s' in windex for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->windex));
7578 rdfstore_iterator_close(results);
7579 return NULL;
7580 } else {
7581 continue;
7582 };
7583 } else {
7584 if (outsize1 > 0) {
7585 me->func_decode(data.size, data.data, &outsize2, me->bits_decode);
7586 if (tp->words_operator == 1) {
7587 /* and them */
7588 outsize1 = rdfstore_bits_and(outsize1, bits, outsize2, me->bits_decode, bits1);
7589 } else if (tp->words_operator == 0) {
7590 /* or them */
7591 outsize1 = rdfstore_bits_or(outsize1, bits, outsize2, me->bits_decode, bits1);
7592 } else if (tp->words_operator == 2) {
7593 fprintf(stderr,"The boolean NOT operator on words is not implemented yet :)\n");
7594 };
7595 outsize1 = rdfstore_bits_shorten(outsize1, bits1); /* really useful due to
7596 * the odd statements
7597 * shortness */
7598 bcopy(bits1, bits, outsize1); /* slow? */
7599 } else {
7600 me->func_decode(data.size, data.data, &outsize1, bits);
7601 };
7602 RDFSTORE_FREE(data.data);
7603 };
7604
7605 #ifdef RDFSTORE_DEBUG
7606 {
7607 int j;
7608 printf("SEARCH windex for word '%s' case-folded as '%s' with tp->words_operator '%d' (words only bits) -->'", tpj->part.string, utf8_casefolded_buff, tp->words_operator);
7609 for(j=0;j<8*outsize1;j++) {
7610 printf("Rec %d %c\n", j, (bits[j>>3] & (1<<(j&7))) ? '1':'0');
7611 };
7612 printf("'\n");
7613 }
7614 #endif
7615
7616 RDFSTORE_FREE(utf8_casefolded_buff);
7617
7618 } while ( ( tpj = tpj->next ) != NULL );
7619
7620 #ifdef RDFSTORE_DEBUG
7621 {
7622 int i;
7623 printf("SEARCH windex for words '");
7624 tpj = tp->words;
7625 do {
7626 fprintf(stderr," %s ", tpj->part.string );
7627 } while ( ( tpj = tpj->next ) != NULL );
7628 printf("' -->'");
7629 for(i=0;i<8*outsize1;i++) {
7630 printf("Rec %d %c\n", i, (bits[i>>3] & (1<<(i&7))) ? '1':'0');
7631 };
7632 printf("'\n");
7633 }
7634 #endif
7635
7636 /* no words matched? */
7637 if (!outsize1)
7638 return results;
7639 };
7640
7641 /*
7642 * this happens when we got a fixed object or free-text; otherwise we
7643 * need a double fetch + shifting of bits to generate the iterator
7644 */
7645 if (tp != NULL) {
7646 if ( tp->subjects != NULL ) {
7647 outsize3=0;
7648 tpj = tp->subjects;
7649 do {
7650
7651 /* compute subject hashcode */
7652 tpj->part.node->hashcode = rdfstore_digest_get_node_hashCode(tpj->part.node, 0);
7653
7654 packInt(tpj->part.node->hashcode, outbuf);
7655 key.data = outbuf;
7656 key.size = sizeof(int);
7657
7658 #ifdef RDFSTORE_CONNECTIONS
7659 err = rdfstore_flat_store_fetch((search_type==0) ? me->subjects : me->s_connections, key, &data);
7660 #else
7661 err = rdfstore_flat_store_fetch( me->subjects, key, &data);
7662 #endif
7663 if (err != 0) {
7664 if (err != FLAT_STORE_E_NOTFOUND) {
7665 perror("rdfstore_search");
7666 #ifdef RDFSTORE_CONNECTIONS
7667 fprintf(stderr,"Could not fetch key '%s' for subject pattern for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error((search_type==0) ? me->subjects : me->s_connections));
7668 #else
7669 fprintf(stderr,"Could not fetch key '%s' for subject pattern for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error( me->subjects ));
7670 #endif
7671 rdfstore_iterator_close(results);
7672 return NULL;
7673 } else {
7674 /* cannot join */
7675 continue;
7676 };
7677 } else {
7678 if (outsize3 > 0) {
7679 #ifdef RDFSTORE_CONNECTIONS
7680 if(search_type==0) {
7681 me->func_decode(data.size, data.data, &outsize2, me->bits_decode);
7682 } else {
7683 me->func_decode_connections(data.size, data.data, &outsize2, me->bits_decode);
7684 };
7685 #else
7686 me->func_decode(data.size, data.data, &outsize2, me->bits_decode);
7687 #endif
7688
7689 if (tp->subjects_operator == 1) {
7690 /* and them i.e. URL1, URL2, URL3....URLn */
7691 outsize3 = rdfstore_bits_and(outsize3, bits2, outsize2, me->bits_decode, bits1);
7692 } else if (tp->subjects_operator == 0) {
7693 /* or them i.e. URL1, URL2, URL3....URLn */
7694 outsize3 = rdfstore_bits_or(outsize3, bits2, outsize2, me->bits_decode, bits1);
7695 } else if (tp->subjects_operator == 2) {
7696 fprintf(stderr,"The boolean NOT operator on subjects is not implemented yet :)\n");
7697 };
7698
7699 outsize3 = rdfstore_bits_shorten(outsize3, bits1); /* why shorten? inefficient??? */
7700 bcopy(bits1, bits2, outsize3); /* slow? */
7701 } else {
7702 #ifdef RDFSTORE_CONNECTIONS
7703 if(search_type==0) {
7704 me->func_decode(data.size, data.data, &outsize3, bits2);
7705 } else {
7706 me->func_decode_connections(data.size, data.data, &outsize3, bits2);
7707 };
7708 #else
7709 me->func_decode(data.size, data.data, &outsize3, bits2);
7710 #endif
7711 };
7712 RDFSTORE_FREE(data.data);
7713 };
7714
7715 #ifdef RDFSTORE_DEBUG
7716 {
7717 int j;
7718 printf("SEARCH subjects[%d] for S -->'",i);
7719 for(j=0;j<8*outsize3;j++) {
7720 printf("Rec %d %c\n", j, (bits2[j>>3] & (1<<(j&7))) ? '1':'0');
7721 };
7722 printf("'\n");
7723 }
7724 #endif
7725 } while ( ( tpj = tpj->next ) != NULL );
7726
7727 /* no subjects matched? */
7728 if (!outsize3)
7729 return results;
7730
7731 /* AND in all subjects to previous words now */
7732 if (outsize1 > 0) {
7733 /* and them */
7734 outsize1 = rdfstore_bits_and(outsize1, bits, outsize3, bits2, bits1);
7735 outsize1 = rdfstore_bits_shorten(outsize1, bits1);
7736
7737 /* cannot join */
7738 if (!outsize1) {
7739 return results;
7740 };
7741
7742 bcopy(bits1, bits, outsize1); /* slow? */
7743 } else {
7744 /* or OR them */
7745 outsize1 = rdfstore_bits_or(outsize3, bits, outsize3, bits2, bits1);
7746 bcopy(bits1, bits, outsize3); /* slow? */
7747 };
7748
7749 #ifdef RDFSTORE_DEBUG
7750 {
7751 int j;
7752 printf("SEARCH subjects for S -->'");
7753 for(j=0;j<8*outsize1;j++) {
7754 printf("Rec %d %c\n", j, (bits[j>>3] & (1<<(j&7))) ? '1':'0');
7755 };
7756 printf("'\n");
7757 }
7758 #endif
7759 };
7760
7761 if ( tp->predicates != NULL ) {
7762 outsize3=0;
7763 tpj = tp->predicates;
7764 do {
7765
7766 /* compute subject hashcode */
7767 tpj->part.node->hashcode = rdfstore_digest_get_node_hashCode(tpj->part.node, 0);
7768
7769 packInt(tpj->part.node->hashcode, outbuf);
7770 key.data = outbuf;
7771 key.size = sizeof(int);
7772
7773 #ifdef RDFSTORE_CONNECTIONS
7774 err = rdfstore_flat_store_fetch((search_type==0) ? me->predicates : me->p_connections, key, &data);
7775 #else
7776 err = rdfstore_flat_store_fetch( me->predicates, key, &data);
7777 #endif
7778 if (err != 0) {
7779 if (err != FLAT_STORE_E_NOTFOUND) {
7780 perror("rdfstore_search");
7781 #ifdef RDFSTORE_CONNECTIONS
7782 fprintf(stderr,"Could not fetch key '%s' for predicate pattern for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error((search_type==0) ? me->predicates : me->p_connections));
7783 #else
7784 fprintf(stderr,"Could not fetch key '%s' for predicate pattern for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error( me->predicates ));
7785 #endif
7786 rdfstore_iterator_close(results);
7787 return NULL;
7788 } else {
7789 continue;
7790 };
7791 } else {
7792 if (outsize3 > 0) {
7793 #ifdef RDFSTORE_CONNECTIONS
7794 if(search_type==0) {
7795 me->func_decode(data.size, data.data, &outsize2, me->bits_decode);
7796 } else {
7797 me->func_decode_connections(data.size, data.data, &outsize2, me->bits_decode);
7798 };
7799 #else
7800 me->func_decode(data.size, data.data, &outsize2, me->bits_decode);
7801 #endif
7802
7803 if (tp->predicates_operator == 1) {
7804 /* and them i.e. URL1, URL2, URL3....URLn */
7805 outsize3 = rdfstore_bits_and(outsize3, bits2, outsize2, me->bits_decode, bits1);
7806 } else if (tp->predicates_operator == 0) {
7807 /* or them i.e. URL1, URL2, URL3....URLn */
7808 outsize3 = rdfstore_bits_or(outsize3, bits2, outsize2, me->bits_decode, bits1);
7809 } else if (tp->predicates_operator == 2) {
7810 fprintf(stderr,"The boolean NOT operator on predicates is not implemented yet :)\n");
7811 };
7812
7813 outsize3 = rdfstore_bits_shorten(outsize3, bits1);
7814 bcopy(bits1, bits2, outsize3); /* slow? */
7815 } else {
7816 #ifdef RDFSTORE_CONNECTIONS
7817 if(search_type==0) {
7818 me->func_decode(data.size, data.data, &outsize3, bits2);
7819 } else {
7820 me->func_decode_connections(data.size, data.data, &outsize3, bits2);
7821 };
7822 #else
7823 me->func_decode(data.size, data.data, &outsize3, bits2);
7824 #endif
7825 };
7826 RDFSTORE_FREE(data.data);
7827 };
7828
7829 #ifdef RDFSTORE_DEBUG
7830 {
7831 int j;
7832 printf("SEARCH predicates[%d] for P -->'",i);
7833 for(j=0;j<8*outsize3;j++) {
7834 printf("Rec %d %c\n", j, (bits2[j>>3] & (1<<(j&7))) ? '1':'0');
7835 };
7836 printf("'\n");
7837 }
7838 #endif
7839 } while ( ( tpj = tpj->next ) != NULL );
7840
7841 /* no predicates matched? */
7842 if (!outsize3)
7843 return results;
7844
7845 /* AND in all predicates to previous words and subjects now */
7846 if (outsize1 > 0) {
7847 /* and them */
7848 outsize1 = rdfstore_bits_and(outsize1, bits, outsize3, bits2, bits1);
7849 outsize1 = rdfstore_bits_shorten(outsize1, bits1);
7850
7851 /* cannot join */
7852 if (!outsize1) {
7853 return results;
7854 };
7855
7856 bcopy(bits1, bits, outsize1); /* slow? */
7857 } else {
7858 /* or OR them */
7859 outsize1 = rdfstore_bits_or(outsize3, bits, outsize3, bits2, bits1);
7860 bcopy(bits1, bits, outsize3); /* slow? */
7861 };
7862
7863 #ifdef RDFSTORE_DEBUG
7864 {
7865 int j;
7866 printf("SEARCH predicates for P -->'");
7867 for(j=0;j<8*outsize1;j++) {
7868 printf("Rec %d %c\n", j, (bits[j>>3] & (1<<(j&7))) ? '1':'0');
7869 };
7870 printf("'\n");
7871 }
7872 #endif
7873
7874 };
7875
7876 if ( tp->objects != NULL ) {
7877 outsize3=0;
7878 tpj = tp->objects;
7879 do {
7880
7881 /* compute subject hashcode */
7882 tpj->part.node->hashcode = rdfstore_digest_get_node_hashCode(tpj->part.node, 0);
7883
7884 packInt(tpj->part.node->hashcode, outbuf);
7885 key.data = outbuf;
7886 key.size = sizeof(int);
7887
7888 #ifdef RDFSTORE_CONNECTIONS
7889 err = rdfstore_flat_store_fetch((search_type==0) ? me->objects : me->o_connections, key, &data);
7890 #else
7891 err = rdfstore_flat_store_fetch( me->objects, key, &data);
7892 #endif
7893 if (err != 0) {
7894 if (err != FLAT_STORE_E_NOTFOUND) {
7895 perror("rdfstore_search");
7896 #ifdef RDFSTORE_CONNECTIONS
7897 fprintf(stderr,"Could not fetch key '%s' for object for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error((search_type==0) ? me->objects : me->o_connections));
7898 #else
7899 fprintf(stderr,"Could not fetch key '%s' for object for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error( me->objects ));
7900 #endif
7901 rdfstore_iterator_close(results);
7902 return NULL;
7903 } else {
7904 continue;
7905 };
7906 } else {
7907 if (outsize3 > 0) {
7908 #ifdef RDFSTORE_CONNECTIONS
7909 if(search_type==0) {
7910 me->func_decode(data.size, data.data, &outsize2, me->bits_decode);
7911 } else {
7912 me->func_decode_connections(data.size, data.data, &outsize2, me->bits_decode);
7913 };
7914 #else
7915 me->func_decode(data.size, data.data, &outsize2, me->bits_decode);
7916 #endif
7917
7918 if (tp->objects_operator == 1) {
7919 /* and them i.e. URL1, URL2, URL3....URLn */
7920 outsize3 = rdfstore_bits_and(outsize3, bits2, outsize2, me->bits_decode, bits1);
7921 } else if (tp->objects_operator == 0) {
7922 /* or them i.e. URL1, URL2, URL3....URLn */
7923 outsize3 = rdfstore_bits_or(outsize3, bits2, outsize2, me->bits_decode, bits1);
7924 } else if (tp->objects_operator == 2) {
7925 fprintf(stderr,"The boolean NOT operator on objects is not implemented yet :)\n");
7926 };
7927
7928 outsize3 = rdfstore_bits_shorten(outsize3, bits1);
7929 bcopy(bits1, bits2, outsize3); /* slow? */
7930 } else {
7931 #ifdef RDFSTORE_CONNECTIONS
7932 if(search_type==0) {
7933 me->func_decode(data.size, data.data, &outsize3, bits2);
7934 } else {
7935 me->func_decode_connections(data.size, data.data, &outsize3, bits2);
7936 };
7937 #else
7938 me->func_decode(data.size, data.data, &outsize3, bits2);
7939 #endif
7940 };
7941 RDFSTORE_FREE(data.data);
7942 };
7943
7944 #ifdef RDFSTORE_DEBUG
7945 {
7946 int j;
7947 printf("SEARCH objects[%d] for O -->'",i);
7948 for(j=0;j<8*outsize3;j++) {
7949 printf("Rec %d %c\n", j, (bits2[j>>3] & (1<<(j&7))) ? '1':'0');
7950 };
7951 printf("'\n");
7952 }
7953 #endif
7954 } while ( ( tpj = tpj->next ) != NULL );
7955
7956 /* no objects matched? */
7957 if (!outsize3)
7958 return results;
7959
7960 /* AND in all objects to previous words, subjects and predicates now */
7961 if (outsize1 > 0) {
7962 /* and them */
7963 outsize1 = rdfstore_bits_and(outsize1, bits, outsize3, bits2, bits1);
7964 outsize1 = rdfstore_bits_shorten(outsize1, bits1);
7965
7966 /* cannot join */
7967 if (!outsize1) {
7968 return results;
7969 };
7970
7971 bcopy(bits1, bits, outsize1); /* slow? */
7972 } else {
7973 /* or OR them */
7974 outsize1 = rdfstore_bits_or(outsize3, bits, outsize3, bits2, bits1);
7975 bcopy(bits1, bits, outsize3); /* slow? */
7976 };
7977
7978 #ifdef RDFSTORE_DEBUG
7979 {
7980 int j;
7981 printf("SEARCH objects for O -->'");
7982 for(j=0;j<8*outsize1;j++) {
7983 printf("Rec %d %c\n", j, (bits[j>>3] & (1<<(j&7))) ? '1':'0');
7984 };
7985 printf("'\n");
7986 }
7987 #endif
7988 };
7989
7990 /* xml:lang ones */
7991 if ( tp->langs != NULL) {
7992 outsize3=0;
7993 tpj = tp->langs;
7994 do {
7995
7996 utf8_casefolded_buff = (unsigned char *)RDFSTORE_MALLOC(strlen(tpj->part.string) * sizeof(unsigned char) * (RDFSTORE_UTF8_MAXLEN_FOLD + 1));
7997 if (utf8_casefolded_buff == NULL) {
7998 perror("rdfstore_search");
7999 fprintf(stderr,"Cannot compute case-folded string out of input literal language for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
8000 rdfstore_iterator_close(results);
8001 return NULL;
8002 };
8003 /* even if strlen() is not UTF-8 safe... */
8004 if (rdfstore_utf8_string_to_utf8_foldedcase(strlen(tpj->part.string), tpj->part.string, &utf8_size, utf8_casefolded_buff)) {
8005 perror("rdfstore_search");
8006 fprintf(stderr,"Cannot compute case-folded string out of input literal language for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
8007 RDFSTORE_FREE(utf8_casefolded_buff);
8008 rdfstore_iterator_close(results);
8009 return NULL;
8010 };
8011
8012 key.data = utf8_casefolded_buff;
8013 key.size = utf8_size;
8014
8015 err = rdfstore_flat_store_fetch( me->languages, key, &data);
8016 if (err != 0) {
8017 if (err != FLAT_STORE_E_NOTFOUND) {
8018 perror("rdfstore_search");
8019 fprintf(stderr,"Could not fetch key '%s' for literal language for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error( me->languages ));
8020 RDFSTORE_FREE(utf8_casefolded_buff);
8021 rdfstore_iterator_close(results);
8022 return NULL;
8023 } else {
8024 continue;
8025 };
8026 } else {
8027 if (outsize3 > 0) {
8028 me->func_decode(data.size, data.data, &outsize2, me->bits_decode);
8029
8030 if (tp->langs_operator == 1) {
8031 /* and them i.e. lang1, lang2, lang3....langn */
8032 outsize3 = rdfstore_bits_and(outsize3, bits2, outsize2, me->bits_decode, bits1);
8033 } else if (tp->langs_operator == 0) {
8034 /* or them i.e. lang1, lang2, lang3....langn */
8035 outsize3 = rdfstore_bits_or(outsize3, bits2, outsize2, me->bits_decode, bits1);
8036 } else if (tp->langs_operator == 2) {
8037 fprintf(stderr,"The boolean NOT operator on objects literal language is not implemented yet :)\n");
8038 };
8039
8040 outsize3 = rdfstore_bits_shorten(outsize3, bits1);
8041 bcopy(bits1, bits2, outsize3); /* slow? */
8042 } else {
8043 me->func_decode(data.size, data.data, &outsize3, bits2);
8044 };
8045 RDFSTORE_FREE(data.data);
8046 };
8047
8048 #ifdef RDFSTORE_DEBUG
8049 {
8050 int j;
8051 printf("SEARCH languages[%d] for O xml:lang -->'",i);
8052 for(j=0;j<8*outsize3;j++) {
8053 printf("Rec %d %c\n", j, (bits2[j>>3] & (1<<(j&7))) ? '1':'0');
8054 };
8055 printf("'\n");
8056 }
8057 #endif
8058
8059 RDFSTORE_FREE(utf8_casefolded_buff);
8060
8061 } while ( ( tpj = tpj->next ) != NULL );
8062
8063 /* no objects matched? */
8064 if (!outsize3)
8065 return results;
8066
8067 /* AND in all xml:lang to previous words, subjects, predicates and objects now */
8068 if (outsize1 > 0) {
8069 /* and them */
8070 outsize1 = rdfstore_bits_and(outsize1, bits, outsize3, bits2, bits1);
8071 outsize1 = rdfstore_bits_shorten(outsize1, bits1);
8072
8073 /* cannot join */
8074 if (!outsize1) {
8075 return results;
8076 };
8077
8078 bcopy(bits1, bits, outsize1); /* slow? */
8079 } else {
8080 /* or OR them */
8081 outsize1 = rdfstore_bits_or(outsize3, bits, outsize3, bits2, bits1);
8082 bcopy(bits1, bits, outsize3); /* slow? */
8083 };
8084
8085 #ifdef RDFSTORE_DEBUG
8086 {
8087 int j;
8088 printf("SEARCH languages for O xml:lang -->'");
8089 for(j=0;j<8*outsize1;j++) {
8090 printf("Rec %d %c\n", j, (bits[j>>3] & (1<<(j&7))) ? '1':'0');
8091 };
8092 printf("'\n");
8093 }
8094 #endif
8095 };
8096
8097 /* rdf:datatype ones */
8098 if ( tp->dts != NULL ) {
8099 outsize3=0;
8100 tpj = tp->dts;
8101 do {
8102
8103 key.data = tpj->part.string;
8104 key.size = strlen(tpj->part.string); /* even if strlen() is not UTF-8 safe... */
8105
8106 err = rdfstore_flat_store_fetch( me->datatypes, key, &data);
8107 if (err != 0) {
8108 if (err != FLAT_STORE_E_NOTFOUND) {
8109 perror("rdfstore_search");
8110 fprintf(stderr,"Could not fetch key '%s' for literal datatype for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error( me->datatypes ));
8111 rdfstore_iterator_close(results);
8112 return NULL;
8113 } else {
8114 continue;
8115 };
8116 } else {
8117 if (outsize3 > 0) {
8118 me->func_decode(data.size, data.data, &outsize2, me->bits_decode);
8119
8120 if (tp->dts_operator == 1) {
8121 /* and them i.e. URL1, URL2, URL3....URLn */
8122 outsize3 = rdfstore_bits_and(outsize3, bits2, outsize2, me->bits_decode, bits1);
8123 } else if (tp->dts_operator == 0) {
8124 /* or them i.e. URL1, URL2, URL3....URLn */
8125 outsize3 = rdfstore_bits_or(outsize3, bits2, outsize2, me->bits_decode, bits1);
8126 } else if (tp->dts_operator == 2) {
8127 fprintf(stderr,"The boolean NOT operator on objects literal datatype is not implemented yet :)\n");
8128 };
8129
8130 outsize3 = rdfstore_bits_shorten(outsize3, bits1);
8131 bcopy(bits1, bits2, outsize3); /* slow? */
8132 } else {
8133 me->func_decode(data.size, data.data, &outsize3, bits2);
8134 };
8135 RDFSTORE_FREE(data.data);
8136 };
8137
8138 #ifdef RDFSTORE_DEBUG
8139 {
8140 int j;
8141 printf("SEARCH datatypes[%d] for O rdf:datatype -->'",i);
8142 for(j=0;j<8*outsize3;j++) {
8143 printf("Rec %d %c\n", j, (bits2[j>>3] & (1<<(j&7))) ? '1':'0');
8144 };
8145 printf("'\n");
8146 }
8147 #endif
8148
8149 } while ( ( tpj = tpj->next ) != NULL );
8150
8151 /* no objects matched? */
8152 if (!outsize3)
8153 return results;
8154
8155 /* AND in all rdf:datatype to previous words, subjects, predicates, objects and languages now */
8156 if (outsize1 > 0) {
8157 /* and them */
8158 outsize1 = rdfstore_bits_and(outsize1, bits, outsize3, bits2, bits1);
8159 outsize1 = rdfstore_bits_shorten(outsize1, bits1);
8160
8161 /* cannot join */
8162 if (!outsize1) {
8163 return results;
8164 };
8165
8166 bcopy(bits1, bits, outsize1); /* slow? */
8167 } else {
8168 /* or OR them */
8169 outsize1 = rdfstore_bits_or(outsize3, bits, outsize3, bits2, bits1);
8170 bcopy(bits1, bits, outsize3); /* slow? */
8171 };
8172
8173 #ifdef RDFSTORE_DEBUG
8174 {
8175 int j;
8176 printf("SEARCH datatypes for O rdf:datatype -->'");
8177 for(j=0;j<8*outsize1;j++) {
8178 printf("Rec %d %c\n", j, (bits[j>>3] & (1<<(j&7))) ? '1':'0');
8179 };
8180 printf("'\n");
8181 }
8182 #endif
8183 };
8184
8185 /* numerical comparinson one */
8186 if ( tp->ranges != NULL ) {
8187 int islval=0;
8188 int isdval=0;
8189 int isdateval=0;
8190 long thelval[2];
8191 long alval;
8192 double thedval[2];
8193 double adval;
8194 struct tm thedateval_tm[2];
8195 char thedateval[2][RDFSTORE_XSD_DATETIME_FORMAT_SIZE];
8196 char adateval[RDFSTORE_XSD_DATETIME_FORMAT_SIZE];
8197 int last=0;
8198
8199 tpj = tp->ranges; /* we simply just take the first/head of the list */
8200
8201 /* guess out the type from the given string */
8202 if( ( islval = rdfstore_xsd_deserialize_integer( tpj->part.string, &thelval[0] ) ) == 0 ) /* do not fetch xsd:integer(s) twice also as xsd:double */
8203 isdval = rdfstore_xsd_deserialize_double( tpj->part.string, &thedval[0] );
8204
8205 if( (! islval) &&
8206 (! isdval) ) {
8207 isdateval = rdfstore_xsd_deserialize_dateTime( tpj->part.string, &thedateval_tm[0] );
8208
8209 if( ! isdateval ) {
8210 isdateval = rdfstore_xsd_deserialize_date( tpj->part.string, &thedateval_tm[0] );
8211 };
8212
8213 if( ! isdateval ) {
8214 /* unknown... */
8215 rdfstore_iterator_close(results);
8216 return NULL;
8217 };
8218
8219 rdfstore_xsd_serialize_dateTime( thedateval_tm[0], thedateval[0] ); /* we index xsd:dataTime version anyway */
8220 };
8221
8222 if ( (tp->ranges_operator > 6 ) &&
8223 (tp->ranges_operator < 11) ) {
8224 tpj = tpj->next;
8225
8226 if ( tpj == NULL ) {
8227 /* error... */
8228 rdfstore_iterator_close(results);
8229 return NULL;
8230 };
8231
8232 /* we can use ranges of the same kind only */
8233 if(islval!=0) {
8234 if( rdfstore_xsd_deserialize_integer( tpj->part.string, &thelval[1] ) == 0 ) {
8235 /* error... */
8236 rdfstore_iterator_close(results);
8237 return NULL;
8238 };
8239 } else if(isdval!=0) {
8240 if( rdfstore_xsd_deserialize_double( tpj->part.string, &thedval[1] ) == 0 ) {
8241 /* error... */
8242 rdfstore_iterator_close(results);
8243 return NULL;
8244 };
8245 } else {
8246 if( rdfstore_xsd_deserialize_dateTime( tpj->part.string, &thedateval_tm[1] ) == 0 ) {
8247 if( rdfstore_xsd_deserialize_date( tpj->part.string, &thedateval_tm[1] ) == 0 ) {
8248 /* error... */
8249 rdfstore_iterator_close(results);
8250 return NULL;
8251 };
8252 };
8253
8254 rdfstore_xsd_serialize_dateTime( thedateval_tm[1], thedateval[1] ); /* we index xsd:dataTime version anyway */
8255 };
8256 };
8257
8258 outsize3=0;
8259
8260 if ( ( tp->ranges_operator == 1 ) ||
8261 ( tp->ranges_operator == 2 ) ) { /* x < a or x <= a */
8262 if (rdfstore_flat_store_first( (islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date , &key) == 0) {
8263 do {
8264 if(islval!=0) {
8265 memcpy( &alval, key.data, sizeof(long) );
8266 if( alval == thelval[0] ) {
8267 if( tp->ranges_operator == 2 ) { /* x <= a */
8268 last=1;
8269 } else {
8270 RDFSTORE_FREE(key.data); /* dispose the key fetched above */
8271 break; /* stop here - anything from the first key till x (excluded) */
8272 };
8273 } else if ( alval > thelval[0] ) {
8274 RDFSTORE_FREE(key.data);
8275 break;
8276 };
8277 } else if(isdval!=0) {
8278 memcpy( &adval, key.data, sizeof(double) );
8279 if( adval == thedval[0] ) {
8280 if( tp->ranges_operator == 2 ) { /* x <= a */
8281 last=1;
8282 } else {
8283 RDFSTORE_FREE(key.data); /* dispose the key fetched above */
8284 break; /* stop here - anything from the first key till x (excluded) */
8285 };
8286 } else if ( adval > thedval[0] ) {
8287 RDFSTORE_FREE(key.data);
8288 break;
8289 };
8290 } else {
8291 memcpy( adateval, key.data, key.size );
8292 if( strcmp( adateval, thedateval[0] ) == 0 ) {
8293 if( tp->ranges_operator == 2 ) { /* x <= a */
8294 last=1;
8295 } else {
8296 RDFSTORE_FREE(key.data); /* dispose the key fetched above */
8297 break; /* stop here - anything from the first key till x (excluded) */
8298 };
8299 } else if ( strcmp( adateval, thedateval[0] ) > 0 ) {
8300 RDFSTORE_FREE(key.data);
8301 break;
8302 };
8303 };
8304 err = rdfstore_flat_store_fetch( (islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, key, &data);
8305 if (err != 0) {
8306 if (err != FLAT_STORE_E_NOTFOUND) {
8307 perror("rdfstore_search");
8308 fprintf(stderr,"Could not fetch key '%s' for range for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error( (islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date ));
8309 rdfstore_iterator_close(results);
8310 return NULL;
8311 } else {
8312 continue;
8313 };
8314 } else {
8315 if (outsize3 > 0) {
8316 me->func_decode(data.size, data.data, &outsize2, me->bits_decode);
8317
8318 /* or each of them */
8319 outsize3 = rdfstore_bits_or(outsize3, bits2, outsize2, me->bits_decode, bits1);
8320
8321 outsize3 = rdfstore_bits_shorten(outsize3, bits1);
8322 bcopy(bits1, bits2, outsize3); /* slow? */
8323 } else {
8324 me->func_decode(data.size, data.data, &outsize3, bits2);
8325 };
8326 RDFSTORE_FREE(data.data);
8327 };
8328
8329 #ifdef RDFSTORE_DEBUG
8330 {
8331 int j;
8332 if(islval!=0) {
8333 printf("SEARCH '%ld' <%s '%ld' -->'", (long)alval, ( ( tp->ranges_operator == 2 ) ? "=" : "" ), (long)thelval[0]);
8334 } else if(isdval!=0) {
8335 printf("SEARCH '%f' <%s '%f' -->'", adval, ( ( tp->ranges_operator == 2 ) ? "=" : "" ), thedval[0]);
8336 } else {
8337 printf("SEARCH '%s' <%s '%s' -->'", adateval, ( ( tp->ranges_operator == 2 ) ? "=" : "" ), thedateval[0]);
8338 };
8339 for(j=0;j<8*outsize3;j++) {
8340 printf("Rec %d %c\n", j, (bits2[j>>3] & (1<<(j&7))) ? '1':'0');
8341 };
8342 printf("'\n");
8343 }
8344 #endif
8345
8346 if(last) {
8347 RDFSTORE_FREE(key.data); /* dispose the key fetched above */
8348 break; /* x <= a */
8349 };
8350
8351 /* hup the next one in b-tree order */
8352 err = rdfstore_flat_store_next((islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, key, &data);
8353 RDFSTORE_FREE(key.data); /* dispose the previous/current key */
8354 if (err == 0) {
8355 key = data;
8356 };
8357 } while (err == 0);
8358 };
8359 } else if ( tp->ranges_operator == 3 ) { /* x == y */
8360 /* simple fetch and AND */
8361 if(islval!=0) {
8362 key.data = (long*) &thelval[0]; /* should pack int perhaps... */
8363 key.size = sizeof(long);
8364 } else if(isdval!=0) {
8365 key.data = (double*) &thedval[0]; /* should pack int perhaps... */
8366 key.size = sizeof(double);
8367 } else {
8368 key.data = thedateval[0];
8369 key.size = strlen(thedateval[0])+1;
8370 };
8371 err = rdfstore_flat_store_fetch( (islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, key, &data);
8372 if (err != 0) {
8373 if (err != FLAT_STORE_E_NOTFOUND) {
8374 perror("rdfstore_search");
8375 fprintf(stderr,"Could not fetch key '%s' for range for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error( (islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date ));
8376 rdfstore_iterator_close(results);
8377 return NULL;
8378 } else {
8379 /* error or no matches?... */
8380 rdfstore_iterator_close(results);
8381 return NULL;
8382 };
8383 } else {
8384 if (outsize3 > 0) {
8385 me->func_decode(data.size, data.data, &outsize2, me->bits_decode);
8386
8387 /* or each of them */
8388 outsize3 = rdfstore_bits_or(outsize3, bits2, outsize2, me->bits_decode, bits1);
8389
8390 outsize3 = rdfstore_bits_shorten(outsize3, bits1);
8391 bcopy(bits1, bits2, outsize3); /* slow? */
8392 } else {
8393 me->func_decode(data.size, data.data, &outsize3, bits2);
8394 };
8395 RDFSTORE_FREE(data.data);
8396 };
8397
8398 #ifdef RDFSTORE_DEBUG
8399 {
8400 int j;
8401 if(islval!=0) {
8402 printf("SEARCH '%ld' == '%ld' -->'", (long)alval, (long)thelval[0]);
8403 } else if(isdval!=0) {
8404 printf("SEARCH '%f' == '%f' -->'", adval, thedval[0]);
8405 } else {
8406 printf("SEARCH '%s' == '%s' -->'", adateval, thedateval[0]);
8407 };
8408 for(j=0;j<8*outsize3;j++) {
8409 printf("Rec %d %c\n", j, (bits2[j>>3] & (1<<(j&7))) ? '1':'0');
8410 };
8411 printf("'\n");
8412 }
8413 #endif
8414 } else if ( tp->ranges_operator == 4 ) { /* x != y */
8415 if (rdfstore_flat_store_first( (islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date , &key) == 0) {
8416 do {
8417 if(islval!=0) {
8418 memcpy( &alval, key.data, sizeof(long) );
8419 if( alval == thelval[0] ) {
8420 /* hup the next one in b-tree order */
8421 err = rdfstore_flat_store_next((islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, key, &data);
8422 RDFSTORE_FREE(key.data); /* dispose the previous/current key */
8423 if (err == 0) {
8424 key = data;
8425 };
8426 continue;
8427 };
8428 } else if(isdval!=0) {
8429 memcpy( &adval, key.data, sizeof(double) );
8430 if( adval == thedval[0] ) {
8431 /* hup the next one in b-tree order */
8432 err = rdfstore_flat_store_next((islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, key, &data);
8433 RDFSTORE_FREE(key.data); /* dispose the previous/current key */
8434 if (err == 0) {
8435 key = data;
8436 };
8437 continue;
8438 };
8439 } else {
8440 memcpy( adateval, key.data, key.size );
8441 if( strcmp( adateval, thedateval[0] ) == 0 ) {
8442 /* hup the next one in b-tree order */
8443 err = rdfstore_flat_store_next((islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, key, &data);
8444 RDFSTORE_FREE(key.data); /* dispose the previous/current key */
8445 if (err == 0) {
8446 key = data;
8447 };
8448 continue;
8449 };
8450 };
8451 err = rdfstore_flat_store_fetch( (islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, key, &data);
8452 if (err != 0) {
8453 if (err != FLAT_STORE_E_NOTFOUND) {
8454 perror("rdfstore_search");
8455 fprintf(stderr,"Could not fetch key '%s' for range for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error( (islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date ));
8456 rdfstore_iterator_close(results);
8457 return NULL;
8458 } else {
8459 continue;
8460 };
8461 } else {
8462 if (outsize3 > 0) {
8463 me->func_decode(data.size, data.data, &outsize2, me->bits_decode);
8464
8465 /* or each of them */
8466 outsize3 = rdfstore_bits_or(outsize3, bits2, outsize2, me->bits_decode, bits1);
8467
8468 outsize3 = rdfstore_bits_shorten(outsize3, bits1);
8469 bcopy(bits1, bits2, outsize3); /* slow? */
8470 } else {
8471 me->func_decode(data.size, data.data, &outsize3, bits2);
8472 };
8473 RDFSTORE_FREE(data.data);
8474 };
8475
8476 /* hup the next one in b-tree order */
8477 err = rdfstore_flat_store_next((islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, key, &data);
8478 RDFSTORE_FREE(key.data); /* dispose the previous/current key */
8479 if (err == 0) {
8480 key = data;
8481 };
8482 } while (err == 0);
8483 };
8484 } else if ( ( tp->ranges_operator == 5 ) ||
8485 ( tp->ranges_operator == 6 ) ) { /* x >= a or x > a */
8486 if(islval!=0) {
8487 data.data = (long*) &thelval[0]; /* should pack int perhaps... */
8488 data.size = sizeof(long);
8489 } else if(isdval!=0) {
8490 data.data = (double*) &thedval[0]; /* should pack int perhaps... */
8491 data.size = sizeof(double);
8492 } else {
8493 data.data = thedateval[0];
8494 data.size = strlen(thedateval[0])+1;
8495 };
8496 if (rdfstore_flat_store_from( (islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, data, &key) == 0) {
8497 do {
8498 if(islval!=0) {
8499 memcpy( &alval, key.data, sizeof(long) );
8500 if( alval == thelval[0] ) {
8501 if( tp->ranges_operator == 6 ) { /* x > a */
8502 /* hup the next one in b-tree order */
8503 err = rdfstore_flat_store_next((islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, key, &data);
8504 RDFSTORE_FREE(key.data); /* dispose the previous/current key */
8505 if (err == 0) {
8506 key = data;
8507 continue;
8508 } else {
8509 break;
8510 };
8511 };
8512 };
8513 } else if(isdval!=0) {
8514 memcpy( &adval, key.data, sizeof(double) );
8515 if( adval == thedval[0] ) {
8516 if( tp->ranges_operator == 6 ) { /* x > a */
8517 /* hup the next one in b-tree order */
8518 err = rdfstore_flat_store_next((islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, key, &data);
8519 RDFSTORE_FREE(key.data); /* dispose the previous/current key */
8520 if (err == 0) {
8521 key = data;
8522 continue;
8523 } else {
8524 break;
8525 };
8526 };
8527 };
8528 } else {
8529 memcpy( adateval, key.data, key.size );
8530 if( strcmp( adateval, thedateval[0] ) == 0 ) {
8531 if( tp->ranges_operator == 6 ) { /* x > a */
8532 /* hup the next one in b-tree order */
8533 err = rdfstore_flat_store_next((islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, key, &data);
8534 RDFSTORE_FREE(key.data); /* dispose the previous/current key */
8535 if (err == 0) {
8536 key = data;
8537 continue;
8538 } else {
8539 break;
8540 };
8541 };
8542 };
8543 };
8544 err = rdfstore_flat_store_fetch( (islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, key, &data);
8545 if (err != 0) {
8546 if (err != FLAT_STORE_E_NOTFOUND) {
8547 perror("rdfstore_search");
8548 fprintf(stderr,"Could not fetch key '%s' for range for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error( (islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date ));
8549 rdfstore_iterator_close(results);
8550 return NULL;
8551 } else {
8552 continue;
8553 };
8554 } else {
8555 if (outsize3 > 0) {
8556 me->func_decode(data.size, data.data, &outsize2, me->bits_decode);
8557
8558 /* or each of them */
8559 outsize3 = rdfstore_bits_or(outsize3, bits2, outsize2, me->bits_decode, bits1);
8560
8561 outsize3 = rdfstore_bits_shorten(outsize3, bits1);
8562 bcopy(bits1, bits2, outsize3); /* slow? */
8563 } else {
8564 me->func_decode(data.size, data.data, &outsize3, bits2);
8565 };
8566 RDFSTORE_FREE(data.data);
8567 };
8568
8569 #ifdef RDFSTORE_DEBUG
8570 {
8571 int j;
8572 if(islval!=0) {
8573 printf("SEARCH '%ld' >%s '%ld' -->'", (long)alval, ( ( tp->ranges_operator == 5 ) ? "=" : "" ), (long)thelval[0]);
8574 } else if(isdval!=0) {
8575 printf("SEARCH '%f' >%s '%f' -->'", adval, ( ( tp->ranges_operator == 5 ) ? "=" : "" ), thedval[0]);
8576 } else {
8577 printf("SEARCH '%s' >%s '%s' -->'", adateval, ( ( tp->ranges_operator == 5 ) ? "=" : "" ), thedateval[0]);
8578 };
8579 for(j=0;j<8*outsize3;j++) {
8580 printf("Rec %d %c\n", j, (bits2[j>>3] & (1<<(j&7))) ? '1':'0');
8581 };
8582 printf("'\n");
8583 }
8584 #endif
8585
8586 /* hup the next one in b-tree order */
8587 err = rdfstore_flat_store_next((islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, key, &data);
8588 RDFSTORE_FREE(key.data); /* dispose the previous/current key */
8589 if (err == 0) {
8590 key = data;
8591 };
8592 } while (err == 0);
8593 };
8594 } else if ( ( tp->ranges_operator > 6 ) &&
8595 ( tp->ranges_operator < 11 ) ) { /* 2 vars ranges */
8596
8597 /* b > a || b >= a */
8598 if(islval!=0) {
8599 data.data = (long*) &thelval[0]; /* should pack int perhaps... */
8600 data.size = sizeof(long);
8601 } else if(isdval!=0) {
8602 data.data = (double*) &thedval[0]; /* should pack int perhaps... */
8603 data.size = sizeof(double);
8604 } else {
8605 data.data = thedateval[0];
8606 data.size = strlen(thedateval[0])+1;
8607 };
8608 if (rdfstore_flat_store_from( (islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, data, &key) == 0) {
8609 do {
8610 if(islval!=0) {
8611 memcpy( &alval, key.data, sizeof(long) );
8612 if( alval == thelval[0] ) {
8613 if( ( tp->ranges_operator == 7 ) ||
8614 ( tp->ranges_operator == 10 ) ) { /* x > a */
8615 /* hup the next one in b-tree order */
8616 err = rdfstore_flat_store_next((islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, key, &data);
8617 RDFSTORE_FREE(key.data); /* dispose the previous/current key */
8618 if (err == 0) {
8619 key = data;
8620 continue;
8621 } else {
8622 break;
8623 };
8624 };
8625 };
8626 } else if(isdval!=0) {
8627 memcpy( &adval, key.data, sizeof(double) );
8628 if( adval == thedval[0] ) {
8629 if( ( tp->ranges_operator == 7 ) ||
8630 ( tp->ranges_operator == 10 ) ) { /* x > a */
8631 /* hup the next one in b-tree order */
8632 err = rdfstore_flat_store_next((islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, key, &data);
8633 RDFSTORE_FREE(key.data); /* dispose the previous/current key */
8634 if (err == 0) {
8635 key = data;
8636 continue;
8637 } else {
8638 break;
8639 };
8640 };
8641 };
8642 } else {
8643 memcpy( adateval, key.data, key.size );
8644 if( strcmp( adateval, thedateval[0] ) == 0 ) {
8645 if( ( tp->ranges_operator == 7 ) ||
8646 ( tp->ranges_operator == 10 ) ) { /* x > a */
8647 /* hup the next one in b-tree order */
8648 err = rdfstore_flat_store_next((islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, key, &data);
8649 RDFSTORE_FREE(key.data); /* dispose the previous/current key */
8650 if (err == 0) {
8651 key = data;
8652 continue;
8653 } else {
8654 break;
8655 };
8656 };
8657 };
8658 };
8659 err = rdfstore_flat_store_fetch( (islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, key, &data);
8660 if (err != 0) {
8661 if (err != FLAT_STORE_E_NOTFOUND) {
8662 perror("rdfstore_search");
8663 fprintf(stderr,"Could not fetch key '%s' for range for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error( (islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date ));
8664 rdfstore_iterator_close(results);
8665 return NULL;
8666 } else {
8667 continue;
8668 };
8669 } else {
8670 if (outsize3 > 0) {
8671 me->func_decode(data.size, data.data, &outsize2, me->bits_decode);
8672
8673 /* or each of them */
8674 outsize3 = rdfstore_bits_or(outsize3, bits2, outsize2, me->bits_decode, bits1);
8675
8676 outsize3 = rdfstore_bits_shorten(outsize3, bits1);
8677 bcopy(bits1, bits2, outsize3); /* slow? */
8678 } else {
8679 me->func_decode(data.size, data.data, &outsize3, bits2);
8680 };
8681 RDFSTORE_FREE(data.data);
8682 };
8683
8684 #ifdef RDFSTORE_DEBUG
8685 {
8686 int j;
8687 if(islval!=0) {
8688 printf("SEARCH '%ld' >%s '%ld' -->'", (long)alval, ( ( ( tp->ranges_operator == 8 ) || ( tp->ranges_operator == 9 ) ) ? "=" : "" ), (long)thelval[0]);
8689 } else if(isdval!=0) {
8690 printf("SEARCH '%f' >%s '%f' -->'", adval, ( ( ( tp->ranges_operator == 8 ) || ( tp->ranges_operator == 9 ) ) ? "=" : "" ), thedval[0]);
8691 } else {
8692 printf("SEARCH '%s' >%s '%s' -->'", adateval, ( ( ( tp->ranges_operator == 8 ) || ( tp->ranges_operator == 9 ) ) ? "=" : "" ), thedateval[0]);
8693 };
8694 for(j=0;j<8*outsize3;j++) {
8695 printf("Rec %d %c\n", j, (bits2[j>>3] & (1<<(j&7))) ? '1':'0');
8696 };
8697 printf("'\n");
8698 }
8699 #endif
8700
8701 /* hup the next one in b-tree order */
8702 err = rdfstore_flat_store_next((islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, key, &data);
8703 RDFSTORE_FREE(key.data); /* dispose the previous/current key */
8704 if (err == 0) {
8705 key = data;
8706 };
8707 } while (err == 0);
8708 };
8709
8710 /* no matches */
8711 if (!outsize3)
8712 return results;
8713
8714 /* AND in all numerical comparinsons to previous rdf:datatype, words, subjects, predicates, objects and languages now */
8715 if (outsize1 > 0) {
8716 /* and them */
8717 outsize1 = rdfstore_bits_and(outsize1, bits, outsize3, bits2, bits1);
8718 outsize1 = rdfstore_bits_shorten(outsize1, bits1);
8719
8720 /* cannot join */
8721 if (!outsize1) {
8722 return results;
8723 };
8724
8725 bcopy(bits1, bits, outsize1); /* slow? */
8726 } else {
8727 /* or OR them */
8728 outsize1 = rdfstore_bits_or(outsize3, bits, outsize3, bits2, bits1);
8729 bcopy(bits1, bits, outsize3); /* slow? */
8730 };
8731
8732 /* b < c || b <= c */
8733 outsize3=0;
8734
8735 if (rdfstore_flat_store_first( (islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date , &key) == 0) {
8736 do {
8737 if(islval!=0) {
8738 memcpy( &alval, key.data, sizeof(long) );
8739 if( alval == thelval[1] ) {
8740 if( ( tp->ranges_operator == 9 ) ||
8741 ( tp->ranges_operator == 10 ) ) { /* x <= a */
8742 last=1;
8743 } else {
8744 RDFSTORE_FREE(key.data); /* dispose the key fetched above */
8745 break; /* stop here - anything from the first key till x (excluded) */
8746 };
8747 } else if ( alval > thelval[1] ) {
8748 RDFSTORE_FREE(key.data);
8749 break;
8750 };
8751 } else if(isdval!=0) {
8752 memcpy( &adval, key.data, sizeof(double) );
8753 if( adval == thedval[1] ) {
8754 if( ( tp->ranges_operator == 9 ) ||
8755 ( tp->ranges_operator == 10 ) ) { /* x <= a */
8756 last=1;
8757 } else {
8758 RDFSTORE_FREE(key.data); /* dispose the key fetched above */
8759 break; /* stop here - anything from the first key till x (excluded) */
8760 };
8761 } else if( adval > thedval[1] ) {
8762 RDFSTORE_FREE(key.data);
8763 break;
8764 };
8765 } else {
8766 memcpy( adateval, key.data, key.size );
8767 if( strcmp( adateval, thedateval[1] ) == 0 ) {
8768 if( ( tp->ranges_operator == 9 ) ||
8769 ( tp->ranges_operator == 10 ) ) { /* x <= a */
8770 last=1;
8771 } else {
8772 RDFSTORE_FREE(key.data); /* dispose the key fetched above */
8773 break; /* stop here - anything from the first key till x (excluded) */
8774 };
8775 } else if( strcmp( adateval, thedateval[1] ) > 0 ) {
8776 RDFSTORE_FREE(key.data);
8777 break;
8778 };
8779 };
8780 err = rdfstore_flat_store_fetch( (islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, key, &data);
8781 if (err != 0) {
8782 if (err != FLAT_STORE_E_NOTFOUND) {
8783 perror("rdfstore_search");
8784 fprintf(stderr,"Could not fetch key '%s' for range for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error( (islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date ));
8785 rdfstore_iterator_close(results);
8786 return NULL;
8787 } else {
8788 continue;
8789 };
8790 } else {
8791 if (outsize3 > 0) {
8792 me->func_decode(data.size, data.data, &outsize2, me->bits_decode);
8793
8794 /* or each of them */
8795 outsize3 = rdfstore_bits_or(outsize3, bits2, outsize2, me->bits_decode, bits1);
8796
8797 outsize3 = rdfstore_bits_shorten(outsize3, bits1);
8798 bcopy(bits1, bits2, outsize3); /* slow? */
8799 } else {
8800 me->func_decode(data.size, data.data, &outsize3, bits2);
8801 };
8802 RDFSTORE_FREE(data.data);
8803 };
8804
8805 #ifdef RDFSTORE_DEBUG
8806 {
8807 int j;
8808 if(islval!=0) {
8809 printf("SEARCH '%ld' <%s '%ld' -->'", (long)alval, ( ( ( tp->ranges_operator == 9 ) || ( tp->ranges_operator == 10 ) ) ? "=" : "" ), (long)thelval[1]);
8810 } else if(isdval!=0) {
8811 printf("SEARCH '%f' <%s '%f' -->'", adval, ( ( ( tp->ranges_operator == 9 ) || ( tp->ranges_operator == 10 ) ) ? "=" : "" ), thedval[1]);
8812 } else {
8813 printf("SEARCH '%s' <%s '%s' -->'", adateval, ( ( ( tp->ranges_operator == 9 ) || ( tp->ranges_operator == 10 ) ) ? "=" : "" ), thedateval[1]);
8814 };
8815 for(j=0;j<8*outsize3;j++) {
8816 printf("Rec %d %c\n", j, (bits2[j>>3] & (1<<(j&7))) ? '1':'0');
8817 };
8818 printf("'\n");
8819 }
8820 #endif
8821
8822 if(last) {
8823 RDFSTORE_FREE(key.data); /* dispose the key fetched above */
8824 break; /* x <= a */
8825 };
8826
8827 /* hup the next one in b-tree order */
8828 err = rdfstore_flat_store_next((islval!=0) ? me->xsd_integer : (isdval!=0) ? me->xsd_double : me->xsd_date, key, &data);
8829 RDFSTORE_FREE(key.data); /* dispose the previous/current key */
8830 if (err == 0) {
8831 key = data;
8832 };
8833 } while (err == 0);
8834 };
8835 };
8836
8837 /* no matches */
8838 if (!outsize3)
8839 return results;
8840
8841 /* AND in all numerical comparinsons to previous rdf:datatype, words, subjects, predicates, objects and languages now */
8842 if (outsize1 > 0) {
8843 /* and them */
8844 outsize1 = rdfstore_bits_and(outsize1, bits, outsize3, bits2, bits1);
8845 outsize1 = rdfstore_bits_shorten(outsize1, bits1);
8846
8847 /* cannot join */
8848 if (!outsize1) {
8849 return results;
8850 };
8851
8852 bcopy(bits1, bits, outsize1); /* slow? */
8853 } else {
8854 /* or OR them */
8855 outsize1 = rdfstore_bits_or(outsize3, bits, outsize3, bits2, bits1);
8856 bcopy(bits1, bits, outsize3); /* slow? */
8857 };
8858
8859 #ifdef RDFSTORE_DEBUG
8860 {
8861 int j;
8862 if(islval!=0) {
8863 printf("SEARCH X %s '%ld' -->'", (tp->ranges_operator ==1) ? "<" :
8864 (tp->ranges_operator ==2) ? "<=" :
8865 (tp->ranges_operator ==3) ? "==" :
8866 (tp->ranges_operator ==4) ? "!=" :
8867 (tp->ranges_operator ==5) ? ">=":
8868 (tp->ranges_operator ==6) ? ">":
8869 (tp->ranges_operator ==7) ? "a < b < c":
8870 (tp->ranges_operator ==8) ? "a <= b < c":
8871 (tp->ranges_operator ==9) ? "a <= b <= c": "a < b <= c", (long)thelval[0]);
8872 } else {
8873 printf("SEARCH X %s '%f' -->'", (tp->ranges_operator ==1) ? "<" :
8874 (tp->ranges_operator ==2) ? "<=" :
8875 (tp->ranges_operator ==3) ? "==" :
8876 (tp->ranges_operator ==4) ? "!=" :
8877 (tp->ranges_operator ==5) ? ">=":
8878 (tp->ranges_operator ==6) ? ">":
8879 (tp->ranges_operator ==7) ? "a < b < c":
8880 (tp->ranges_operator ==8) ? "a <= b < c":
8881 (tp->ranges_operator ==9) ? "a <= b <= c": "a < b <= c", thedval[0]);
8882 };
8883 for(j=0;j<8*outsize1;j++) {
8884 printf("Rec %d %c\n", j, (bits[j>>3] & (1<<(j&7))) ? '1':'0');
8885 };
8886 printf("'\n");
8887 }
8888 #endif
8889 };
8890 };
8891
8892 if ( tp->contexts != NULL ) {
8893 outsize3=0;
8894 tpj = tp->contexts;
8895 do {
8896
8897 /* compute subject hashcode */
8898 tpj->part.node->hashcode = rdfstore_digest_get_node_hashCode(tpj->part.node, 0);
8899
8900 packInt(tpj->part.node->hashcode, outbuf);
8901 key.data = outbuf;
8902 key.size = sizeof(int);
8903
8904 err = rdfstore_flat_store_fetch(me->contexts, key, &data);
8905 if (err != 0) {
8906 if (err != FLAT_STORE_E_NOTFOUND) {
8907 perror("rdfstore_search");
8908 fprintf(stderr,"Could not fetch key '%s' in contexts for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->contexts));
8909 rdfstore_iterator_close(results);
8910 return NULL;
8911 } else {
8912 continue;
8913 };
8914 } else {
8915 if (outsize3 > 0) {
8916 me->func_decode(data.size, data.data, &outsize2, me->bits_decode);
8917
8918 if (tp->contexts_operator == 1) {
8919 /* and them i.e. URL1, URL2, URL3....URLn */
8920 outsize3 = rdfstore_bits_and(outsize3, bits2, outsize2, me->bits_decode, bits1);
8921 } else if (tp->contexts_operator == 0) {
8922 /* or them i.e. URL1, URL2, URL3....URLn */
8923 outsize3 = rdfstore_bits_or(outsize3, bits2, outsize2, me->bits_decode, bits1);
8924 } else if (tp->contexts_operator == 2) {
8925 fprintf(stderr,"The boolean NOT operator on contexts is not implemented yet :)\n");
8926 };
8927
8928 outsize3 = rdfstore_bits_shorten(outsize3, bits1);
8929 bcopy(bits1, bits2, outsize3); /* slow? */
8930 } else {
8931 me->func_decode(data.size, data.data, &outsize3, bits2);
8932 };
8933 RDFSTORE_FREE(data.data);
8934 };
8935
8936 #ifdef RDFSTORE_DEBUG
8937 {
8938 int j;
8939 printf("SEARCH contexts[%d] for C -->'",i);
8940 for(j=0;j<8*outsize3;j++) {
8941 printf("Rec %d %c\n", j, (bits2[j>>3] & (1<<(j&7))) ? '1':'0');
8942 };
8943 printf("'\n");
8944 }
8945 #endif
8946 } while ( ( tpj = tpj->next ) != NULL );
8947
8948 /* no contexts matched? */
8949 if (!outsize3)
8950 return results;
8951
8952 /* AND in all contexts to previous words now */
8953 if (outsize1 > 0) {
8954 /* and them */
8955 outsize1 = rdfstore_bits_and(outsize1, bits, outsize3, bits2, bits1);
8956 outsize1 = rdfstore_bits_shorten(outsize1, bits1);
8957
8958 /* cannot join */
8959 if (!outsize1) {
8960 return results;
8961 };
8962 bcopy(bits1, bits, outsize1); /* slow? */
8963 } else {
8964 outsize1=outsize3;
8965 bcopy(bits2, bits, outsize3); /* slow? */
8966 };
8967
8968 #ifdef RDFSTORE_DEBUG
8969 {
8970 int j;
8971 printf("SEARCH contexts for C -->'");
8972 for(j=0;j<8*outsize1;j++) {
8973 printf("Rec %d %c\n", j, (bits[j>>3] & (1<<(j&7))) ? '1':'0');
8974 };
8975 printf("'\n");
8976 }
8977 #endif
8978 };
8979
8980 #ifdef RDFSTORE_DEBUG
8981 {
8982 int i;
8983 printf("SEARCH (whole) -->'");
8984 for(i=0;i<8*outsize1;i++) {
8985 printf("Rec %d %c\n", i, (bits[i>>3] & (1<<(i&7))) ? '1':'0');
8986 };
8987 printf("'\n");
8988 }
8989 #endif
8990
8991 /* just copy the bits through the iterator array */
8992 memcpy(results->ids, bits, outsize1);
8993 results->ids_size = outsize1;
8994 /*
8995 * just copy the bits through the iterator array shifting them to the
8996 * right position (odd or even)
8997 */
8998 pos = 0;
8999 /* count the ones (inefficient still) */
9000 while ((pos = rdfstore_bits_getfirstsetafter(outsize1, bits, pos)) < 8 * outsize1) {
9001 results->size++;
9002 pos++;
9003 };
9004
9005 #ifdef RDFSTORE_DEBUG
9006 {
9007 printf("Actually matched (bits only) '");
9008 for(i=0;i<8*results->ids_size;i++) {
9009 printf("%c", (results->ids[i>>3] & (1<<(i&7))) ? '1':'0');
9010 };
9011 printf("' (%d/%d)\n", results->ids_size, results->size);
9012 }
9013 {
9014 RDF_Statement *r;
9015 rdfstore_iterator *results1;
9016 printf("search MATCHED (statements) :\n");
9017 results1 = rdfstore_iterator_duplicate(results);
9018 for (r = rdfstore_iterator_first(results1);
9019 rdfstore_iterator_hasnext(results1);
9020 r = rdfstore_iterator_next(results1)) {
9021 fprintf(stderr,"\tS='%s'\n", r->subject->value.resource.identifier);
9022 fprintf(stderr,"\tP='%s'\n", r->predicate->value.resource.identifier);
9023 if (r->object->type != 1) {
9024 fprintf(stderr,"\tO='%s'\n", r->object->value.resource.identifier);
9025 } else {
9026 fprintf(stderr,"\tOLIT='%s'", r->object->value.literal.string);
9027 fprintf(stderr," LANG='%s'", r->object->value.literal.lang);
9028 fprintf(stderr," TYPE='%s'", r->object->value.literal.dataType);
9029 fprintf(stderr," PARSETYPE='%d'", r->object->value.literal.parseType);
9030 fprintf(stderr,"\n");
9031 };
9032 };
9033 rdfstore_iterator_close(results1);
9034 };
9035 #endif
9036
9037 return results; /* we should distinguish between errors and
9038 * empty return values in a future version */
9039 };
9040
9041 /*
9042 * "get all relevant RDF about this thing in the repository"
9043 *
9044 * i.e. get a "concise bounded description" of a given resource/thing
9045 *
9046 * Given a URI denoting some resource, a concise bounded description of that resource is a set of RDF statements,
9047 * explicitly asserted and/or inferred, comprised of the following:
9048 *
9049 * 1. All statements where the subject of the statement denotes the resource in question; and
9050 *
9051 * 2. Recursively, for all statements included in the description thus far, for all anonymous node objects,
9052 * all statements where the subject of the statement denotes anonymous resource in question; and
9053 *
9054 * 3. Recursively, for all statements included in the description thus far, for all reifications of each statement,
9055 * the concise bounded description of each reification.
9056 *
9057 * This results in an RDF graph where the terminal nodes are either URI references, literals, or anonymous nodes not
9058 * serving as the subject of any statement, insofar as the describing agent is aware; effectively constraining the description
9059 * to only those statements made explicitly about the resource in question or about other directly related anonymous resources,
9060 * and any associated reifications. (http://sw.nokia.com/uriqa/URIQA.html)
9061 *
9062 * see also http://www.joseki.org/RDF_data_objects.html and http://lists.w3.org/Archives/Public/www-rdf-dspace/2003Jun/0047.html
9063 *
9064 * NOTE: once connections table will be place this operations should be carried out much more efficently
9065 *
9066 */
9067
9068 int
_rdfstore_recursive_fetch_object(rdfstore * me,RDF_Node * resource,unsigned char * given_context,unsigned int given_context_size,int level,rdfstore_iterator * out)9069 _rdfstore_recursive_fetch_object( rdfstore * me,
9070 RDF_Node * resource,
9071 unsigned char * given_context,
9072 unsigned int given_context_size,
9073 int level, rdfstore_iterator * out ) {
9074 rdfstore_iterator *subject_results;
9075 DBT key;
9076 int err = 0;
9077 unsigned int outsize = 0;
9078 unsigned char outbuf[256];
9079 RDF_Node *sub_object = NULL;
9080
9081 if(level==RDFSTORE_MAX_FETCH_OBJECT_DEEPNESS) { /* fire safe :) */
9082 return 0;
9083 };
9084
9085 memset(&key, 0, sizeof(key));
9086
9087 subject_results = (rdfstore_iterator *) RDFSTORE_MALLOC(sizeof(rdfstore_iterator));
9088 if (subject_results == NULL) {
9089 perror("recursive_fetch_object");
9090 fprintf(stderr,"Cannot create results cursor/iterator for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
9091 return -1;
9092 };
9093 subject_results->store = me;
9094 subject_results->store->attached++;
9095 /* bzero(subject_results->ids,sizeof(unsigned char)*(RDFSTORE_MAXRECORDS_BYTES_SIZE)); */
9096 subject_results->remove_holes = 0; /* reset the total number of holes */
9097 subject_results->st_counter = 0;
9098 subject_results->pos = 0;
9099 subject_results->ids_size = 0;
9100 subject_results->size = 0;
9101
9102 /* compute subject hashcode */
9103 resource->hashcode = rdfstore_digest_get_node_hashCode(resource, 0);
9104
9105 packInt(resource->hashcode, outbuf);
9106 key.data = outbuf;
9107 key.size = sizeof(int);
9108
9109 err = rdfstore_flat_store_fetch_compressed(me->subjects, me->func_decode, key, &outsize, me->bits_decode);
9110 if (err != 0) {
9111 if (err != FLAT_STORE_E_NOTFOUND) {
9112 perror("recursive_fetch_object");
9113 fprintf(stderr,"Could not fetch subject resource '%s' for store '%s': %s\n", resource->value.resource.identifier, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->subjects));
9114 rdfstore_iterator_close(subject_results);
9115 return -1;
9116 } else {
9117 outsize = 0;
9118 };
9119 };
9120
9121 /* just keep the ones not visited to avoid recursion i.e. bits set in subjects but not set in out */
9122 subject_results->ids_size = rdfstore_bits_exor( outsize, me->bits_decode, out->ids_size, out->ids, subject_results->ids );
9123
9124 if( ( given_context != NULL ) &&
9125 ( given_context_size > 0 ) ) {
9126 /* AND context constraint if passed */
9127 subject_results->ids_size = rdfstore_bits_and( subject_results->ids_size, subject_results->ids,
9128 given_context_size, given_context, me->bits_decode );
9129 bcopy(me->bits_decode, subject_results->ids, subject_results->ids_size);
9130 };
9131 subject_results->ids_size = rdfstore_bits_shorten( subject_results->ids_size, subject_results->ids);
9132
9133 /* count the ones (inefficient still) */
9134 subject_results->size = 0;
9135 subject_results->pos = 0;
9136 while ( (subject_results->pos = rdfstore_bits_getfirstsetafter(subject_results->ids_size,
9137 subject_results->ids, subject_results->pos)) < 8*(subject_results->ids_size) ) {
9138 subject_results->pos++;
9139 subject_results->size++;
9140 };
9141 subject_results->pos = 0;
9142
9143 /* scan the obtained iterator */
9144 while ( ( sub_object = rdfstore_iterator_each_object ( subject_results ) ) != NULL ) {
9145 if ( sub_object->type == 2 ) {
9146 if ( _rdfstore_recursive_fetch_object( me, sub_object, given_context, given_context_size,
9147 level+1, out ) == -1 ) {/* recurse */
9148 if ( sub_object->type == 1 ) {
9149 if ( sub_object->value.literal.dataType != NULL )
9150 RDFSTORE_FREE( sub_object->value.literal.dataType );
9151 RDFSTORE_FREE( sub_object->value.literal.string );
9152 } else {
9153 RDFSTORE_FREE( sub_object->value.resource.identifier );
9154 };
9155 RDFSTORE_FREE( sub_object );
9156 rdfstore_iterator_close(subject_results);
9157 return -1;
9158 };
9159 };
9160
9161 #ifdef RDFSTORE_DEBUG
9162 if (sub_object->type != 1) {
9163 fprintf(stderr,"\t>>>GOT OBJECT='%s'\n", sub_object->value.resource.identifier);
9164 } else {
9165 fprintf(stderr,"\t>>>GOT OLIT='%s'", sub_object->value.literal.string);
9166 fprintf(stderr," LANG='%s'", sub_object->value.literal.lang);
9167 fprintf(stderr," TYPE='%s'", sub_object->value.literal.dataType);
9168 fprintf(stderr," PARSETYPE='%d'", sub_object->value.literal.parseType);
9169 fprintf(stderr,"\n");
9170 };
9171 #endif
9172
9173 if ( sub_object->type == 1 ) {
9174 if ( sub_object->value.literal.dataType != NULL )
9175 RDFSTORE_FREE( sub_object->value.literal.dataType );
9176 RDFSTORE_FREE( sub_object->value.literal.string );
9177 } else {
9178 RDFSTORE_FREE( sub_object->value.resource.identifier );
9179 };
9180 RDFSTORE_FREE( sub_object );
9181 };
9182
9183 /* add the processed ones to out (main results) */
9184 out->ids_size = rdfstore_bits_or( out->ids_size, out->ids, subject_results->ids_size, subject_results->ids, me->bits_decode );
9185 bcopy(me->bits_decode, out->ids, out->ids_size);
9186
9187 /* count the ones (inefficient still) */
9188 out->size = 0;
9189 out->pos = 0;
9190 while ( (out->pos = rdfstore_bits_getfirstsetafter(out->ids_size, out->ids, out->pos)) < 8*(out->ids_size) ) {
9191 out->pos++;
9192 out->size++;
9193 };
9194 out->pos = 0;
9195
9196 rdfstore_iterator_close(subject_results);
9197
9198 return 0;
9199 };
9200
9201 /*
9202 Work in progress implementation of http://www.w3.org/Submission/CBD/ - it does not implement "Inverse Functional Bounded Description" yet
9203 See also http://www.w3.org/TR/rdf-sparql-query/#describe
9204 */
9205 rdfstore_iterator *
rdfstore_fetch_object(rdfstore * me,RDF_Node * resource,RDF_Node * given_context)9206 rdfstore_fetch_object( rdfstore * me, RDF_Node * resource, RDF_Node * given_context ) {
9207 RDF_Node *context = NULL;
9208 rdfstore_iterator *results;
9209 DBT key;
9210 int err = 0;
9211 unsigned int context_outsize = 0;
9212 unsigned char outbuf[256];
9213 static unsigned char bits[RDFSTORE_MAXRECORDS_BYTES_SIZE];
9214
9215 /* just start from a resource (URI or bNode) and follow its associated bNodes (connected to its statements) */
9216 if ( (resource == NULL) ||
9217 (resource->type == RDFSTORE_NODE_TYPE_LITERAL) ||
9218 (resource->value.resource.identifier == NULL) ||
9219 ( (given_context != NULL) &&
9220 (given_context->value.resource.identifier == NULL)) )
9221 return NULL;
9222
9223 /* use given context instead */
9224 context = given_context;
9225
9226 memset(&key, 0, sizeof(key));
9227
9228 if(context!=NULL) {
9229 /* compute context hashcode */
9230 context->hashcode = rdfstore_digest_get_node_hashCode(context, 0);
9231
9232 packInt(context->hashcode, outbuf);
9233 key.data = outbuf;
9234 key.size = sizeof(int);
9235
9236 err = rdfstore_flat_store_fetch_compressed(me->contexts, me->func_decode, key, &context_outsize, me->bits_decode);
9237 if (err != 0) {
9238 if (err != FLAT_STORE_E_NOTFOUND) {
9239 perror("rdfstore_fetch_object");
9240 fprintf(stderr,"Could not fetch context resource '%s' for store '%s': %s\n", context->value.resource.identifier, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->contexts));
9241 return NULL;
9242 } else {
9243 context_outsize = 0;
9244 };
9245 };
9246 bcopy(me->bits_decode, bits, context_outsize);
9247 };
9248
9249 results = (rdfstore_iterator *) RDFSTORE_MALLOC(sizeof(rdfstore_iterator));
9250 if (results == NULL) {
9251 perror("rdfstore_fetch_object");
9252 fprintf(stderr,"Cannot create results cursor/iterator for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
9253 return NULL;
9254 };
9255 results->store = me;
9256 results->store->attached++;
9257 /*bzero(results->ids,sizeof(unsigned char)*(RDFSTORE_MAXRECORDS_BYTES_SIZE));*/
9258 results->remove_holes = 0; /* reset the total number of holes */
9259 results->st_counter = 0;
9260 results->pos = 0;
9261 results->ids_size = 0;
9262 results->size = 0;
9263
9264 #ifdef RDFSTORE_DEBUG
9265 {
9266 char *buff;
9267 fprintf(stderr,"FETCH OBJECT:\n");
9268 fprintf(stderr,"\tresource='%s'\n", resource->value.resource.identifier);
9269 if (context != NULL) {
9270 fprintf(stderr,"\tC='%s'\n", context->value.resource.identifier);
9271 };
9272 if ((buff = rdfstore_ntriples_node(resource)) != NULL) {
9273 fprintf(stderr," Resource (N-Triples part): %s\n", buff);
9274 RDFSTORE_FREE(buff);
9275 };
9276 }
9277 #endif
9278
9279 if( (context!=NULL) &&
9280 (context_outsize==0) )
9281 return results; /* empty */
9282
9283 /* start visiting the graph from this subject resource downwards... */
9284 if ( _rdfstore_recursive_fetch_object( me, resource, ((context!=NULL) ? bits : NULL ), ((context!=NULL) ? context_outsize : 0 ),
9285 0, results ) == -1 ) {
9286 rdfstore_iterator_close(results);
9287 return NULL;
9288 };
9289
9290 #ifdef RDFSTORE_DEBUG
9291 {
9292 int i=0;
9293 printf("Actually matched (bits only) '");
9294 for(i=0;i<8*results->ids_size;i++) {
9295 printf("%c", (results->ids[i>>3] & (1<<(i&7))) ? '1':'0');
9296 };
9297 printf("' (%d/%d)\n", results->ids_size, results->size);
9298 }
9299 {
9300 RDF_Statement *r;
9301 rdfstore_iterator *results1;
9302 printf("fetch_object MATCHED (statements) :\n");
9303 results1 = rdfstore_iterator_duplicate(results);
9304 for (r = rdfstore_iterator_first(results1);
9305 rdfstore_iterator_hasnext(results1);
9306 r = rdfstore_iterator_next(results1)) {
9307 fprintf(stderr,"\tS='%s'\n", r->subject->value.resource.identifier);
9308 fprintf(stderr,"\tP='%s'\n", r->predicate->value.resource.identifier);
9309 if (r->object->type != 1) {
9310 fprintf(stderr,"\tO='%s'\n", r->object->value.resource.identifier);
9311 } else {
9312 fprintf(stderr,"\tOLIT='%s'", r->object->value.literal.string);
9313 fprintf(stderr," LANG='%s'", r->object->value.literal.lang);
9314 fprintf(stderr," TYPE='%s'", r->object->value.literal.dataType);
9315 fprintf(stderr," PARSETYPE='%d'", r->object->value.literal.parseType);
9316 fprintf(stderr,"\n");
9317 };
9318 };
9319 rdfstore_iterator_close(results1);
9320 };
9321 #endif
9322
9323 return results;
9324 };
9325
9326 /* end fetch object */
9327
9328 /* return != 0 if not contained */
9329 int
rdfstore_contains(rdfstore * me,RDF_Statement * statement,RDF_Node * given_context)9330 rdfstore_contains(
9331 rdfstore * me,
9332 RDF_Statement * statement,
9333 RDF_Node * given_context
9334 )
9335 {
9336 RDF_Node *context = NULL;
9337 int err = 0;
9338 rdf_store_digest_t hc = 0;
9339 DBT key, data;
9340 unsigned char outbuf[256];
9341
9342 if ((statement == NULL) ||
9343 (statement->subject == NULL) ||
9344 (statement->predicate == NULL) ||
9345 (statement->subject->value.resource.identifier == NULL) ||
9346 (statement->predicate->value.resource.identifier == NULL) ||
9347 (statement->object == NULL) ||
9348 ((statement->object->type != 1) &&
9349 (statement->object->value.resource.identifier == NULL)) ||
9350 ((given_context != NULL) &&
9351 (given_context->value.resource.identifier == NULL)) ||
9352 ((statement->node != NULL) &&
9353 (statement->node->value.resource.identifier == NULL)))
9354 return -1;
9355
9356 if (given_context == NULL) {
9357 if (statement->context != NULL)
9358 context = statement->context;
9359 } else {
9360 /* use given context instead */
9361 context = given_context;
9362 };
9363
9364 #ifdef RDFSTORE_DEBUG
9365 {
9366 char *buff;
9367 fprintf(stderr,"CONTAINS:\n");
9368 fprintf(stderr,"\tS='%s'\n", statement->subject->value.resource.identifier);
9369 fprintf(stderr,"\tP='%s'\n", statement->predicate->value.resource.identifier);
9370 if (statement->object->type != 1) {
9371 fprintf(stderr,"\tO='%s'\n", statement->object->value.resource.identifier);
9372 } else {
9373 fprintf(stderr,"\tOLIT='%s'", statement->object->value.literal.string);
9374 fprintf(stderr," LANG='%s'", statement->object->value.literal.lang);
9375 fprintf(stderr," TYPE='%s'", statement->object->value.literal.dataType);
9376 fprintf(stderr," PARSETYPE='%d'", statement->object->value.literal.parseType);
9377 fprintf(stderr,"\n");
9378 };
9379 if (context != NULL) {
9380 fprintf(stderr,"\tC='%s'\n", context->value.resource.identifier);
9381 };
9382 if (statement->node != NULL)
9383 fprintf(stderr,"\tSRES='%s'\n", statement->node->value.resource.identifier);
9384 if ((buff = rdfstore_ntriples_statement(statement, context)) != NULL) {
9385 fprintf(stderr," N-triples: %s\n", buff);
9386 RDFSTORE_FREE(buff);
9387 };
9388 }
9389 #endif
9390
9391 memset(&key, 0, sizeof(key));
9392 memset(&data, 0, sizeof(data));
9393
9394 /* compute statement hashcode */
9395 hc = rdfstore_digest_get_statement_hashCode(statement, context);
9396
9397 /* cache the hashcode if the statement has a "proper" identity */
9398 if ((given_context == NULL) &&
9399 (me->context == NULL))
9400 statement->hashcode = hc;
9401
9402 /* look for the statement internal identifier */
9403 packInt(hc, outbuf);
9404
9405 #ifdef RDFSTORE_DEBUG
9406 {
9407 int i = 0;
9408 printf("Statement hashcode is '%d' while packed is '", hc);
9409 for (i = 0; i < sizeof(int); i++) {
9410 printf("%02X", outbuf[i]);
9411 };
9412 printf("'\n");
9413 }
9414 #endif
9415
9416 key.data = outbuf;
9417 key.size = sizeof(int);
9418 err = rdfstore_flat_store_fetch(me->statements, key, &data);
9419 if (err != 0) {
9420 if (err != FLAT_STORE_E_NOTFOUND) {
9421 perror("rdfstore_contains");
9422 fprintf(stderr,"Could not fetch key '%s' in statements for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->statements));
9423 return -1;
9424 } else {
9425 #ifdef RDFSTORE_DEBUG
9426 {
9427 char *buff;
9428 if ((buff = rdfstore_ntriples_statement(statement, context)) != NULL) {
9429 fprintf(stderr,"Statement %s is NOT contained\n", buff);
9430 RDFSTORE_FREE(buff);
9431 };
9432 };
9433 #endif
9434 return 1;
9435 };
9436 } else {
9437 RDFSTORE_FREE(data.data);
9438 return 0;
9439 };
9440 };
9441
9442 /*
9443 * set a context for the statements (i.e. each asserted statement will get
9444 * such a context automatically by insert() ) NOTE: this stuff I can not
9445 * still understand how could be related to reification/logic/inference but
9446 * it should...
9447 */
9448 int
rdfstore_set_context(rdfstore * me,RDF_Node * given_context)9449 rdfstore_set_context(
9450 rdfstore * me,
9451 RDF_Node * given_context
9452 )
9453 {
9454 int i = 0;
9455
9456 /*
9457 * NOTE: bear in mind that here we use a ref/pointer instead to
9458 * really allocate and copy the stuff across; correct??
9459 */
9460 if ((me->context == NULL) && /* we explicitly need to reset_context() first if need to replace the current one */
9461 (given_context != NULL)) {
9462
9463 #ifdef RDFSTORE_DEBUG
9464 fprintf(stderr,"SET CONTEXT:\n");
9465 fprintf(stderr,"\tC='%s'\n", given_context->value.resource.identifier);
9466 #endif
9467
9468 me->context = (RDF_Node *) RDFSTORE_MALLOC(sizeof(RDF_Node));
9469 if (me->context == NULL) {
9470 perror("rdfstore_set_context");
9471 fprintf(stderr,"Cannot set statement context for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
9472 return -1;
9473 };
9474 me->context->hashcode = 0;
9475 me->context->type = given_context->type;
9476
9477 me->context->value.resource.identifier = NULL;
9478 me->context->value.resource.identifier = (char *)RDFSTORE_MALLOC(sizeof(char) * (given_context->value.resource.identifier_len + 1));
9479 if (me->context->value.resource.identifier == NULL) {
9480 perror("rdfstore_set_context");
9481 fprintf(stderr,"Cannot set statement context for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
9482 RDFSTORE_FREE(me->context);
9483 return -1;
9484 };
9485 i = 0;
9486 memcpy(me->context->value.resource.identifier + i, given_context->value.resource.identifier, given_context->value.resource.identifier_len);
9487 i += given_context->value.resource.identifier_len;
9488 memcpy(me->context->value.resource.identifier + i, "\0", 1);
9489 i++;
9490 me->context->value.resource.identifier_len = given_context->value.resource.identifier_len;
9491
9492 return 0;
9493 } else {
9494 return 1;
9495 };
9496 };
9497
9498 /*
9499 * reset the context for the statements (i.e. each asserted statement will be
9500 * put in no context by insert() unless specified )
9501 */
9502 int
rdfstore_reset_context(rdfstore * me)9503 rdfstore_reset_context(
9504 rdfstore * me
9505 )
9506 {
9507
9508 if (me->context != NULL) {
9509 RDFSTORE_FREE(me->context->value.resource.identifier);
9510 RDFSTORE_FREE(me->context);
9511 } else {
9512 return 1;
9513 };
9514
9515 me->context = NULL;
9516
9517 return 0;
9518 };
9519
9520 /* return actual defined context of the model */
9521 RDF_Node *
rdfstore_get_context(rdfstore * me)9522 rdfstore_get_context(
9523 rdfstore * me
9524 )
9525 {
9526 if (me->context != NULL) {
9527 return me->context;
9528 } else {
9529 return NULL;
9530 };
9531 };
9532
9533 int
rdfstore_set_source_uri(rdfstore * me,char * uri)9534 rdfstore_set_source_uri(
9535 rdfstore * me,
9536 char *uri
9537 )
9538 {
9539 DBT key, data;
9540 int err;
9541
9542 memset(&key, 0, sizeof(key));
9543 memset(&data, 0, sizeof(data));
9544
9545 if ((uri != NULL) &&
9546 (strlen(uri) > 0)) {
9547 key.data = "uri";
9548 key.size = sizeof("uri");
9549 data.data = uri;
9550 data.size = strlen(uri) + 1;
9551 err = rdfstore_flat_store_store(me->model, key, data);
9552 if ((err != 0) &&
9553 (err != FLAT_STORE_E_KEYEXIST)) {
9554 perror("rdfstore_set_source_uri");
9555 fprintf(stderr,"Could not store '%d' bytes for key '%s' in model for store '%s': %s\n", (int)data.size, (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->model));
9556 return -1;
9557 };
9558 strcpy(me->uri, data.data);
9559
9560 return 0;
9561 } else {
9562 return -1;
9563 };
9564 };
9565
9566 int
rdfstore_get_source_uri(rdfstore * me,char * uri)9567 rdfstore_get_source_uri(
9568 rdfstore * me,
9569 char *uri
9570 )
9571 {
9572 DBT key, data;
9573
9574 memset(&key, 0, sizeof(key));
9575 memset(&data, 0, sizeof(data));
9576
9577 key.data = "uri";
9578 key.size = sizeof("uri");
9579 if ((rdfstore_flat_store_fetch(me->model, key, &data)) == 0) {
9580 strcpy(uri, data.data);
9581 strcpy(me->uri, data.data);
9582
9583 RDFSTORE_FREE(data.data);
9584
9585 return 0;
9586 } else {
9587 return -1;
9588 };
9589 };
9590
9591 /* return 0 if the store is empty */
9592 int
rdfstore_is_empty(rdfstore * me)9593 rdfstore_is_empty(
9594 rdfstore * me
9595 )
9596 {
9597 unsigned int size;
9598
9599 if (rdfstore_size(me, &size)) {
9600 perror("rdfstore_is_empty");
9601 fprintf(stderr,"Could carry out model size for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
9602 return -1;
9603 };
9604
9605 return (size > 0) ? 1 : 0;
9606 };
9607
9608 /*
9609 * return a statement iterator; the returned object must be garbage-collected
9610 * by the caller via rdfstore_iterator_close()
9611 */
9612 rdfstore_iterator *
rdfstore_elements(rdfstore * me)9613 rdfstore_elements(
9614 rdfstore * me
9615 )
9616 {
9617 rdfstore_iterator *cursor;
9618 DBT key, data;
9619 int retval = 0;
9620 unsigned int st_id = 0;
9621
9622 memset(&key, 0, sizeof(key));
9623 memset(&data, 0, sizeof(data));
9624
9625 cursor = (rdfstore_iterator *) RDFSTORE_MALLOC(sizeof(rdfstore_iterator));
9626 if (cursor == NULL) {
9627 perror("rdfstore_elements");
9628 fprintf(stderr,"Cannot create elements cursor/iterator for store '%s'\n", (me->name != NULL) ? me->name : "(in-memory)");
9629 return NULL;
9630 };
9631 cursor->store = me;
9632 me->attached++;
9633
9634 /* bzero(cursor->ids,sizeof(unsigned char)*(RDFSTORE_MAXRECORDS_BYTES_SIZE)); */
9635 cursor->size = 0;
9636 cursor->remove_holes = 0; /* reset the total of holes */
9637 cursor->st_counter = 0;
9638 cursor->pos = 0;
9639 cursor->ids_size = 0;
9640
9641 if (rdfstore_flat_store_first(me->statements, &key) == 0) {
9642 do {
9643 retval = 0;
9644 if (rdfstore_flat_store_fetch(me->statements, key, &data) == 0) {
9645 unpackInt(data.data, &st_id);
9646 RDFSTORE_FREE(data.data);
9647
9648 /*
9649 * not sure rdfstore_bits_setmask() actually
9650 * sets ids_size right.....
9651 */
9652 rdfstore_bits_setmask(&cursor->ids_size, cursor->ids, st_id, 1, 1, sizeof(cursor->ids));
9653
9654 cursor->size++;
9655 } else {
9656 RDFSTORE_FREE(key.data);
9657 RDFSTORE_FREE(cursor);
9658 perror("rdfstore_elements");
9659 fprintf(stderr,"Could not fetch key '%s' in statements for store '%s': %s\n", (char *)key.data, (me->name != NULL) ? me->name : "(in-memory)", rdfstore_flat_store_get_error(me->statements));
9660 return NULL;
9661 };
9662 /* set the right bit */
9663 retval = rdfstore_flat_store_next(me->statements, key, &data);
9664 RDFSTORE_FREE(key.data); /* dispose the key
9665 * fetched above */
9666 if (retval == 0) {
9667 key = rdfstore_flat_store_kvdup(me->statements, data);
9668 RDFSTORE_FREE(data.data);
9669 };
9670 } while (retval == 0);
9671 };
9672
9673 #ifdef RDFSTORE_DEBUG
9674 {
9675 register int i;
9676 printf("Actually matched (bits only) '");
9677 for(i=0;i<8*cursor->ids_size;i++) {
9678 printf("%c", (cursor->ids[i>>3] & (1<<(i&7))) ? '1':'0');
9679 };
9680 printf("' (%d)\n", cursor->ids_size);
9681 }
9682 #endif
9683
9684 return cursor;
9685 };
9686
9687 #ifndef packInt
9688 /* pack the integer */
9689 void
packInt(uint32_t value,unsigned char * buffer)9690 packInt(uint32_t value, unsigned char *buffer)
9691 {
9692 /* bzero(buffer, sizeof(int)); */
9693 *(uint32_t *)buffer=htonl(value);
9694 }
9695 #endif
9696
9697 #ifndef unpackInt
9698 /* unpack the integer */
9699 void
unpackInt(unsigned char * buffer,uint32_t * value)9700 unpackInt(unsigned char *buffer, uint32_t * value)
9701 {
9702 *value = ntohl(*(uint32_t *)buffer);
9703 }
9704 #endif
9705
9706 /* core API implementation */
9707
9708 /* see http://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-NCName */
_rdfstore_is_xml_name(unsigned char * name_char)9709 int _rdfstore_is_xml_name(
9710 unsigned char * name_char ) {
9711
9712 if ( ( ! isalpha((int)*name_char) ) &&
9713 ( *name_char != '_' ) )
9714 return 0;
9715
9716 name_char++;
9717 while( *name_char ) {
9718 if ( ( ! isalnum((int)*name_char) ) &&
9719 ( *name_char != '_' ) &&
9720 ( *name_char != '-' ) &&
9721 ( *name_char != '.' ) )
9722 return 0;
9723 name_char++;
9724 };
9725
9726 return 1;
9727 };
9728
rdfstore_node_new()9729 RDF_Node * rdfstore_node_new() {
9730 RDF_Node * node = NULL;
9731
9732 node = (RDF_Node *) RDFSTORE_MALLOC(sizeof(RDF_Node));
9733
9734 if( node == NULL ) {
9735 return NULL;
9736 };
9737
9738 bzero( node, sizeof(RDF_Node) );
9739
9740 node->type = -1; /* unset */
9741
9742 /* init the union parts - correct? */
9743 node->value.resource.identifier = NULL;
9744 node->value.resource.identifier_len = 0;
9745 node->value.literal.string = NULL;
9746 node->value.literal.string_len = 0;
9747 node->value.literal.dataType = NULL;
9748 strcpy(node->value.literal.lang,"");
9749 node->value.literal.parseType = 0;
9750
9751 return node;
9752 };
9753
rdfstore_node_clone(RDF_Node * node)9754 RDF_Node * rdfstore_node_clone( RDF_Node * node ) {
9755
9756 if ( node == NULL )
9757 return NULL;
9758
9759 if ( node->type == RDFSTORE_NODE_TYPE_LITERAL ) {
9760 return rdfstore_literal_clone( node );
9761 } else {
9762 return rdfstore_resource_clone( node );
9763 };
9764 };
9765
rdfstore_node_set_type(RDF_Node * node,int type)9766 int rdfstore_node_set_type(
9767 RDF_Node * node,
9768 int type ) {
9769
9770 if ( ( node == NULL ) ||
9771 ( ! ( ( type == RDFSTORE_NODE_TYPE_RESOURCE ) ||
9772 ( type == RDFSTORE_NODE_TYPE_LITERAL ) ||
9773 ( type == RDFSTORE_NODE_TYPE_BNODE ) ) ) )
9774 return 0;
9775
9776 node->type = type;
9777
9778 return 1;
9779 };
9780
rdfstore_node_get_type(RDF_Node * node)9781 int rdfstore_node_get_type(
9782 RDF_Node * node ) {
9783
9784 if ( node == NULL )
9785 return -1;
9786
9787 return node->type;
9788 };
9789
rdfstore_node_get_label(RDF_Node * node,int * len)9790 unsigned char * rdfstore_node_get_label(
9791 RDF_Node * node,
9792 int * len ) {
9793 *len = 0;
9794
9795 if ( node == NULL )
9796 return NULL;
9797
9798 *len = ( node->type != RDFSTORE_NODE_TYPE_LITERAL ) ? node->value.resource.identifier_len : node->value.literal.string_len;
9799
9800 return ( node->type != RDFSTORE_NODE_TYPE_LITERAL ) ? node->value.resource.identifier : node->value.literal.string;
9801 };
9802
rdfstore_node_to_string(RDF_Node * node,int * len)9803 unsigned char * rdfstore_node_to_string(
9804 RDF_Node * node,
9805 int * len ) {
9806
9807 return rdfstore_node_get_label( node, len );
9808
9809 };
9810
rdfstore_node_get_digest(RDF_Node * node,int * len)9811 unsigned char * rdfstore_node_get_digest(
9812 RDF_Node * node,
9813 int * len ) {
9814 static unsigned char dd[RDFSTORE_SHA_DIGESTSIZE]; /* NOTE: static is not thread safe due is coming from process mem and not from stack */
9815 *len = 0;
9816
9817 if ( node == NULL )
9818 return NULL;
9819
9820 if ( rdfstore_digest_get_node_digest( node, dd, 1 ) == 0 ) { /* get unique digest by xml:lang and rdf:datatype if necessary */
9821 *len = RDFSTORE_SHA_DIGESTSIZE;
9822
9823 return dd;
9824 } else {
9825 return NULL;
9826 };
9827 };
9828
rdfstore_node_equals(RDF_Node * node1,RDF_Node * node2)9829 int rdfstore_node_equals(
9830 RDF_Node * node1,
9831 RDF_Node * node2 ) {
9832 unsigned char * dd1=NULL;
9833 int ll1=0;
9834 unsigned char * dd2=NULL;
9835 int ll2=0;
9836
9837 if ( ( node1 == NULL ) ||
9838 ( node2 == NULL ) ||
9839 ( node1->type != node2->type ) )
9840 return 0;
9841
9842 /* try to compare crypto digests if possible */
9843 if ( ( ( dd1 = rdfstore_node_get_digest( node1, &ll1 ) ) != NULL ) &&
9844 ( ll1 > 0 ) &&
9845 ( ( dd2 = rdfstore_node_get_digest( node2, &ll2 ) ) != NULL ) &&
9846 ( ll2 > 0 ) &&
9847 ( ll1 == ll2 ) ) {
9848 return ( memcmp( dd1, dd2, MAX( ll1, ll2 ) ) == 0 ) ? 1 : 0 ;
9849 } else {
9850 /* otherwise memcmp their labels... */
9851 if ( node1->type == RDFSTORE_NODE_TYPE_LITERAL ) {
9852 return ( memcmp( node1->value.literal.string, node2->value.literal.string, MAX( node1->value.literal.string_len, node2->value.literal.string_len ) ) == 0 ) ? 1 : 0 ;
9853 } else {
9854 return ( memcmp( node1->value.resource.identifier, node2->value.resource.identifier, MAX( node1->value.resource.identifier_len, node2->value.resource.identifier_len ) ) == 0 ) ? 1 : 0 ;
9855 };
9856 };
9857 };
9858
rdfstore_node_free(RDF_Node * node)9859 int rdfstore_node_free(
9860 RDF_Node * node ) {
9861
9862 if ( node == NULL )
9863 return 0;
9864
9865 if ( node->type == RDFSTORE_NODE_TYPE_LITERAL ) {
9866 if ( node->value.literal.string != NULL ) /* due we have also empty literals */
9867 RDFSTORE_FREE( node->value.literal.string );
9868 if ( node->value.literal.dataType != NULL )
9869 RDFSTORE_FREE( node->value.literal.dataType );
9870 } else if ( ( node->type == RDFSTORE_NODE_TYPE_RESOURCE ) ||
9871 ( node->type == RDFSTORE_NODE_TYPE_BNODE ) ) {
9872 if ( node->value.resource.identifier != NULL ) /* due we do NOT use this API everywhere we need to check */
9873 RDFSTORE_FREE( node->value.resource.identifier );
9874 };
9875
9876 RDFSTORE_FREE( node );
9877
9878 return 1;
9879 };
9880
rdfstore_node_dump(RDF_Node * node)9881 void rdfstore_node_dump(
9882 RDF_Node * node ) {
9883
9884 unsigned char * buff=NULL;
9885
9886 buff = rdfstore_ntriples_node( node );
9887
9888 if ( buff ) {
9889 fprintf(stderr, "(type='%s') %s\n", ( node->type == RDFSTORE_NODE_TYPE_LITERAL ) ? "literal" : ( node->type == RDFSTORE_NODE_TYPE_BNODE ) ? "bNode" : "URI", buff );
9890 RDFSTORE_FREE( buff );
9891 };
9892
9893 };
9894
9895 /* for resource centric API ala Jena */
rdfstore_node_set_model(RDF_Node * node,rdfstore * model)9896 int rdfstore_node_set_model(
9897 RDF_Node * node,
9898 rdfstore * model ) {
9899
9900 if ( ( node == NULL ) ||
9901 ( model == NULL ) )
9902 return 0;
9903
9904 node->model = model; /* tell it there is a guy attached to it??? */
9905
9906 return 1;
9907 };
9908
rdfstore_node_reset_model(RDF_Node * node)9909 int rdfstore_node_reset_model(
9910 RDF_Node * node ) {
9911
9912 if ( node == NULL )
9913 return 0;
9914
9915 node->model = NULL;
9916
9917 return 1;
9918 };
9919
rdfstore_node_get_model(RDF_Node * node)9920 rdfstore * rdfstore_node_get_model(
9921 RDF_Node * node ) {
9922
9923 if ( node == NULL )
9924 return 0;
9925
9926 return node->model;
9927 };
9928
9929 /* RDF literals */
9930
rdfstore_literal_new(unsigned char * string,int len,int parseType,unsigned char * lang,unsigned char * dt)9931 RDF_Node * rdfstore_literal_new(
9932 unsigned char * string,
9933 int len,
9934 int parseType,
9935 unsigned char * lang,
9936 unsigned char * dt ) {
9937 RDF_Node * node = NULL;
9938
9939 if( (parseType) &&
9940 (dt!=NULL) &&
9941 (strlen(dt) > 0) &&
9942 (strcmp(dt,RDFSTORE_RDF_PARSETYPE_LITERAL)) ) {
9943 return NULL;
9944 };
9945
9946 node = rdfstore_node_new();
9947
9948 if ( ( node == NULL ) ||
9949 ( ! ( ( parseType == RDFSTORE_PARSE_TYPE_NORMAL ) ||
9950 ( parseType == RDFSTORE_PARSE_TYPE_LITERAL ) ) ) )
9951 return NULL;
9952
9953 if ( ! rdfstore_node_set_type( node, RDFSTORE_NODE_TYPE_LITERAL ) ) {
9954 rdfstore_node_free( node );
9955 return NULL;
9956 };
9957
9958 node->value.literal.string = NULL;
9959 node->value.literal.string_len = 0;
9960
9961 if ( ( string != NULL ) &&
9962 ( len > 0 ) ) {
9963
9964 node->value.literal.string = (unsigned char *) RDFSTORE_MALLOC( sizeof(unsigned char) * ( len + 1 ) );
9965
9966 if ( node->value.literal.string == NULL ) {
9967 rdfstore_node_free( node );
9968 return NULL;
9969 };
9970 node->value.literal.string_len = len;
9971
9972 memcpy( node->value.literal.string, string, len );
9973 memcpy( node->value.literal.string+len,"\0",1);
9974 };
9975
9976 node->value.literal.parseType = parseType;
9977
9978 /* FORCE this - rdf:parseType="Literal" is the same as rdf:datatype="http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral" */
9979 if( parseType == RDFSTORE_PARSE_TYPE_LITERAL ) {
9980 dt = RDFSTORE_RDF_PARSETYPE_LITERAL;
9981 };
9982
9983 node->value.literal.dataType = NULL;
9984
9985 /* set rdf:datatype */
9986 if ( ( dt != NULL ) &&
9987 ( strlen(dt) > 0 ) ) {
9988 node->value.literal.dataType = (unsigned char *) RDFSTORE_MALLOC( sizeof(unsigned char) * ( strlen(dt) + 1 ) );
9989
9990 if ( node->value.literal.dataType == NULL ) {
9991 rdfstore_node_free( node );
9992 return NULL;
9993 };
9994 strcpy( node->value.literal.dataType, dt );
9995 };
9996
9997 /* set xml:lang */
9998 if ( ( lang != NULL ) &&
9999 ( strlen(lang) > 0 ) ) {
10000 if ( strlen(lang) > RDFSTORE_MAX_LANG_LENGTH ) {
10001 perror("rdfstore_literal_new");
10002 fprintf(stderr,"Literal xml:lang '%s' is too long. Max allowed is %d characters long\n", lang, RDFSTORE_MAX_LANG_LENGTH );
10003 rdfstore_node_free( node );
10004 return NULL;
10005 };
10006
10007 strcpy( node->value.literal.lang, lang );
10008 } else {
10009 strcpy( node->value.literal.lang, "\0" ); /* or =NULL ? */
10010 };
10011
10012 return node;
10013 };
10014
rdfstore_literal_clone(RDF_Node * node)10015 RDF_Node * rdfstore_literal_clone(
10016 RDF_Node * node ) {
10017
10018 if ( ( node == NULL ) ||
10019 ( node->type != RDFSTORE_NODE_TYPE_LITERAL ) )
10020 return NULL;
10021
10022 return rdfstore_literal_new( node->value.literal.string,
10023 node->value.literal.string_len,
10024 node->value.literal.parseType,
10025 node->value.literal.lang,
10026 node->value.literal.dataType );
10027 };
10028
rdfstore_literal_get_label(RDF_Node * node,int * len)10029 unsigned char * rdfstore_literal_get_label(
10030 RDF_Node * node,
10031 int * len ) {
10032
10033 return rdfstore_node_get_label( node, len );
10034
10035 };
10036
rdfstore_literal_to_string(RDF_Node * node,int * len)10037 unsigned char * rdfstore_literal_to_string(
10038 RDF_Node * node,
10039 int * len ) {
10040
10041 return rdfstore_node_to_string( node, len );
10042
10043 };
10044
rdfstore_literal_get_digest(RDF_Node * node,int * len)10045 unsigned char * rdfstore_literal_get_digest(
10046 RDF_Node * node,
10047 int * len ) {
10048
10049 return rdfstore_node_get_digest( node, len );
10050
10051 };
10052
rdfstore_literal_equals(RDF_Node * node1,RDF_Node * node2)10053 int rdfstore_literal_equals(
10054 RDF_Node * node1,
10055 RDF_Node * node2 ) {
10056
10057 return rdfstore_node_equals( node1, node2 );
10058
10059 };
10060
rdfstore_literal_set_string(RDF_Node * node,unsigned char * string,int len)10061 int rdfstore_literal_set_string(
10062 RDF_Node * node,
10063 unsigned char * string,
10064 int len ) {
10065
10066 if ( ( node == NULL ) ||
10067 ( node->type != RDFSTORE_NODE_TYPE_LITERAL ) )
10068 return 0;
10069
10070 if ( ( string != NULL ) &&
10071 ( len > 0 ) ) {
10072
10073 if ( node->value.literal.string != NULL )
10074 RDFSTORE_FREE( node->value.literal.string );
10075
10076 node->value.literal.string = (unsigned char *) RDFSTORE_MALLOC( sizeof(unsigned char) * ( len + 1 ) );
10077
10078 if ( node->value.literal.string == NULL ) {
10079 return 0;
10080 };
10081 node->value.literal.string_len = len;
10082
10083 memcpy( node->value.literal.string, string, len );
10084 memcpy( node->value.literal.string+len,"\0",1);
10085 };
10086
10087 return 1;
10088 };
10089
rdfstore_literal_set_lang(RDF_Node * node,unsigned char * lang)10090 int rdfstore_literal_set_lang(
10091 RDF_Node * node,
10092 unsigned char * lang ) {
10093
10094 if ( ( node == NULL ) ||
10095 ( node->type != RDFSTORE_NODE_TYPE_LITERAL ) )
10096 return 0;
10097
10098 /* set xml:lang */
10099 if ( ( lang != NULL ) &&
10100 ( strlen(lang) > 0 ) )
10101 strcpy( node->value.literal.lang, lang );
10102
10103 return 1;
10104 };
10105
rdfstore_literal_get_lang(RDF_Node * node)10106 unsigned char * rdfstore_literal_get_lang(
10107 RDF_Node * node ) {
10108
10109 if ( ( node == NULL ) ||
10110 ( node->type != RDFSTORE_NODE_TYPE_LITERAL ) )
10111 return NULL;
10112
10113 return node->value.literal.lang;
10114 };
10115
rdfstore_literal_set_datatype(RDF_Node * node,unsigned char * dt)10116 int rdfstore_literal_set_datatype(
10117 RDF_Node * node,
10118 unsigned char * dt ) {
10119
10120 if ( ( node == NULL ) ||
10121 ( node->type != RDFSTORE_NODE_TYPE_LITERAL ) )
10122 return 0;
10123
10124 /* set rdf:datatype */
10125 if ( dt != NULL ) {
10126 if ( node->value.literal.dataType != NULL )
10127 RDFSTORE_FREE( node->value.literal.dataType );
10128
10129 node->value.literal.dataType = (unsigned char *) RDFSTORE_MALLOC( sizeof(unsigned char) * ( strlen(dt) + 1 ) );
10130
10131 if ( node->value.literal.dataType == NULL ) {
10132 return 0;
10133 };
10134 strcpy( node->value.literal.dataType, dt );
10135 };
10136
10137 return 1;
10138 };
10139
rdfstore_literal_get_datatype(RDF_Node * node)10140 unsigned char * rdfstore_literal_get_datatype(
10141 RDF_Node * node ) {
10142
10143 if ( ( node == NULL ) ||
10144 ( node->type != RDFSTORE_NODE_TYPE_LITERAL ) )
10145 return NULL;
10146
10147 return node->value.literal.dataType;
10148 };
10149
rdfstore_literal_set_parsetype(RDF_Node * node,int parseType)10150 int rdfstore_literal_set_parsetype(
10151 RDF_Node * node,
10152 int parseType ) {
10153
10154 if ( ( node == NULL ) ||
10155 ( node->type != RDFSTORE_NODE_TYPE_LITERAL ) ||
10156 ( ! ( ( parseType == RDFSTORE_PARSE_TYPE_NORMAL ) ||
10157 ( parseType == RDFSTORE_PARSE_TYPE_LITERAL ) ) ) )
10158 return 0;
10159
10160 /* FORCE this - rdf:parseType="Literal" is the same as rdf:datatype="http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral" */
10161 if( parseType == RDFSTORE_PARSE_TYPE_LITERAL ) {
10162 node->value.literal.parseType = parseType;
10163
10164 if ( ! rdfstore_literal_set_datatype( node, RDFSTORE_RDF_PARSETYPE_LITERAL ) )
10165 return 0;
10166 };
10167
10168 return 1;
10169 };
10170
rdfstore_literal_get_parsetype(RDF_Node * node)10171 int rdfstore_literal_get_parsetype(
10172 RDF_Node * node ) {
10173
10174 if ( ( node == NULL ) ||
10175 ( node->type != RDFSTORE_NODE_TYPE_LITERAL ) )
10176 return -1;
10177
10178 return node->value.literal.parseType;
10179 };
10180
rdfstore_literal_free(RDF_Node * node)10181 int rdfstore_literal_free(
10182 RDF_Node * node ) {
10183
10184 return rdfstore_node_free( node );
10185
10186 };
10187
rdfstore_literal_dump(RDF_Node * node)10188 void rdfstore_literal_dump(
10189 RDF_Node * node ) {
10190
10191 rdfstore_node_dump( node );
10192 };
10193
10194 /* for resource centric API ala Jena */
rdfstore_literal_set_model(RDF_Node * node,rdfstore * model)10195 int rdfstore_literal_set_model(
10196 RDF_Node * node,
10197 rdfstore * model ) {
10198
10199 return rdfstore_node_set_model( node, model );
10200 };
10201
rdfstore_literal_reset_model(RDF_Node * node)10202 int rdfstore_literal_reset_model(
10203 RDF_Node * node ) {
10204
10205 return rdfstore_node_reset_model( node );
10206
10207 };
10208
rdfstore_literal_get_model(RDF_Node * node)10209 rdfstore * rdfstore_literal_get_model(
10210 RDF_Node * node ) {
10211
10212 return rdfstore_node_get_model( node );
10213
10214 };
10215
10216 /* RDF resources (URIs or bNodes) */
10217
rdfstore_resource_new(unsigned char * identifier,int len,int type)10218 RDF_Node * rdfstore_resource_new(
10219 unsigned char * identifier,
10220 int len,
10221 int type ) {
10222 RDF_Node * node = NULL;
10223
10224 if ( ( ! ( ( type == RDFSTORE_NODE_TYPE_RESOURCE ) ||
10225 ( type == RDFSTORE_NODE_TYPE_BNODE ) ) ) ||
10226 ( identifier == NULL ) ||
10227 ( len <= 0 ) )
10228 return NULL;
10229
10230 node = rdfstore_node_new();
10231
10232 if ( node == NULL )
10233 return NULL;
10234
10235 if ( ! rdfstore_node_set_type( node, type ) ) {
10236 rdfstore_node_free( node );
10237 return NULL;
10238 };
10239
10240 node->value.resource.identifier = (unsigned char *) RDFSTORE_MALLOC( sizeof(unsigned char) * ( len + 1 ) );
10241
10242 if ( node->value.resource.identifier == NULL ) {
10243 rdfstore_node_free( node );
10244 return NULL;
10245 };
10246 node->value.resource.identifier_len = len;
10247
10248 memcpy( node->value.resource.identifier, identifier, len );
10249 memcpy( node->value.resource.identifier+len,"\0",1);
10250
10251 return node;
10252 };
10253
rdfstore_resource_new_from_qname(unsigned char * namespace,int nsl,unsigned char * localname,int lnl,int type)10254 RDF_Node * rdfstore_resource_new_from_qname(
10255 unsigned char * namespace,
10256 int nsl,
10257 unsigned char * localname,
10258 int lnl,
10259 int type ) {
10260 RDF_Node * node = NULL;
10261
10262 if ( ( namespace == NULL ) ||
10263 ( nsl <= 0 ) ||
10264 ( localname == NULL ) ||
10265 ( lnl <= 0 ) ||
10266 ( type != RDFSTORE_NODE_TYPE_RESOURCE ) )
10267 return NULL;
10268
10269 node = rdfstore_node_new();
10270
10271 if ( node == NULL )
10272 return NULL;
10273
10274 rdfstore_node_set_type( node, type );
10275
10276 /* check whether or not is a valid XML localname */
10277 if ( ! _rdfstore_is_xml_name( localname ) ) {
10278 /* invalid resource local name */
10279 rdfstore_node_free( node );
10280 return NULL;
10281 };
10282
10283 node->value.resource.identifier = (unsigned char *) RDFSTORE_MALLOC( sizeof(unsigned char) * (lnl + nsl + 1) );
10284
10285 if ( node->value.resource.identifier == NULL ) {
10286 rdfstore_node_free( node );
10287 return NULL;
10288 };
10289 memcpy( node->value.resource.identifier, namespace, nsl );
10290 memcpy( node->value.resource.identifier+nsl, localname, lnl );
10291 memcpy( node->value.resource.identifier+nsl+lnl, "\0", 1);
10292
10293 node->value.resource.identifier_len = lnl + nsl;
10294
10295 return node;
10296 };
10297
10298
rdfstore_resource_clone(RDF_Node * node)10299 RDF_Node * rdfstore_resource_clone( RDF_Node * node ) {
10300
10301 if ( ( node == NULL ) ||
10302 ( ! ( ( node->type == RDFSTORE_NODE_TYPE_RESOURCE ) ||
10303 ( node->type == RDFSTORE_NODE_TYPE_BNODE ) ) ) )
10304 return NULL;
10305
10306 return rdfstore_resource_new( node->value.resource.identifier,
10307 node->value.resource.identifier_len,
10308 node->type );
10309 };
10310
rdfstore_resource_get_label(RDF_Node * node,int * len)10311 unsigned char * rdfstore_resource_get_label(
10312 RDF_Node * node,
10313 int * len ) {
10314
10315 return rdfstore_node_get_label( node, len );
10316
10317 };
10318
rdfstore_resource_to_string(RDF_Node * node,int * len)10319 unsigned char * rdfstore_resource_to_string(
10320 RDF_Node * node,
10321 int * len ) {
10322
10323 return rdfstore_node_to_string( node, len );
10324
10325 };
10326
rdfstore_resource_get_digest(RDF_Node * node,int * len)10327 unsigned char * rdfstore_resource_get_digest(
10328 RDF_Node * node,
10329 int * len ) {
10330
10331 return rdfstore_node_get_digest( node, len );
10332
10333 };
10334
rdfstore_resource_equals(RDF_Node * node1,RDF_Node * node2)10335 int rdfstore_resource_equals(
10336 RDF_Node * node1,
10337 RDF_Node * node2 ) {
10338
10339 return rdfstore_node_equals( node1, node2 );
10340
10341 };
10342
rdfstore_resource_set_uri(RDF_Node * node,unsigned char * identifier,int len)10343 int rdfstore_resource_set_uri(
10344 RDF_Node * node,
10345 unsigned char * identifier,
10346 int len ) {
10347
10348 if ( ( node == NULL ) ||
10349 ( identifier == NULL ) ||
10350 ( len <= 0 ) ||
10351 ( ! ( ( node->type == RDFSTORE_NODE_TYPE_RESOURCE ) ||
10352 ( node->type == RDFSTORE_NODE_TYPE_BNODE ) ) ) )
10353 return 0;
10354
10355 if ( node->value.resource.identifier != NULL )
10356 RDFSTORE_FREE( node->value.resource.identifier );
10357
10358 node->value.resource.identifier = (unsigned char *) RDFSTORE_MALLOC( sizeof(unsigned char) * ( len + 1 ) );
10359
10360 if ( node->value.resource.identifier == NULL ) {
10361 return 0;
10362 };
10363 node->value.resource.identifier_len = len;
10364
10365 memcpy( node->value.resource.identifier, identifier, len );
10366 memcpy( node->value.resource.identifier+len,"\0",1);
10367
10368 return 1;
10369 };
10370
rdfstore_resource_get_uri(RDF_Node * node,int * len)10371 unsigned char * rdfstore_resource_get_uri(
10372 RDF_Node * node,
10373 int * len ) {
10374 *len = 0;
10375
10376 if ( ( node == NULL ) ||
10377 ( ! ( ( node->type == RDFSTORE_NODE_TYPE_RESOURCE ) ||
10378 ( node->type == RDFSTORE_NODE_TYPE_BNODE ) ) ) )
10379 return NULL;
10380
10381 *len = node->value.resource.identifier_len;
10382
10383 return node->value.resource.identifier;
10384 };
10385
rdfstore_resource_is_anonymous(RDF_Node * node)10386 int rdfstore_resource_is_anonymous(
10387 RDF_Node * node ) {
10388
10389 if ( node == NULL )
10390 return -1;
10391
10392 return ( node->type == RDFSTORE_NODE_TYPE_BNODE ) ? 1 : 0 ;
10393 };
10394
rdfstore_resource_is_bnode(RDF_Node * node)10395 int rdfstore_resource_is_bnode(
10396 RDF_Node * node ) {
10397
10398 return rdfstore_resource_is_anonymous( node );
10399
10400 };
10401
rdfstore_resource_get_namespace(RDF_Node * node,int * len)10402 unsigned char * rdfstore_resource_get_namespace(
10403 RDF_Node * node,
10404 int * len ) {
10405 unsigned char * nc=NULL;
10406 *len = 0;
10407
10408 if ( ( node == NULL ) ||
10409 ( node->type != RDFSTORE_NODE_TYPE_RESOURCE ) )
10410 return NULL;
10411
10412 nc = rdfstore_resource_get_localname( node, len );
10413
10414 if ( nc == NULL ) {
10415 *len = 0;
10416 return NULL;
10417 } else {
10418 *len = (int)( (unsigned char * ) nc - (unsigned char *) node->value.resource.identifier );
10419 };
10420
10421 return (*len > 0 ) ? node->value.resource.identifier : NULL ; /* and the caller will use len to sort out how long the namespace is */
10422 };
10423
rdfstore_resource_get_localname(RDF_Node * node,int * len)10424 unsigned char * rdfstore_resource_get_localname(
10425 RDF_Node * node,
10426 int * len ) {
10427 unsigned char * localname=NULL;
10428 unsigned char * nc=NULL;
10429 *len = 0;
10430
10431 if ( ( node == NULL ) ||
10432 ( node->type != RDFSTORE_NODE_TYPE_RESOURCE ) )
10433 return NULL;
10434
10435 /* try to get out XML QName LocalName from resource identifier */
10436 nc = node->value.resource.identifier + ( node->value.resource.identifier_len - 1 );
10437 while( nc >= node->value.resource.identifier ) {
10438 if( _rdfstore_is_xml_name( nc ) ) {
10439 localname = nc;
10440 *len = (int)( ( (unsigned char *)(node->value.resource.identifier_len) ) - ( (unsigned char *)(localname) - (unsigned char *)(node->value.resource.identifier) ) ); /* correct??? */
10441 };
10442 nc--;
10443 };
10444
10445 if( !localname ) {
10446 localname = node->value.resource.identifier;
10447 *len = node->value.resource.identifier_len;
10448 };
10449
10450 return localname;
10451 };
10452
rdfstore_resource_get_bnode(RDF_Node * node,int * len)10453 unsigned char * rdfstore_resource_get_bnode(
10454 RDF_Node * node,
10455 int * len ) {
10456 node = NULL;
10457 *len = 0;
10458
10459 if ( ( node == NULL ) ||
10460 ( node->type != RDFSTORE_NODE_TYPE_BNODE ) )
10461 return NULL;
10462
10463 return rdfstore_node_get_label( node, len );
10464
10465 };
10466
rdfstore_resource_get_nodeid(RDF_Node * node,int * len)10467 unsigned char * rdfstore_resource_get_nodeid(
10468 RDF_Node * node,
10469 int * len ) {
10470
10471 return rdfstore_resource_get_bnode( node, len );
10472
10473 };
10474
rdfstore_resource_free(RDF_Node * node)10475 int rdfstore_resource_free(
10476 RDF_Node * node ) {
10477
10478 return rdfstore_node_free( node );
10479
10480 };
10481
rdfstore_resource_dump(RDF_Node * node)10482 void rdfstore_resource_dump(
10483 RDF_Node * node ) {
10484
10485 return rdfstore_node_dump( node );
10486
10487 };
10488
10489 /* for resource centric API ala Jena */
10490
rdfstore_resource_set_model(RDF_Node * node,rdfstore * model)10491 int rdfstore_resource_set_model(
10492 RDF_Node * node,
10493 rdfstore * model ) {
10494
10495 return rdfstore_node_set_model( node, model );
10496
10497 };
rdfstore_resource_reset_model(RDF_Node * node)10498 int rdfstore_resource_reset_model(
10499 RDF_Node * node ) {
10500
10501 return rdfstore_node_reset_model( node );
10502
10503 };
10504
rdfstore_resource_get_model(RDF_Node * node)10505 rdfstore * rdfstore_resource_get_model(
10506 RDF_Node * node ) {
10507
10508 return rdfstore_node_get_model( node );
10509
10510 };
10511
10512 /* RDF statements */
10513
10514 /* create a new statement from given components - then the components are being owned by the statement and freed on error/destruction - and they
10515 must not be used by the caller after this call */
rdfstore_statement_new(RDF_Node * s,RDF_Node * p,RDF_Node * o,RDF_Node * c,RDF_Node * node,int isreified)10516 RDF_Statement * rdfstore_statement_new(
10517 RDF_Node * s,
10518 RDF_Node * p,
10519 RDF_Node * o,
10520 RDF_Node * c,
10521 RDF_Node * node,
10522 int isreified ) {
10523 RDF_Statement * st=NULL;
10524
10525 if ( ( s == NULL ) ||
10526 ( p == NULL ) ||
10527 ( o == NULL ) )
10528 return NULL;
10529
10530 st = (RDF_Statement *) RDFSTORE_MALLOC( sizeof(RDF_Statement) );
10531
10532 if ( st == NULL ) {
10533 rdfstore_resource_free( s );
10534 rdfstore_resource_free( p );
10535 rdfstore_node_free( o );
10536 rdfstore_resource_free( c );
10537 rdfstore_resource_free( node );
10538 return NULL;
10539 };
10540
10541 st->hashcode = 0;
10542 st->isreified = (isreified) ? 1 : 0;
10543
10544 st->subject = s;
10545 st->predicate = p;
10546 st->object = o;
10547 st->context = (c != NULL) ? c : NULL ;
10548
10549 st->node = NULL;
10550
10551 /* create st->node if we need an explicit label for it, otherwise getLabel is systematically calculating the URI even after stored */
10552 if ( node != NULL ) {
10553 if ( ! st->isreified ) {
10554 rdfstore_statement_free( st );
10555 /* Statement can have an identfier (be a resource) only if it is reified */
10556 return NULL;
10557 };
10558 st->node = node;
10559 } else if ( st->isreified ) {
10560 unsigned char * label=NULL;
10561 int ll=0;
10562 /* for reified statements we dynamically assign a node to it as resource */
10563 if ( ( ( label = rdfstore_statement_get_label( st, &ll ) ) != NULL ) &&
10564 ( ll > 0 ) ) {
10565 st->node = rdfstore_resource_new( label, ll, RDFSTORE_NODE_TYPE_RESOURCE );
10566 if ( st->node == NULL ) {
10567 rdfstore_statement_free( st );
10568 return NULL;
10569 };
10570 };
10571 };
10572
10573 st->model = NULL;
10574
10575 return st;
10576 };
10577
rdfstore_statement_clone(RDF_Statement * st)10578 RDF_Statement * rdfstore_statement_clone(
10579 RDF_Statement * st ) {
10580
10581 if ( st == NULL )
10582 return NULL;
10583
10584 return rdfstore_statement_new( rdfstore_resource_clone( st->subject ),
10585 rdfstore_resource_clone( st->predicate ),
10586 rdfstore_node_clone( st->object ),
10587 rdfstore_resource_clone( st->context ),
10588 rdfstore_resource_clone( st->node ),
10589 st->isreified );
10590 };
10591
rdfstore_statement_get_label(RDF_Statement * st,int * len)10592 unsigned char * rdfstore_statement_get_label(
10593 RDF_Statement * st,
10594 int * len ) {
10595 *len = 0;
10596
10597 if ( st == NULL )
10598 return NULL;
10599
10600 if ( st->node != NULL ) {
10601 *len = st->node->value.resource.identifier_len;
10602 return st->node->value.resource.identifier;
10603 } else {
10604 int i=0,status=0;
10605 unsigned char dd[RDFSTORE_SHA_DIGESTSIZE];
10606 static unsigned char label[9+10+(RDFSTORE_SHA_DIGESTSIZE*2)]; /* assume strlen( rdfstore_digest_get_digest_algorithm() ) up to 10 chars */
10607
10608 /* NOTE: the static above is not thread safe due is coming from process mem and not from stack */
10609
10610 /* e.g. urn:rdf:SHA-1-d2619b606c7ecac3dcf9151dae104c4ae7554786 */
10611 sprintf( label, "urn:rdf:%s-", rdfstore_digest_get_digest_algorithm() );
10612 status = rdfstore_digest_get_statement_digest( st, NULL, dd );
10613 if ( status != 0 )
10614 return NULL;
10615
10616 for ( i=0; i< RDFSTORE_SHA_DIGESTSIZE ; i++ ) {
10617 char cc[2];
10618 sprintf( cc, "%02X", dd[i] );
10619 strncat(label, cc, 2);
10620 };
10621 *len = 9 + 10 + (RDFSTORE_SHA_DIGESTSIZE*2);
10622 return label;
10623 };
10624 };
10625
rdfstore_statement_to_string(RDF_Statement * st,int * len)10626 unsigned char * rdfstore_statement_to_string(
10627 RDF_Statement * st,
10628 int * len ) {
10629 unsigned char * ntriple=NULL;
10630 *len = 0;
10631
10632 if ( st == NULL )
10633 return ntriple;
10634
10635 ntriple = rdfstore_ntriples_statement( st, NULL );
10636
10637 *len = strlen( ntriple );
10638
10639 return ntriple;
10640 };
10641
rdfstore_statement_get_digest(RDF_Statement * st,int * len)10642 unsigned char * rdfstore_statement_get_digest(
10643 RDF_Statement * st,
10644 int * len ) {
10645 static unsigned char dd[RDFSTORE_SHA_DIGESTSIZE]; /* NOTE: static is not thread safe due is coming from process mem and not from stack */
10646 *len = 0;
10647
10648 if ( st == NULL )
10649 return NULL;
10650
10651 if ( ! rdfstore_digest_get_statement_digest( st, NULL, dd ) )
10652 return NULL;
10653
10654 *len = RDFSTORE_SHA_DIGESTSIZE;
10655
10656 return dd;
10657 };
10658
rdfstore_statement_is_anonymous(RDF_Statement * st)10659 int rdfstore_statement_is_anonymous(
10660 RDF_Statement * st ) {
10661
10662 if ( st == NULL )
10663 return -1;
10664
10665 return 0;
10666 };
10667
rdfstore_statement_is_bnode(RDF_Statement * st)10668 int rdfstore_statement_is_bnode(
10669 RDF_Statement * st ) {
10670
10671 return rdfstore_statement_is_anonymous( st );
10672
10673 };
10674
rdfstore_statement_get_localname(RDF_Statement * st,int * len)10675 unsigned char * rdfstore_statement_get_localname(
10676 RDF_Statement * st,
10677 int * len ) {
10678
10679 return rdfstore_statement_get_label( st, len );
10680
10681 };
10682
rdfstore_statement_get_namespace(RDF_Statement * st,int * len)10683 unsigned char * rdfstore_statement_get_namespace(
10684 RDF_Statement * st,
10685 int * len ) {
10686 *len = 0;
10687
10688 return NULL;
10689 };
10690
rdfstore_statement_get_uri(RDF_Statement * st,int * len)10691 unsigned char * rdfstore_statement_get_uri(
10692 RDF_Statement * st,
10693 int * len ) {
10694
10695 return rdfstore_statement_get_label( st, len );
10696
10697 };
10698
rdfstore_statement_equals(RDF_Statement * st1,RDF_Statement * st2)10699 int rdfstore_statement_equals(
10700 RDF_Statement * st1,
10701 RDF_Statement * st2 ) {
10702 int ls1=0, ls2=0, lp1=0, lp2=0, lo1=0, lo2=0;
10703
10704 if ( ( st1 == NULL ) ||
10705 ( st2 == NULL ) )
10706 return 0;
10707
10708 if ( ( st1->context != NULL ) &&
10709 ( st2->context != NULL ) ) {
10710 int lc1=0, lc2=0;
10711 return ( ( memcmp( rdfstore_resource_get_label( st1->subject, &ls1 ),
10712 rdfstore_resource_get_label( st2->subject, &ls2 ), MAX(ls1, ls2) ) == 0 ) &&
10713 ( ls1 > 0 ) && ( ls2 > 0 ) &&
10714 ( memcmp( rdfstore_resource_get_label( st1->predicate, &lp1 ),
10715 rdfstore_resource_get_label( st2->predicate, &lp2 ), MAX(lp1, lp2) ) == 0 ) &&
10716 ( lp1 > 0 ) && ( lp2 > 0 ) &&
10717 ( memcmp( rdfstore_node_get_label( st1->object, &lo1 ),
10718 rdfstore_node_get_label( st2->object, &lo2 ), MAX(lo1, lo2) ) == 0 ) &&
10719 ( memcmp( rdfstore_resource_get_label( st1->context, &lc1 ),
10720 rdfstore_resource_get_label( st2->context, &lc2 ), MAX(lc1, lc2) ) == 0 ) &&
10721 ( lc1 > 0 ) && ( lc2 > 0 ) ) ? 1 : 0 ;
10722 } else {
10723 return ( ( memcmp( rdfstore_resource_get_label( st1->subject, &ls1 ),
10724 rdfstore_resource_get_label( st2->subject, &ls2 ), MAX(ls1, ls2) ) == 0 ) &&
10725 ( ls1 > 0 ) && ( ls2 > 0 ) &&
10726 ( memcmp( rdfstore_resource_get_label( st1->predicate, &lp1 ),
10727 rdfstore_resource_get_label( st2->predicate, &lp2 ), MAX(lp1, lp2) ) == 0 ) &&
10728 ( lp1 > 0 ) && ( lp2 > 0 ) &&
10729 ( memcmp( rdfstore_node_get_label( st1->object, &lo1 ),
10730 rdfstore_node_get_label( st2->object, &lo2 ), MAX(lo1, lo2) ) == 0 ) ) ? 1 : 0 ;
10731 };
10732 };
10733
rdfstore_statement_isreified(RDF_Statement * st)10734 int rdfstore_statement_isreified(
10735 RDF_Statement * st ) {
10736
10737 if ( st == NULL )
10738 return -1;
10739
10740 return st->isreified;
10741 };
10742
rdfstore_statement_get_subject(RDF_Statement * st)10743 RDF_Node * rdfstore_statement_get_subject(
10744 RDF_Statement * st ) {
10745
10746 if ( st == NULL )
10747 return 0;
10748
10749 return st->subject;
10750 };
10751
rdfstore_statement_set_subject(RDF_Statement * st,RDF_Node * s)10752 int rdfstore_statement_set_subject(
10753 RDF_Statement * st,
10754 RDF_Node * s ) {
10755
10756 if ( st == NULL )
10757 return 0;
10758
10759 rdfstore_resource_free( st->subject );
10760
10761 st->subject = s;
10762
10763 return 1;
10764 };
10765
rdfstore_statement_get_predicate(RDF_Statement * st)10766 RDF_Node * rdfstore_statement_get_predicate(
10767 RDF_Statement * st ) {
10768
10769 if ( st == NULL )
10770 return 0;
10771
10772 return st->predicate;
10773 };
10774
rdfstore_statement_set_predicate(RDF_Statement * st,RDF_Node * p)10775 int rdfstore_statement_set_predicate(
10776 RDF_Statement * st,
10777 RDF_Node * p ) {
10778
10779 if ( st == NULL )
10780 return 0;
10781
10782 rdfstore_resource_free( st->predicate );
10783
10784 st->predicate = p;
10785
10786 return 1;
10787 };
10788
rdfstore_statement_get_object(RDF_Statement * st)10789 RDF_Node * rdfstore_statement_get_object(
10790 RDF_Statement * st ) {
10791
10792 if ( st == NULL )
10793 return 0;
10794
10795 return st->object;
10796 };
10797
rdfstore_statement_set_object(RDF_Statement * st,RDF_Node * o)10798 int rdfstore_statement_set_object(
10799 RDF_Statement * st,
10800 RDF_Node * o ) {
10801
10802 if ( st == NULL )
10803 return 0;
10804
10805 rdfstore_node_free( st->object );
10806
10807 st->object = o;
10808
10809 return 1;
10810 };
10811
rdfstore_statement_get_context(RDF_Statement * st)10812 RDF_Node * rdfstore_statement_get_context(
10813 RDF_Statement * st ) {
10814
10815 if ( st == NULL )
10816 return 0;
10817
10818 return st->context;
10819 };
10820
rdfstore_statement_set_context(RDF_Statement * st,RDF_Node * c)10821 int rdfstore_statement_set_context(
10822 RDF_Statement * st,
10823 RDF_Node * c ) {
10824
10825 if ( st == NULL )
10826 return 0;
10827
10828 rdfstore_resource_free( st->context );
10829
10830 st->context = c;
10831
10832 return 1;
10833 };
10834
rdfstore_statement_get_node(RDF_Statement * st)10835 RDF_Node * rdfstore_statement_get_node(
10836 RDF_Statement * st ) {
10837
10838 if ( st == NULL )
10839 return 0;
10840
10841 return st->node;
10842 };
10843
rdfstore_statement_set_node(RDF_Statement * st,RDF_Node * node)10844 int rdfstore_statement_set_node(
10845 RDF_Statement * st,
10846 RDF_Node * node ) {
10847
10848 if ( st == NULL )
10849 return 0;
10850
10851 rdfstore_resource_free( st->node );
10852
10853 st->node = node;
10854
10855 return 1;
10856 };
10857
rdfstore_statement_free(RDF_Statement * st)10858 int rdfstore_statement_free(
10859 RDF_Statement * st ) {
10860
10861 if ( st == NULL )
10862 return 0;
10863
10864 rdfstore_resource_free( st->subject );
10865 rdfstore_resource_free( st->predicate );
10866 rdfstore_node_free( st->object );
10867 rdfstore_resource_free( st->context );
10868 rdfstore_resource_free( st->node );
10869
10870 RDFSTORE_FREE( st );
10871
10872 return 1;
10873 };
10874
rdfstore_statement_dump(RDF_Statement * st)10875 void rdfstore_statement_dump(
10876 RDF_Statement * st ) {
10877 unsigned char * buff=NULL;
10878
10879 if ( st == NULL )
10880 return;
10881
10882 buff = rdfstore_ntriples_statement( st, NULL );
10883
10884 if ( buff ) {
10885 fprintf(stderr, "(statement) %s\n", buff);
10886 RDFSTORE_FREE( buff );
10887 };
10888 };
10889
10890 /* for resource centric API ala Jena */
10891
rdfstore_statement_set_model(RDF_Statement * st,rdfstore * model)10892 int rdfstore_statement_set_model(
10893 RDF_Statement * st,
10894 rdfstore * model ) {
10895
10896 if ( ( st == NULL ) ||
10897 ( model == NULL ) )
10898 return 0;
10899
10900 st->model = model; /* tell it there is a guy attached to it??? */
10901
10902 return 1;
10903 };
10904
rdfstore_statement_reset_model(RDF_Statement * st)10905 int rdfstore_statement_reset_model(
10906 RDF_Statement * st ) {
10907
10908 if ( st == NULL )
10909 return 0;
10910
10911 st->model = NULL;
10912
10913 return 1;
10914 };
10915
rdfstore_statement_get_model(RDF_Statement * st)10916 rdfstore * rdfstore_statement_get_model(
10917 RDF_Statement * st ) {
10918
10919 if ( st == NULL )
10920 return 0;
10921
10922 return st->model;
10923 };
10924
10925 /* RDF_Triple_Pattern related ones */
10926
rdfstore_triple_pattern_new()10927 RDF_Triple_Pattern * rdfstore_triple_pattern_new() {
10928 RDF_Triple_Pattern * tp=NULL;
10929
10930 tp = (RDF_Triple_Pattern *)RDFSTORE_MALLOC(sizeof(RDF_Triple_Pattern));
10931
10932 if( tp == NULL )
10933 return NULL;
10934
10935 tp->subjects=NULL;
10936 tp->subjects_operator=0;
10937 tp->predicates=NULL;
10938 tp->predicates_operator=0;
10939 tp->objects=NULL;
10940 tp->objects_operator=0;
10941 tp->contexts=NULL;
10942 tp->contexts_operator=0;
10943 tp->langs=NULL;
10944 tp->langs_operator=0;
10945 tp->dts=NULL;
10946 tp->dts_operator=0;
10947 tp->words=NULL;
10948 tp->words_operator=0;
10949 tp->ranges=NULL;
10950 tp->ranges_operator=0;
10951
10952 return tp;
10953 };
10954
rdfstore_triple_pattern_add_subject(RDF_Triple_Pattern * tp,RDF_Node * node)10955 RDF_Triple_Pattern_Part * rdfstore_triple_pattern_add_subject(
10956 RDF_Triple_Pattern * tp,
10957 RDF_Node * node ) {
10958 RDF_Triple_Pattern_Part * li=NULL;
10959 RDF_Triple_Pattern_Part * li1=NULL;
10960 RDF_Triple_Pattern_Part * tail=NULL;
10961
10962 if ( ( tp == NULL ) ||
10963 ( node == NULL ) ||
10964 ( node->type == RDFSTORE_NODE_TYPE_LITERAL ) )
10965 return NULL;
10966
10967 li = (RDF_Triple_Pattern_Part *)RDFSTORE_MALLOC(sizeof(RDF_Triple_Pattern_Part));
10968
10969 if( li == NULL )
10970 return NULL;
10971
10972 li->type = RDFSTORE_TRIPLE_PATTERN_PART_RESOURCE_NODE;
10973 li->part.string = NULL;
10974 li->part.node = node;
10975 li->next = NULL;
10976
10977 if ( tp->subjects != NULL ) {
10978 li1 = tp->subjects;
10979 do {
10980 tail = li1;
10981 } while ( ( li1 = li1->next ) != NULL );
10982 tail->next = li;
10983 } else {
10984 tp->subjects = li;
10985 };
10986
10987 return li;
10988 };
10989
rdfstore_triple_pattern_set_subjects_operator(RDF_Triple_Pattern * tp,int op)10990 int rdfstore_triple_pattern_set_subjects_operator(
10991 RDF_Triple_Pattern * tp,
10992 int op ) {
10993 if ( ( tp == NULL ) ||
10994 ( op < 0 ) ||
10995 ( op > 2 ) )
10996 return 0;
10997
10998 tp->subjects_operator = op;
10999
11000 return 1;
11001 };
11002
rdfstore_triple_pattern_add_predicate(RDF_Triple_Pattern * tp,RDF_Node * node)11003 RDF_Triple_Pattern_Part * rdfstore_triple_pattern_add_predicate(
11004 RDF_Triple_Pattern * tp,
11005 RDF_Node * node ) {
11006 RDF_Triple_Pattern_Part * li=NULL;
11007 RDF_Triple_Pattern_Part * li1=NULL;
11008 RDF_Triple_Pattern_Part * tail=NULL;
11009
11010 if ( ( tp == NULL ) ||
11011 ( node == NULL ) ||
11012 ( node->type == RDFSTORE_NODE_TYPE_LITERAL ) )
11013 return NULL;
11014
11015 li = (RDF_Triple_Pattern_Part *)RDFSTORE_MALLOC(sizeof(RDF_Triple_Pattern_Part));
11016
11017 if( li == NULL )
11018 return NULL;
11019
11020 li->type = RDFSTORE_TRIPLE_PATTERN_PART_RESOURCE_NODE;
11021 li->part.string = NULL;
11022 li->part.node = node;
11023 li->next = NULL;
11024
11025 if ( tp->predicates != NULL ) {
11026 li1 = tp->predicates;
11027 do {
11028 tail = li1;
11029 } while ( ( li1 = li1->next ) != NULL );
11030 tail->next = li;
11031 } else {
11032 tp->predicates = li;
11033 };
11034
11035 return li;
11036 };
11037
rdfstore_triple_pattern_set_predicates_operator(RDF_Triple_Pattern * tp,int op)11038 int rdfstore_triple_pattern_set_predicates_operator(
11039 RDF_Triple_Pattern * tp,
11040 int op ) {
11041 if ( ( tp == NULL ) ||
11042 ( op < 0 ) ||
11043 ( op > 2 ) )
11044 return 0;
11045
11046 tp->predicates_operator = op;
11047
11048 return 1;
11049 };
11050
rdfstore_triple_pattern_add_object(RDF_Triple_Pattern * tp,RDF_Node * node)11051 RDF_Triple_Pattern_Part * rdfstore_triple_pattern_add_object(
11052 RDF_Triple_Pattern * tp,
11053 RDF_Node * node ) {
11054 RDF_Triple_Pattern_Part * li=NULL;
11055 RDF_Triple_Pattern_Part * li1=NULL;
11056 RDF_Triple_Pattern_Part * tail=NULL;
11057
11058 if ( ( tp == NULL ) ||
11059 ( node == NULL ) )
11060 return NULL;
11061
11062 li = (RDF_Triple_Pattern_Part *)RDFSTORE_MALLOC(sizeof(RDF_Triple_Pattern_Part));
11063
11064 if( li == NULL )
11065 return NULL;
11066
11067 li->type = ( node->type == RDFSTORE_NODE_TYPE_LITERAL ) ? RDFSTORE_TRIPLE_PATTERN_PART_LITERAL_NODE : RDFSTORE_TRIPLE_PATTERN_PART_RESOURCE_NODE ;
11068 li->part.string = NULL;
11069 li->part.node = node;
11070 li->next = NULL;
11071
11072 if ( tp->objects != NULL ) {
11073 li1 = tp->objects;
11074 do {
11075 tail = li1;
11076 } while ( ( li1 = li1->next ) != NULL );
11077 tail->next = li;
11078 } else {
11079 tp->objects = li;
11080 };
11081
11082 return li;
11083 };
11084
rdfstore_triple_pattern_set_objects_operator(RDF_Triple_Pattern * tp,int op)11085 int rdfstore_triple_pattern_set_objects_operator(
11086 RDF_Triple_Pattern * tp,
11087 int op ) {
11088 if ( ( tp == NULL ) ||
11089 ( op < 0 ) ||
11090 ( op > 2 ) )
11091 return 0;
11092
11093 tp->objects_operator = op;
11094
11095 return 1;
11096 };
11097
rdfstore_triple_pattern_add_context(RDF_Triple_Pattern * tp,RDF_Node * node)11098 RDF_Triple_Pattern_Part * rdfstore_triple_pattern_add_context(
11099 RDF_Triple_Pattern * tp,
11100 RDF_Node * node ) {
11101 RDF_Triple_Pattern_Part * li=NULL;
11102 RDF_Triple_Pattern_Part * li1=NULL;
11103 RDF_Triple_Pattern_Part * tail=NULL;
11104
11105 if ( ( tp == NULL ) ||
11106 ( node == NULL ) ||
11107 ( node->type == RDFSTORE_NODE_TYPE_LITERAL ) )
11108 return NULL;
11109
11110 li = (RDF_Triple_Pattern_Part *)RDFSTORE_MALLOC(sizeof(RDF_Triple_Pattern_Part));
11111
11112 if( li == NULL )
11113 return NULL;
11114
11115 li->type = RDFSTORE_TRIPLE_PATTERN_PART_RESOURCE_NODE;
11116 li->part.string = NULL;
11117 li->part.node = node;
11118 li->next = NULL;
11119
11120 if ( tp->contexts != NULL ) {
11121 li1 = tp->contexts;
11122 do {
11123 tail = li1;
11124 } while ( ( li1 = li1->next ) != NULL );
11125 tail->next = li;
11126 } else {
11127 tp->contexts = li;
11128 };
11129
11130 return li;
11131 };
11132
rdfstore_triple_pattern_set_contexts_operator(RDF_Triple_Pattern * tp,int op)11133 int rdfstore_triple_pattern_set_contexts_operator(
11134 RDF_Triple_Pattern * tp,
11135 int op ) {
11136 if ( ( tp == NULL ) ||
11137 ( op < 0 ) ||
11138 ( op > 2 ) )
11139 return 0;
11140
11141 tp->contexts_operator = op;
11142
11143 return 1;
11144 };
11145
rdfstore_triple_pattern_add_lang(RDF_Triple_Pattern * tp,char * lang)11146 RDF_Triple_Pattern_Part * rdfstore_triple_pattern_add_lang(
11147 RDF_Triple_Pattern * tp,
11148 char * lang ) {
11149 RDF_Triple_Pattern_Part * li=NULL;
11150 RDF_Triple_Pattern_Part * li1=NULL;
11151 RDF_Triple_Pattern_Part * tail=NULL;
11152
11153 if ( ( tp == NULL ) ||
11154 ( lang == NULL ) ||
11155 ( strlen( lang ) <= 0 ) )
11156 return NULL;
11157
11158 li = (RDF_Triple_Pattern_Part *)RDFSTORE_MALLOC(sizeof(RDF_Triple_Pattern_Part));
11159
11160 if( li == NULL )
11161 return NULL;
11162
11163 li->type = RDFSTORE_TRIPLE_PATTERN_PART_STRING;
11164 li->part.node = NULL;
11165 li->part.string = NULL;
11166 li->part.string = (unsigned char *) RDFSTORE_MALLOC( sizeof(unsigned char) * ( strlen(lang) + 1 ) );
11167 if ( li->part.string == NULL ) {
11168 RDFSTORE_FREE( li );
11169 return NULL;
11170 };
11171 strcpy( li->part.string, lang);
11172 li->next = NULL;
11173
11174 if ( tp->langs != NULL ) {
11175 li1 = tp->langs;
11176 do {
11177 tail = li1;
11178 } while ( ( li1 = li1->next ) != NULL );
11179 tail->next = li;
11180 } else {
11181 tp->langs = li;
11182 };
11183
11184 return li;
11185 };
11186
rdfstore_triple_pattern_set_langs_operator(RDF_Triple_Pattern * tp,int op)11187 int rdfstore_triple_pattern_set_langs_operator(
11188 RDF_Triple_Pattern * tp,
11189 int op ) {
11190 if ( ( tp == NULL ) ||
11191 ( op < 0 ) ||
11192 ( op > 2 ) )
11193 return 0;
11194
11195 tp->langs_operator = op;
11196
11197 return 1;
11198 };
11199
rdfstore_triple_pattern_add_datatype(RDF_Triple_Pattern * tp,char * dt,int len)11200 RDF_Triple_Pattern_Part * rdfstore_triple_pattern_add_datatype(
11201 RDF_Triple_Pattern * tp,
11202 char * dt,
11203 int len ) {
11204 RDF_Triple_Pattern_Part * li=NULL;
11205 RDF_Triple_Pattern_Part * li1=NULL;
11206 RDF_Triple_Pattern_Part * tail=NULL;
11207
11208 if ( ( tp == NULL ) ||
11209 ( dt == NULL ) ||
11210 ( len <= 0 ) )
11211 return NULL;
11212
11213 li = (RDF_Triple_Pattern_Part *)RDFSTORE_MALLOC(sizeof(RDF_Triple_Pattern_Part));
11214
11215 if( li == NULL )
11216 return NULL;
11217
11218 li->type = RDFSTORE_TRIPLE_PATTERN_PART_STRING;
11219 li->part.node = NULL;
11220
11221 li->part.string = NULL;
11222 li->part.string = (unsigned char *) RDFSTORE_MALLOC( sizeof(unsigned char) * len );
11223 if ( li->part.string == NULL ) {
11224 RDFSTORE_FREE( li );
11225 return NULL;
11226 };
11227 memcpy( li->part.string, dt, len );
11228 memcpy( li->part.string+len, "\0", 1);
11229
11230 li->next = NULL;
11231
11232 if ( tp->dts != NULL ) {
11233 li1 = tp->dts;
11234 do {
11235 tail = li1;
11236 } while ( ( li1 = li1->next ) != NULL );
11237 tail->next = li;
11238 } else {
11239 tp->dts = li;
11240 };
11241
11242 return li;
11243 };
11244
rdfstore_triple_pattern_set_datatypes_operator(RDF_Triple_Pattern * tp,int op)11245 int rdfstore_triple_pattern_set_datatypes_operator(
11246 RDF_Triple_Pattern * tp,
11247 int op ) {
11248 if ( ( tp == NULL ) ||
11249 ( op < 0 ) ||
11250 ( op > 2 ) )
11251 return 0;
11252
11253 tp->dts_operator = op;
11254
11255 return 1;
11256 };
11257
rdfstore_triple_pattern_add_word(RDF_Triple_Pattern * tp,unsigned char * word,int len)11258 RDF_Triple_Pattern_Part * rdfstore_triple_pattern_add_word(
11259 RDF_Triple_Pattern * tp,
11260 unsigned char * word,
11261 int len ) {
11262 RDF_Triple_Pattern_Part * li=NULL;
11263 RDF_Triple_Pattern_Part * li1=NULL;
11264 RDF_Triple_Pattern_Part * tail=NULL;
11265
11266 if ( ( tp == NULL ) ||
11267 ( word == NULL ) ||
11268 ( len <= 0 ) )
11269 return NULL;
11270
11271 li = (RDF_Triple_Pattern_Part *)RDFSTORE_MALLOC(sizeof(RDF_Triple_Pattern_Part));
11272
11273 if( li == NULL )
11274 return NULL;
11275
11276 li->type = RDFSTORE_TRIPLE_PATTERN_PART_STRING;
11277 li->part.node = NULL;
11278
11279 li->part.string = NULL;
11280 li->part.string = (unsigned char *) RDFSTORE_MALLOC( sizeof(unsigned char) * len );
11281 if ( li->part.string == NULL ) {
11282 RDFSTORE_FREE( li );
11283 return NULL;
11284 };
11285 memcpy( li->part.string, word, len );
11286 memcpy( li->part.string+len, "\0", 1);
11287
11288 li->next = NULL;
11289
11290 if ( tp->words != NULL ) {
11291 li1 = tp->words;
11292 do {
11293 tail = li1;
11294 } while ( ( li1 = li1->next ) != NULL );
11295 tail->next = li;
11296 } else {
11297 tp->words = li;
11298 };
11299
11300 return li;
11301 };
11302
rdfstore_triple_pattern_set_words_operator(RDF_Triple_Pattern * tp,int op)11303 int rdfstore_triple_pattern_set_words_operator(
11304 RDF_Triple_Pattern * tp,
11305 int op ) {
11306 if ( ( tp == NULL ) ||
11307 ( op < 0 ) ||
11308 ( op > 2 ) )
11309 return 0;
11310
11311 tp->words_operator = op;
11312
11313 return 1;
11314 };
11315
rdfstore_triple_pattern_add_ranges(RDF_Triple_Pattern * tp,char * num,int len)11316 RDF_Triple_Pattern_Part * rdfstore_triple_pattern_add_ranges(
11317 RDF_Triple_Pattern * tp,
11318 char * num,
11319 int len ) {
11320 RDF_Triple_Pattern_Part * li=NULL;
11321 RDF_Triple_Pattern_Part * li1=NULL;
11322 RDF_Triple_Pattern_Part * tail=NULL;
11323
11324 if ( ( tp == NULL ) ||
11325 ( num == NULL ) ||
11326 ( len <= 0 ) )
11327 return NULL;
11328
11329 li = (RDF_Triple_Pattern_Part *)RDFSTORE_MALLOC(sizeof(RDF_Triple_Pattern_Part));
11330
11331 if( li == NULL )
11332 return NULL;
11333
11334 li->type = RDFSTORE_TRIPLE_PATTERN_PART_STRING;
11335 li->part.node = NULL;
11336
11337 li->part.string = NULL;
11338 li->part.string = (unsigned char *) RDFSTORE_MALLOC( sizeof(unsigned char) * len );
11339 if ( li->part.string == NULL ) {
11340 RDFSTORE_FREE( li );
11341 return NULL;
11342 };
11343 memcpy( li->part.string, num, len );
11344 memcpy( li->part.string+len, "\0", 1);
11345
11346 li->next = NULL;
11347
11348 if ( tp->ranges != NULL ) {
11349 li1 = tp->ranges;
11350 do {
11351 tail = li1;
11352 } while ( ( li1 = li1->next ) != NULL );
11353 tail->next = li;
11354 } else {
11355 tp->ranges = li;
11356 };
11357
11358 return li;
11359 };
11360
rdfstore_triple_pattern_set_ranges_operator(RDF_Triple_Pattern * tp,int op)11361 int rdfstore_triple_pattern_set_ranges_operator(
11362 RDF_Triple_Pattern * tp,
11363 int op ) {
11364 if ( ( tp == NULL ) ||
11365 ( op < 0 ) ||
11366 ( op > 10 ) )
11367 return 0;
11368
11369 tp->ranges_operator = op;
11370
11371 return 1;
11372 };
11373
_rdfstore_triple_pattern_free_part(RDF_Triple_Pattern_Part * list)11374 int _rdfstore_triple_pattern_free_part(
11375 RDF_Triple_Pattern_Part * list ) {
11376 if ( list == NULL )
11377 return 0;
11378
11379 _rdfstore_triple_pattern_free_part( list->next );
11380
11381 if ( list->type == RDFSTORE_TRIPLE_PATTERN_PART_STRING ) {
11382 if ( list->part.string != NULL )
11383 RDFSTORE_FREE( list->part.string );
11384 } else {
11385 rdfstore_node_free( list->part.node );
11386 };
11387
11388 RDFSTORE_FREE( list );
11389
11390 return 1;
11391 };
11392
rdfstore_triple_pattern_free(RDF_Triple_Pattern * tp)11393 int rdfstore_triple_pattern_free(
11394 RDF_Triple_Pattern * tp ) {
11395
11396 if ( tp == NULL )
11397 return 0;
11398
11399 if ( tp->subjects != NULL )
11400 _rdfstore_triple_pattern_free_part( tp->subjects );
11401
11402 if ( tp->predicates != NULL )
11403 _rdfstore_triple_pattern_free_part( tp->predicates );
11404
11405 if ( tp->objects != NULL )
11406 _rdfstore_triple_pattern_free_part( tp->objects );
11407
11408 if ( tp->contexts != NULL )
11409 _rdfstore_triple_pattern_free_part( tp->contexts );
11410
11411 if ( tp->langs != NULL )
11412 _rdfstore_triple_pattern_free_part( tp->langs );
11413
11414 if ( tp->dts != NULL )
11415 _rdfstore_triple_pattern_free_part( tp->dts );
11416
11417 if ( tp->ranges != NULL )
11418 _rdfstore_triple_pattern_free_part( tp->ranges );
11419
11420 if ( tp->words != NULL )
11421 _rdfstore_triple_pattern_free_part( tp->words );
11422
11423 RDFSTORE_FREE( tp );
11424
11425 return 1;
11426 };
11427
rdfstore_triple_pattern_dump(RDF_Triple_Pattern * tp)11428 void rdfstore_triple_pattern_dump(
11429 RDF_Triple_Pattern * tp ) {
11430 RDF_Triple_Pattern_Part * tpj=NULL;
11431
11432 if (tp != NULL) {
11433 fprintf(stderr,"Triple pattern search:\n");
11434 if (tp->subjects != NULL) {
11435 fprintf(stderr,"Subjects: (%s)\n", ( tp->subjects_operator == 0 ) ? "OR" : ( tp->subjects_operator == 1 ) ? "AND" : "NOT" );
11436 tpj = tp->subjects;
11437 do {
11438 fprintf(stderr,"\tS='%s'\n", tpj->part.node->value.resource.identifier );
11439 } while ( ( tpj = tpj->next ) != NULL );
11440 };
11441 if (tp->predicates != NULL) {
11442 fprintf(stderr,"Predicates: (%s)\n", ( tp->predicates_operator == 0 ) ? "OR" : ( tp->predicates_operator == 1 ) ? "AND" : "NOT");
11443 tpj = tp->predicates;
11444 do {
11445 fprintf(stderr,"\tP='%s'\n", tpj->part.node->value.resource.identifier );
11446 } while ( ( tpj = tpj->next ) != NULL );
11447 };
11448 if (tp->objects != NULL) {
11449 fprintf(stderr,"Objects: (%s)\n", ( tp->objects_operator == 0 ) ? "OR" : ( tp->objects_operator == 1 ) ? "AND" : "NOT");
11450 tpj = tp->objects;
11451 do {
11452 if ( tpj->part.node->type != RDFSTORE_NODE_TYPE_LITERAL ) {
11453 fprintf(stderr,"\tO='%s'\n", tpj->part.node->value.resource.identifier );
11454 } else {
11455 fprintf(stderr,"\tOLIT='%s'", tpj->part.node->value.literal.string );
11456 /* do not search parser type in RDQL/BRQL??
11457 fprintf(stderr," PARSETYPE='%d'", tpj->part.node->value.literal.parseType);
11458 */
11459 fprintf(stderr,"\n");
11460 };
11461 } while ( ( tpj = tpj->next ) != NULL );
11462 };
11463 if (tp->langs != NULL) {
11464 fprintf(stderr,"Languages: (%s)\n", ( tp->langs_operator == 0 ) ? "OR" : ( tp->langs_operator == 1 ) ? "AND" : "NOT");
11465 tpj = tp->langs;
11466 do {
11467 fprintf(stderr,"\txml:lang='%s'\n", tpj->part.string );
11468 } while ( ( tpj = tpj->next ) != NULL );
11469 };
11470 if (tp->dts != NULL) {
11471 fprintf(stderr,"Datatypes: (%s)\n", ( tp->dts_operator == 0 ) ? "OR" : ( tp->dts_operator == 1 ) ? "AND" : "NOT");
11472 tpj = tp->dts;
11473 do {
11474 fprintf(stderr,"\trdf:datatype='%s'\n", tpj->part.string );
11475 } while ( ( tpj = tpj->next ) != NULL );
11476 };
11477 if (tp->ranges != NULL) {
11478 fprintf(stderr,"Ranges: (%s)\n", ( tp->ranges_operator == 1 ) ? "<" :
11479 ( tp->ranges_operator == 2 ) ? "<=" :
11480 ( tp->ranges_operator == 3 ) ? "==" :
11481 ( tp->ranges_operator == 4 ) ? "!=" :
11482 ( tp->ranges_operator == 5 ) ? ">=" :
11483 ( tp->ranges_operator == 6 ) ? ">":
11484 ( tp->ranges_operator == 7 ) ? "a < b < c":
11485 ( tp->ranges_operator == 8 ) ? "a <= b < c":
11486 ( tp->ranges_operator == 9 ) ? "a <= b <= c": "a < b <= c" );
11487 tpj = tp->ranges; /* it will have one element only anyway */
11488 do {
11489 fprintf(stderr,"\tterm='%s'\n", tpj->part.string );
11490 } while ( ( tpj = tpj->next ) != NULL );
11491 };
11492 if (tp->words != NULL) {
11493 fprintf(stderr,"Words: (%s)\n", ( tp->words_operator == 0 ) ? "OR" : ( tp->words_operator == 1 ) ? "AND" : "NOT");
11494 tpj = tp->words;
11495 do {
11496 fprintf(stderr,"\tword/stem='%s'\n", tpj->part.string );
11497 } while ( ( tpj = tpj->next ) != NULL );
11498 };
11499 if (tp->contexts != NULL) {
11500 fprintf(stderr,"Contexts: (%s)\n", ( tp->contexts_operator == 0 ) ? "OR" : ( tp->contexts_operator == 1 ) ? "AND" : "NOT");
11501 tpj = tp->contexts;
11502 do {
11503 fprintf(stderr,"\tC='%s'\n", tpj->part.node->value.resource.identifier );
11504 } while ( ( tpj = tpj->next ) != NULL );
11505 };
11506 };
11507 };
11508
11509