Esempio n. 1
0
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;
}
Esempio n. 2
0
int DictionaryDatabase::lookupIDFromStringNameInternal(
	OperationContext &context,
	DbXmlDbt &dbt,
	NameID &id,
	bool define) const
{
	if (!dbt.size) {
		id.reset();
		return 0;
	}
	u_int32_t flags = (getTxn(context) && !define) ? DB_READ_COMMITTED : 0;
	if (stringCacheLookup(context, dbt, id))
			return 0;
	int err = secondary_->get(getTxn(context), &dbt,
				  &context.data(), flags);
	if (err == 0) {
		id.setThisFromDbt(context.data());
		stringCache_.insert(&dbt, id.raw());
	} else
		id.reset();
	return err;
}
Esempio n. 3
0
// mutex is locked if present and necessary
int DictionaryDatabase::defineStringName(OperationContext &context,
					 const char *name, size_t namelen,
					 NameID &id)
{
	// Primary { id -> name\0 }
	// Secondary { name -> id }
	int err = 0;
	id.reset();
	DbtIn primaryData((void*)name, namelen + 1); // add null
	DbtIn secondaryKey((void*)name, namelen); // don't add null
	err = primary_->appendPrimary(context, id,
				      primaryData, /*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(), primaryData);
		id.setDbtFromThis(context.key());
		Transaction *txn = getTxn(context);
		err = secondary_->put(txn, &secondaryKey,
				      &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(&secondaryKey, 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;
}