static void insert_quad(xmlctxt *ctxt) { fs_rid buffer[1][4]; int subj = FS_RID_SEGMENT(ctxt->s, ctxt->segments); int obj = FS_RID_SEGMENT(ctxt->o, ctxt->segments); buffer[0][0] = ctxt->m; buffer[0][1] = ctxt->s; buffer[0][2] = ctxt->p; buffer[0][3] = ctxt->o; fsp_quad_import(ctxt->link, subj, FS_BIND_BY_SUBJECT, 1, buffer); fsp_quad_import(ctxt->link, obj, FS_BIND_BY_OBJECT, 1, buffer); }
static int insert_rasqal_triple(struct update_context *uc, rasqal_triple *triple, int row) { fs_rid quad_buf[1][4]; fs_resource res; if (triple->origin) { fs_resource_from_rasqal_literal(uc, triple->origin, &res, row); quad_buf[0][0] = fs_hash_rasqal_literal(uc, triple->origin, row); } else if (uc->op->graph_uri) { res.lex = (char *)raptor_uri_as_string(uc->op->graph_uri); res.attr = FS_RID_NULL; quad_buf[0][0] = fs_hash_uri((char *)raptor_uri_as_string(uc->op->graph_uri)); } else { quad_buf[0][0] = fs_c.default_graph; res.lex = FS_DEFAULT_GRAPH; res.attr = FS_RID_NULL; } if (quad_buf[0][0] == fs_c.system_config) fsp_reload_acl_system(uc->link); if (!FS_IS_URI(quad_buf[0][0])) { return 1; } quad_buf[0][1] = fs_hash_rasqal_literal(uc, triple->subject, row); if (FS_IS_LITERAL(quad_buf[0][1])) { return 1; } quad_buf[0][2] = fs_hash_rasqal_literal(uc, triple->predicate, row); if (!FS_IS_URI(quad_buf[0][2])) { return 1; } quad_buf[0][3] = fs_hash_rasqal_literal(uc, triple->object, row); res.rid = quad_buf[0][0]; if (res.lex) fsp_res_import(uc->link, FS_RID_SEGMENT(quad_buf[0][0], uc->segments), 1, &res); res.rid = quad_buf[0][1]; fs_resource_from_rasqal_literal(uc, triple->subject, &res, 0); if (res.lex) fsp_res_import(uc->link, FS_RID_SEGMENT(quad_buf[0][1], uc->segments), 1, &res); res.rid = quad_buf[0][2]; fs_resource_from_rasqal_literal(uc, triple->predicate, &res, 0); if (res.lex) fsp_res_import(uc->link, FS_RID_SEGMENT(quad_buf[0][2], uc->segments), 1, &res); res.rid = quad_buf[0][3]; fs_resource_from_rasqal_literal(uc, triple->object, &res, 0); if (res.lex) fsp_res_import(uc->link, FS_RID_SEGMENT(quad_buf[0][3], uc->segments), 1, &res); fsp_quad_import(uc->link, FS_RID_SEGMENT(quad_buf[0][1], uc->segments), FS_BIND_BY_SUBJECT, 1, quad_buf); //printf("I %016llx %016llx %016llx %016llx\n", quad_buf[0][0], quad_buf[0][1], quad_buf[0][2], quad_buf[0][3]); return 0; }
fs_value fn_datatype(fs_query *q, fs_value a) { #if 0 printf("datatype("); fs_value_print(a); printf(")\n"); #endif if (a.valid & fs_valid_bit(FS_V_TYPE_ERROR)) { return a; } if (a.valid & fs_valid_bit(FS_V_RID) && FS_IS_URI_BN(a.rid)) { return fs_value_error(FS_ERROR_INVALID_TYPE, NULL); } if (a.attr == FS_RID_NULL) { return fs_value_error(FS_ERROR_INVALID_TYPE, NULL); } if (FS_IS_LITERAL(a.attr) && a.attr != fs_c.empty) { return fs_value_error(FS_ERROR_INVALID_TYPE, NULL); } else { if (a.attr == fs_c.xsd_string || a.attr == fs_c.empty) { return fs_value_uri(XSD_STRING); } else if (a.attr == fs_c.xsd_double) { return fs_value_uri(XSD_DOUBLE); } else if (a.attr == fs_c.xsd_float) { return fs_value_uri(XSD_FLOAT); } else if (a.attr == fs_c.xsd_decimal) { return fs_value_uri(XSD_DECIMAL); } else if (a.attr == fs_c.xsd_integer) { return fs_value_uri(XSD_INTEGER); } else if (a.attr == fs_c.xsd_boolean) { return fs_value_uri(XSD_BOOLEAN); } else if (a.attr == fs_c.xsd_datetime) { return fs_value_uri(XSD_DATETIME); } } fs_rid_vector *r = fs_rid_vector_new(1); r->data[0] = a.attr; fs_resource res; if (fs_query_link(q)) { fsp_resolve(fs_query_link(q), FS_RID_SEGMENT(a.attr, fsp_link_segments(fs_query_link(q))), r, &res); fs_rid_vector_free(r); return fs_value_uri(res.lex); } return fs_value_uri("error:unresloved"); }
static char *get_lex(fsp_link *link, fs_rid rid) { if (rid == FS_RID_NULL) return g_strdup("*"); const int segments = fsp_link_segments(link); fs_resource res; fs_rid_vector *rv = fs_rid_vector_new(1); rv->data[0] = rid; fsp_resolve(link, FS_RID_SEGMENT(rid, segments), rv, &res); fs_rid_vector_free(rv); if (!strncmp(RDF_NAMESPACE, res.lex, strlen(RDF_NAMESPACE))) { char *new = g_strdup_printf("rdf:%s", res.lex + strlen(RDF_NAMESPACE)); g_free(res.lex); return new; }
static void insert_resource(xmlctxt *ctxt, fs_rid rid, fs_rid attr, char* lex) { /* TODO a cache might speed things up */ int segment = FS_RID_SEGMENT(rid, ctxt->segments); resources[segment][res_count[segment]].rid = rid; resources[segment][res_count[segment]].attr = attr; resources[segment][res_count[segment]].lex = g_strdup(lex); if (++res_count[segment] == RES_BUF_SIZE) { fsp_res_import(ctxt->link, segment, RES_BUF_SIZE, resources[segment]); for (int k = 0; k < RES_BUF_SIZE; ++k) { g_free(resources[segment][k].lex); } res_count[segment] = 0; } }
fs_value fn_lang(fs_query *q, fs_value a) { if (a.valid & fs_valid_bit(FS_V_TYPE_ERROR)) { return a; } if (a.valid & fs_valid_bit(FS_V_RID) && FS_IS_URI_BN(a.rid)) { return fs_value_error(FS_ERROR_INVALID_TYPE, NULL); } if (a.attr == FS_RID_NULL) { return fs_value_error(FS_ERROR_INVALID_TYPE, NULL); } if (FS_IS_URI(a.attr)) { return fs_value_plain(""); } else { if (a.attr == fs_c.lang_en) { return fs_value_plain("en"); } else if (a.attr == fs_c.lang_fr) { return fs_value_plain("fr"); } else if (a.attr == fs_c.lang_de) { return fs_value_plain("de"); } else if (a.attr == fs_c.lang_es) { return fs_value_plain("es"); } else if (a.attr == fs_c.empty) { return fs_value_plain(""); } } fs_rid_vector *r = fs_rid_vector_new(1); r->data[0] = a.attr; fs_resource res; if (fs_query_link(q)) { fsp_resolve(fs_query_link(q), FS_RID_SEGMENT(a.attr, fsp_link_segments(fs_query_link(q))), r, &res); fs_rid_vector_free(r); fs_query_add_freeable(q, res.lex); return fs_value_plain(res.lex); } return fs_value_plain("???"); }
/* insert the triples in s, p, o into model */ static int insert_triples(struct update_context *uc, fs_rid model, fs_rid_vector *s, fs_rid_vector *p, fs_rid_vector *o) { for (int i=0; i<s->length; i++) { int segment = FS_RID_SEGMENT(s->data[i], uc->segments); int pos = quad_buffer[segment].length; quad_buffer[segment].quads[pos][0] = model; quad_buffer[segment].quads[pos][1] = s->data[i]; quad_buffer[segment].quads[pos][2] = p->data[i]; quad_buffer[segment].quads[pos][3] = o->data[i]; quad_buffer[segment].length++; if (quad_buffer[segment].length == QUAD_BUF_SIZE) { fsp_quad_import(uc->link, segment, FS_BIND_BY_SUBJECT, quad_buffer[segment].length, quad_buffer[segment].quads); quad_buffer[segment].length = 0; } } flush_triples(uc); //if (model == fs printf("%p ",uc->link->kb_name); return 0; }
void fs_resource_from_rasqal_literal(struct update_context *uctxt, rasqal_literal *l, fs_resource *res, int row) { if (!l) { res->lex = "(null)"; res->attr = FS_RID_NULL; return; } rasqal_literal_type type = l->type; if (type == RASQAL_LITERAL_VARIABLE) { /* right now you can't introduce new literals in INSERT, so it doesn't * matter */ res->lex = NULL; res->attr = FS_RID_GONE; } else if (type == RASQAL_LITERAL_URI) { res->lex = (char *)raptor_uri_as_string(l->value.uri); res->attr = FS_RID_NULL; } else { res->lex = (char *)l->string; res->attr = 0; fs_resource ares; ares.lex = NULL; if (l->datatype) { res->attr = fs_hash_uri((char *)raptor_uri_as_string(l->datatype)); ares.rid = res->attr; ares.lex = (char *)raptor_uri_as_string(l->datatype); ares.attr = FS_RID_NULL; } else if (l->language) { res->attr = fs_hash_literal(l->language, 0); ares.rid = res->attr; ares.lex = (char *)l->language; ares.attr = 0; } /* insert attribute resource if there is one */ if (ares.lex) { fsp_res_import(uctxt->link, FS_RID_SEGMENT(ares.rid, uctxt->segments), 1, &ares); } } }
static int buffer_res(fsp_link *link, const int segments, fs_rid r, char *lex, fs_rid attr, int dryrun) { int seg = FS_RID_SEGMENT(r, segments); if (FS_IS_BNODE(r)) { return 1; } if (nodecache[r & CACHE_MASK] == r) { return 1; } if (!lex) { return 1; } nodecache[r & CACHE_MASK] = r; res_buffer[seg][res_pos[seg]].rid = r; res_buffer[seg][res_pos[seg]].attr = attr; if (strlen(lex) < RES_BUF_SIZE) { strcpy(lex_tmp[seg][res_pos[seg]], lex); res_buffer[seg][res_pos[seg]].lex = lex_tmp[seg][res_pos[seg]]; } else { res_buffer[seg][res_pos[seg]].lex = g_strdup(lex); } if (++res_pos[seg] == RES_BUF_SIZE) { if (!(dryrun & FS_DRYRUN_RESOURCES) && fsp_res_import(link, seg, res_pos[seg], res_buffer[seg])) { fs_error(LOG_ERR, "resource import failed"); return 1; } for (int i=0; i<res_pos[seg]; i++) { if (res_buffer[seg][i].lex != lex_tmp[seg][i]) { free(res_buffer[seg][i].lex); res_buffer[seg][i].lex = NULL; } } res_pos[seg] = 0; } return 0; }
int fs_copy(struct update_context *uc, char *from, char *to) { fs_rid_vector *mvec = fs_rid_vector_new(0); fs_rid_vector *empty = fs_rid_vector_new(0); fs_rid fromrid, torid; if (from) { fromrid = fs_hash_uri(from); } else { from = FS_DEFAULT_GRAPH; fromrid = fs_c.default_graph; } if (to) { torid = fs_hash_uri(to); } else { to = FS_DEFAULT_GRAPH; torid = fs_c.default_graph; } if (fromrid == torid) { /*don't need to do anything */ fs_rid_vector_free(mvec); fs_rid_vector_free(empty); add_message(uc, g_strdup_printf("Copied <%s> to <%s>", from, to), 1); add_message(uc, "0 triples added, 0 removed", 0); return 0; } fs_rid_vector_append(mvec, fromrid); /* search for all the triples in from */ fs_rid_vector **results; fs_rid_vector *slot[4] = { mvec, empty, empty, empty }; /* see if there's any data in <from> */ fs_bind_cache_wrapper(uc->qs, NULL, 1, FS_BIND_BY_SUBJECT | FS_BIND_SUBJECT, slot, &results, -1, 1); if (!results || results[0]->length == 0) { if (results) { fs_rid_vector_free(results[0]); free(results); } fs_rid_vector_free(mvec); fs_rid_vector_free(empty); add_message(uc, g_strdup_printf("<%s> is empty, not copying", from), 1); return 1; } fs_rid_vector_free(results[0]); free(results); /* get the contents of <from> */ fs_bind_cache_wrapper(uc->qs, NULL, 1, FS_BIND_BY_SUBJECT | FS_BIND_SUBJECT | FS_BIND_PREDICATE | FS_BIND_OBJECT, slot, &results, -1, -1); /* map old bnodes to new ones */ map_bnodes(uc, results[0]); map_bnodes(uc, results[1]); map_bnodes(uc, results[2]); /* delete <to> */ mvec->data[0] = torid; if (fsp_delete_model_all(uc->link, mvec)) { fs_rid_vector_free(mvec); fs_rid_vector_free(empty); add_message(uc, g_strdup_printf("Error while trying to delete %s", to), 1); return 1; } fs_rid_vector_free(mvec); fs_rid_vector_free(empty); /* insert <to> */ fs_resource tores; tores.lex = to; tores.attr= FS_RID_NULL; tores.rid = torid; fsp_res_import(uc->link, FS_RID_SEGMENT(torid, uc->segments), 1, &tores); insert_triples(uc, torid, results[0], results[1], results[2]); add_message(uc, g_strdup_printf("Copied <%s> to <%s>", from, to), 1); add_message(uc, g_strdup_printf("%d triples added, ?? removed", results[0]->length), 1); for (int i=0; i<3; i++) { fs_rid_vector_free(results[i]); } free(results); return 0; }
int fs_add(struct update_context *uc, char *from, char *to) { fs_rid_vector *mvec = fs_rid_vector_new(0); fs_rid_vector *empty = fs_rid_vector_new(0); fs_rid fromrid, torid; if (from) { fromrid = fs_hash_uri(from); } else { from = FS_DEFAULT_GRAPH; fromrid = fs_c.default_graph; } if (to) { torid = fs_hash_uri(to); } else { to = FS_DEFAULT_GRAPH; torid = fs_c.default_graph; } if (fromrid == torid) { /*don't need to do anything */ add_message(uc, g_strdup_printf("Added <%s> to <%s>", from, to), 1); add_message(uc, "0 triples added, 0 removed", 0); return 0; } fs_rid_vector_append(mvec, fromrid); int errors = 0; /* search for all the triples in from */ fs_rid_vector **results; fs_rid_vector *slot[4] = { mvec, empty, empty, empty }; fs_bind_cache_wrapper(uc->qs, NULL, 1, FS_BIND_BY_SUBJECT | FS_BIND_SUBJECT | FS_BIND_PREDICATE | FS_BIND_OBJECT, slot, &results, -1, -1); fs_rid_vector_free(mvec); fs_rid_vector_free(empty); if (!results || results[0]->length == 0) { /* there's nothing to add */ if (results) { for (int i=0; i<3; i++) { fs_rid_vector_free(results[i]); } free(results); } add_message(uc, g_strdup_printf("Added <%s> to <%s>", from, to), 1); add_message(uc, "0 triples added, 0 removed", 0); return 0; } map_bnodes(uc, results[0]); map_bnodes(uc, results[1]); map_bnodes(uc, results[2]); fs_resource tores; tores.lex = to; tores.attr= FS_RID_NULL; tores.rid = torid; fsp_res_import(uc->link, FS_RID_SEGMENT(torid, uc->segments), 1, &tores); insert_triples(uc, torid, results[0], results[1], results[2]); add_message(uc, g_strdup_printf("Added <%s> to <%s>", from, to), 1); add_message(uc, g_strdup_printf("%d triples added, 0 removed", results[0]->length), 1); for (int i=0; i<3; i++) { fs_rid_vector_free(results[i]); } free(results); return errors; }
xmlChar *get_uri(fsp_link *link, fs_rid rid) { if (cache[rid & CACHE_MASK].rid == rid) { return (xmlChar *) cache[rid & CACHE_MASK].lex; } fs_rid_vector onerid = { .length = 1, .size = 1, .data = &rid }; fs_resource resource; fsp_resolve(link, FS_RID_SEGMENT(rid, segments), &onerid, &resource); return (xmlChar *) resource.lex; } xmlChar *get_attr(fsp_link *link, fs_rid rid) { if (attr_cache[rid & CACHE_MASK].rid == rid) { return (xmlChar *) attr_cache[rid & CACHE_MASK].lex; } fs_rid_vector onerid = { .length = 1, .size = 1, .data = &rid }; fs_resource resource; fsp_resolve(link, FS_RID_SEGMENT(rid, segments), &onerid, &resource); memcpy(&attr_cache[rid & ATTR_CACHE_MASK], &resource, sizeof(fs_resource)); return (xmlChar *) resource.lex; } xmlChar *get_literal(fsp_link *link, fs_rid rid, fs_rid *attr) { if (cache[rid & CACHE_MASK].rid == rid) { *attr = cache[rid & CACHE_MASK].attr; return (xmlChar *) cache[rid & CACHE_MASK].lex; } fs_rid_vector onerid = { .length = 1, .size = 1, .data = &rid }; fs_resource resource; fsp_resolve(link, FS_RID_SEGMENT(rid, segments), &onerid, &resource); *attr = resource.attr; return (xmlChar *) resource.lex; } void resolve_triples(fsp_link *link, fs_rid_vector **rids) { int quads = rids[0]->length; fs_rid_vector *todo[segments]; fs_segment segment; for (segment = 0; segment < segments; ++segment) { todo[segment] = fs_rid_vector_new(0); } for (int c = 0; c < 3; ++c) { for (int k = 0; k < quads; ++k) { const fs_rid rid = rids[c]->data[k]; if (FS_IS_BNODE(rid) || cache[rid & CACHE_MASK].rid == rid) continue; fs_rid_vector_append(todo[FS_RID_SEGMENT(rid, segments)], rid); cache[rid & CACHE_MASK].rid = rid; /* well, it will be soon */ } } int length[segments]; fs_resource *resources[segments]; for (segment = 0; segment < segments; ++segment) { length[segment] = todo[segment]->length; resources[segment] = calloc(length[segment], sizeof(fs_resource)); } fsp_resolve_all(link, todo, resources); for (segment = 0; segment < segments; ++segment) { fs_resource *res = resources[segment]; for (int k = 0; k < length[segment]; ++k) { free(cache[res[k].rid & CACHE_MASK].lex); memcpy(&cache[res[k].rid & CACHE_MASK], &res[k], sizeof(fs_resource)); } fs_rid_vector_free(todo[segment]); free(resources[segment]); } } void dump_model(fsp_link *link, fs_rid model, xmlTextWriterPtr xml) { fs_rid_vector none = { .length = 0, .size = 0, .data = 0 }; fs_rid_vector one = { .length = 1, .size = 1, .data = &model }; fs_rid_vector **results; double then; /* for time keeping */ then = fs_time(); fsp_bind_first_all(link, BIND_SPO, &one, &none, &none, &none, &results, QUAD_LIMIT); time_bind_first += (fs_time() - then); while (results != NULL) { long length = results[0]->length; if (length == 0) break; then = fs_time(); resolve_triples(link, results); time_resolving += (fs_time() - then); then = fs_time(); for (int k = 0; k < length; ++k) { xmlTextWriterStartElement(xml, (xmlChar *) "triple"); for (int r = 0; r < 3; ++r) { fs_rid rid = results[r]->data[k]; if (FS_IS_BNODE(rid)) { unsigned long long node = FS_BNODE_NUM(rid); xmlTextWriterWriteFormatElement(xml, (xmlChar *) "id", "%llu", node); } else if (FS_IS_URI(rid)) { xmlChar *uri = get_uri(link, rid); xmlTextWriterWriteElement(xml, (xmlChar *) "uri", uri); } else if (FS_IS_LITERAL(rid)) { fs_rid attr; xmlChar *lex = get_literal(link, rid, &attr); if (attr == fs_c.empty) { xmlTextWriterWriteElement(xml, (xmlChar *) "plainLiteral", lex); } else if (FS_IS_URI(attr)) { xmlChar *type = get_uri(link, attr); xmlTextWriterStartElement(xml, (xmlChar *) "typedLiteral"); xmlTextWriterWriteString(xml, (xmlChar *) lex); xmlTextWriterWriteAttribute(xml, (xmlChar *) "datatype", type); xmlTextWriterEndElement(xml); } else if (FS_IS_LITERAL(attr)) { xmlChar *lang = get_attr(link, attr); xmlTextWriterStartElement(xml, (xmlChar *) "plainLiteral"); xmlTextWriterWriteAttribute(xml, (xmlChar *) "xml:lang", lang); xmlTextWriterWriteString(xml, (xmlChar *) lex); xmlTextWriterEndElement(xml); } } } xmlTextWriterEndElement(xml); xmlTextWriterWriteString(xml, (xmlChar *) "\n"); } time_write_out += (fs_time() - then); fs_rid_vector_free(results[0]); fs_rid_vector_free(results[1]); fs_rid_vector_free(results[2]); free(results); then = fs_time(); fsp_bind_next_all(link, BIND_SPO, &results, QUAD_LIMIT); time_bind_next += (fs_time() - then); } fsp_bind_done_all(link); } void dump_trix(fsp_link *link, xmlTextWriterPtr xml) { fs_rid_vector **models; fs_rid_vector none = { .length = 0, .size = 0, .data = 0 }; fsp_bind_all(link, FS_BIND_DISTINCT | FS_BIND_MODEL | FS_BIND_BY_SUBJECT, &none, &none, &none, &none, &models); fs_rid_vector_sort(models[0]); fs_rid_vector_uniq(models[0], 1); long length = models[0]->length; for (int k = 0; k < length; ++k) { fs_rid model = models[0]->data[k]; xmlChar *model_uri = get_uri(link, model); xmlTextWriterStartElement(xml, (xmlChar *) "graph"); if (FS_IS_URI(model)) { xmlTextWriterWriteElement(xml, (xmlChar *) "uri", model_uri); } else { fs_error(LOG_WARNING, "model %lld is not a URI", model); } dump_model(link, model, xml); xmlTextWriterEndElement(xml); xmlTextWriterWriteString(xml, (xmlChar *) "\n"); printf("%5d/%ld: %4.5f %4.5f %4.5f %4.5f\n", k + 1, length, time_resolving, time_bind_first, time_bind_next, time_write_out); } } void dump_file(fsp_link *link, char *filename) { xmlTextWriterPtr xml = xmlNewTextWriterFilename(filename, TRUE); if (!xml) { fs_error(LOG_ERR, "Couldn't write output file, giving up"); exit(4); } xmlTextWriterStartDocument(xml, NULL, NULL, NULL); xmlTextWriterStartElement(xml, (xmlChar *) "TriX"); dump_trix(link, xml); xmlTextWriterEndDocument(xml); /* also closes TriX */ xmlFreeTextWriter(xml); } int main(int argc, char *argv[]) { char *password = fsp_argv_password(&argc, argv); if (argc != 3) { fprintf(stderr, "%s revision %s\n", argv[0], FS_FRONTEND_VER); fprintf(stderr, "Usage: %s <kbname> <uri>\n", argv[0]); exit(1); } fsp_link *link = fsp_open_link(argv[1], password, FS_OPEN_HINT_RO); if (!link) { fs_error (LOG_ERR, "couldn't connect to ā%sā", argv[1]); exit(2); } fs_hash_init(fsp_hash_type(link)); segments = fsp_link_segments(link); dump_file(link, argv[2]); fsp_close_link(link); }
static int process_quads(fs_parse_stuff *data) { fsp_link *link = data->link; const int segments = data->segments; int tfd = data->quad_fd; int verbosity = data->verbosity; int dryrun = data->dryrun; int total = 0; int ret; struct timeval now; if (lseek(tfd, 0, SEEK_SET) == -1) { fs_error(LOG_ERR, "error seeking in triple buffer file (fd %d): %s", tfd, strerror(errno)); return -1; } do { ret = read(tfd, quad_buf, sizeof(quad_buf)); int count = ret / (sizeof(fs_rid) * 4); if (ret < 0) { fs_error(LOG_ERR, "error reading triple buffer file (fd %d): %s", tfd, strerror(errno)); return -1; } if (ret % sizeof(fs_rid) * 4 != 0) { fs_error(LOG_ERR, "bad read size, %d - not multiple of 4 RIDs", ret); return -1; } total += count; for (int seg=0; seg < segments; seg++) { int i=0, scnt = 0; for (i=0; i<count; i++) { if (FS_RID_SEGMENT(quad_buf[i][1], segments) == seg) { quad_buf_s[scnt][0] = quad_buf[i][0]; quad_buf_s[scnt][1] = quad_buf[i][1]; quad_buf_s[scnt][2] = quad_buf[i][2]; quad_buf_s[scnt][3] = quad_buf[i][3]; scnt++; } } if (!(dryrun & FS_DRYRUN_QUADS) && scnt > 0 && fsp_quad_import(link, seg, FS_BIND_BY_SUBJECT, scnt, quad_buf_s)) { fs_error(LOG_ERR, "quad import failed"); return 1; } } if (verbosity) printf("Pass 2, processed %d triples\r", total); fflush(stdout); } while (ret == sizeof(quad_buf)); if (verbosity) { gettimeofday(&now, 0); double diff = (now.tv_sec - then_last.tv_sec) + (now.tv_usec - then_last.tv_usec) * 0.000001; printf("Pass 2, processed %d triples", total); if (total > 0) { printf(", %d triples/s\n", (int)((double)total/diff)); } else { printf("\n"); } } ftruncate(tfd, 0); lseek(tfd, 0, SEEK_SET); return total; }