int DocumentDatabase::getContent(Transaction *txn, DbtOut &key, DbtOut &data, u_int32_t flags) const { int err = 0; // NOTE: db_.get() does not throw on DB_NOTFOUND, but // try/catch anyway... err = content_.get(txn, &key, &data, flags); if(err == 0 && (data.size != 0)) { if (compressor_) { XmlData source(data.data, data.size); XmlData dest; XmlTransaction xtxn(txn); if(!compressor_->decompress(xtxn, source, dest)){ throw XmlException(XmlException::INTERNAL_ERROR, "Error while tring to decompress your XML document."); } /* Replace the buffer in data with the one in dest. Because of this, DbtOut and Buffer must both use malloc and free*/ if (data.data != dest.get_data()) data.setNoCopy((*dest.getBuffer())->donateBuffer(), dest.get_size()); } } return err; }
// Basic lookup, returning a pointer that will be valid // until this object is deleted. Lookup does not require locking // because entries are never removed, and they are only added // at the beginning of the hash chain with a simple pointer update. // A race condition could theoretically happen if a compiler reorders // some of the code in insert bool DictionaryCache::lookup(OperationContext &context, const NameID &id, DbtOut &dbt, bool useDictionary) { while (true) { // will only ever loop once nameId_t nid = id.raw(); int bucket = hash(nid); DictionaryCacheEntry *current = htable_[bucket]; while (current && (current->getNid() != nid)) current = current->getNext(); if (current) { dbt.set(current->getValue(), current->getLen()); return true; } if (!useDictionary) return false; // read through the dictionary int ret = ddb_->lookupStringNameFromID(context, id, dbt); if (ret == 0) { DBXML_ASSERT(dbt.size); insert(nid, dbt); } else { // this should never happen, but if it does, // be silent (for now) return false; } } }
int DictionaryDatabase::lookupStringNameFromID( OperationContext &context, const NameID &id, DbtOut &dbt) const { int err = 0; nameId_t raw = id.raw() - 1; // id space is 1-based, not 0 if ((raw < DICTIONARY_RESERVE_SIZE) && usePreloads_) { const char *name = preloadNames[raw]; dbt.set((const void *)name, ::strlen(name) + 1); } else err = lookupFromID(context, dbt, id); return err; }
static void marshalKey(const NameID &id1, const NameID &id2, DbtOut &dbt) { DBXML_ASSERT(id1 != 0 || id2 == 0); int size = 1; if(id1 != 0) size += id1.marshalSize(); if(id2 != 0) size += id2.marshalSize(); dbt.set(0, size); xmlbyte_t *ptr = (xmlbyte_t*)dbt.data; *ptr++ = KEY_PREFIX_BYTE; if(id1 != 0) ptr += id1.marshal(ptr); if(id2 != 0) ptr += id2.marshal(ptr); }
void StructuralStats::marshal(DbtOut &dbt, bool nodeStats) const { int count = marshal(0, /*count*/true, nodeStats); dbt.set(0, count); marshal((xmlbyte_t*)dbt.data, /*count*/false, nodeStats); }
void DocID::setDbtFromThis(DbtOut &dbt) const { char buf[9]; u_int32_t len = marshal(buf); dbt.set(buf, len); // copies the data }
void KeyStatistics::setDbtFromThis(DbtOut &dbt) const { int count = marshal(0, /*count*/true); dbt.set(0, count); marshal((xmlbyte_t*)dbt.data, /*count*/false); }