static fs_rid insert_bnode(xmlctxt *ctxt) { fs_rid bnode = atoll(ctxt->resource); /* TODO catch other people's non-numeric bNode IDs */ while (ctxt->bnodemax < bnode) { fs_rid bnodenext; fsp_bnode_alloc(ctxt->link, 1000000, &bnodenext, &(ctxt->bnodemax)); printf("(allocated bNode %lld to %lld)\n", bnodenext, ctxt->bnodemax); } return bnode | 0x8000000000000000LL; }
static fs_rid fs_bnode_id(fsp_link *link, const char *bnode) { GHashTable *bnids = fs_hash_bnids(); fs_rid bn = (fs_rid) (unsigned long) g_hash_table_lookup(bnids, bnode); if (!bn) { if (bnodenext > bnodemax) { fsp_bnode_alloc(link, 1000000, &bnodenext, &bnodemax); if (sizeof(gpointer) < sizeof(fs_rid) && bnodemax >= 0x100000000LL) { fs_error(LOG_CRIT, "bNode RID %lld exceeds safe size on 32-bit arch", bnodemax); abort(); } } bn = bnodenext++; g_hash_table_insert(bnids, g_strdup(bnode), (gpointer) (unsigned long) bn); } union { fs_rid rid; char bytes[8]; } node; /* bNode IDs up to 2 ** 56 or only */ node.rid = bn; node.bytes[7] = (node.bytes[0] & 0x7c) >> 2; node.bytes[1] ^= node.bytes[6]; node.bytes[6] ^= node.bytes[1]; node.bytes[1] ^= node.bytes[6]; node.bytes[2] ^= node.bytes[5]; node.bytes[5] ^= node.bytes[2]; node.bytes[2] ^= node.bytes[5]; node.bytes[3] ^= node.bytes[4]; node.bytes[4] ^= node.bytes[3]; node.bytes[3] ^= node.bytes[4]; return node.rid | 0x8000000000000000LL; }