int DictionaryDatabase::lookupIDFromName(OperationContext &context, const Name &name, NameID &id, bool define) { int err = 0; if (name == Name::dbxml_colon_name) { id = nidName_; } else if (name == Name::dbxml_colon_root) { id = nidRoot_; } if (id == 0) { MutexLock ml(mutex_); u_int32_t flags = (getTxn(context) && !define) ? DB_READ_COMMITTED : 0; name.setDbtFromThis_SecondaryKey(context.key()); if (stringCacheLookup(context, context.key(), id)) return 0; err = secondary_->get(getTxn(context), &context.key(), &context.data(), flags); if (err == 0) { id.setThisFromDbt(context.data()); stringCache_.insert(&context.key(), id.raw()); } else if (err == DB_NOTFOUND && define) { err = defineName(context, name, id); // define from name:uri } else { id.reset(); } } return err; }
// mutex is locked if present and necessary int DictionaryDatabase::defineName(OperationContext &context, const Name &name, NameID &id) { // Primary { id -> name\0uri\0 } // Secondary { name:uri -> id } id.reset(); name.setDbtFromThis_PrimaryValue(context.data()); int err = primary_->appendPrimary(context, id, context.data(), /*no flags*/0); if (err == 0) { /*Cache after insert. This prevents the cache from returning bad answers * on a transaction abort, and speeds up access to newly inserted element * and attribute names that are needed for indexing after an insert. */ cache_.insert(id.raw(), context.data()); id.setDbtFromThis(context.key()); name.setDbtFromThis_SecondaryKey(context.data()); Transaction *txn = getTxn(context); err = secondary_->put(txn, &context.data(), &context.key(), /*no flags*/0); if (err == 0) { /* Add to the transaction's string cache, that way if an abort occurs * the values can be removed from the cache. */ if (txn) { DictionaryStringCache *dsc = txn->getStringCache(this, true); dsc->insert(&context.data(), id.raw()); } if(Log::isLogEnabled(Log::C_DICTIONARY, Log::L_INFO)) { ostringstream oss; oss << "Define new name " << id << " -> " << name; Log::log(environment_, Log::C_DICTIONARY, Log::L_INFO, name_.c_str(), oss.str().c_str()); } } } return err; }