int StructuralStatsDatabase::subtractStats(OperationContext &context, const NameID &id1, const NameID &id2,
	const StructuralStats &stats)
{
	DBXML_ASSERT(id1 != 0 || id2 == 0);

	Cursor myCursor(const_cast<DbWrapper&>(db_), getTxn(context), CURSOR_WRITE, 0);
	if(myCursor.error() != 0) return myCursor.error();

	marshalKey(id1, id2, context.key());
	int err = myCursor.get(context.key(), context.data(), DB_SET);
	if(err != DB_NOTFOUND && err != 0) return err;

	StructuralStats current;

	if(err == DB_NOTFOUND) {
		current.subtract(stats);

		current.marshal(context.data(), id2 == 0);
		err = myCursor.put(context.key(), context.data(), DB_KEYLAST);
	} else {
		current.unmarshal(context.data());
		current.subtract(stats);

		current.marshal(context.data(), id2 == 0);
		err = myCursor.put(context.key(), context.data(), DB_CURRENT);
	}

	return err;
}
void DictionaryDatabase::display(OperationContext &context, ostream &out) const
{
	{
	Cursor myCursor(const_cast<PrimaryDatabase&>(*primary_.get()), getTxn(context), CURSOR_READ, 0);
	if(myCursor.error() != 0) throw XmlException(myCursor.error());

	int err = 0;
	NameID id;
	while((err = myCursor.get(context.key(), context.data(), DB_NEXT)) == 0) {
		id.setThisFromDbtAsId(context.key());
		Buffer val(context.data().data, context.data().size, true);
		out << id << " -> " << val.asString(true) << endl;
	}
	}
	{
	Cursor myCursor(const_cast<SecondaryDatabase&>(*secondary_.get()), getTxn(context), CURSOR_READ, 0);
	if(myCursor.error() != 0) throw XmlException(myCursor.error());

	int err = 0;
	NameID id;
	while((err = myCursor.get(context.key(), context.data(), DB_NEXT)) == 0) {
		Buffer val(context.key().data, context.key().size, true);
		id.setThisFromDbt(context.data());
		out << val.asString(true) << " -> " << id << endl;
	}
	}
}
int DocumentDatabase::getMetaData(OperationContext &context,
	DictionaryDatabase *dictionary, const Name &name,
	const DocID &did, XmlValue::Type &type, DbXmlDbt *metadata,
	u_int32_t flags) const
{
	NameID nid;
	int err = dictionary->lookupIDFromName(context, name,
					       nid, /*define=*/false);
	if(err == 0) {
		Cursor cursor(const_cast<SecondaryDatabase&>(secondary_),
			context.txn(), CURSOR_READ, "DocumentMetaData", flags);
		u_int32_t origFlags = DB_CURSOR_GET_MASK(const_cast<SecondaryDatabase&>(secondary_),flags);
		MetaDatum::setKeyDbt(did, nid, XmlValue::NONE, context.key());
		DbtIn none;
		none.set_flags(DB_DBT_PARTIAL); // Don't pull back the data.
		err = cursor.get(context.key(), none,
				 (flags | DB_SET_RANGE) & ~DB_RMW);
		if (err == 0) {
			DocID db_did;
			NameID db_nid;
			MetaDatum::decodeKeyDbt(context.key(), db_did,
						db_nid, type);
			if(db_did == did && db_nid == nid) {
				err = cursor.get(context.key(), *metadata,
						 origFlags|DB_CURRENT);
			} else {
				return DB_NOTFOUND;
			}
		}
	}

	return err;
}
int DocumentDatabase::addMetaData(OperationContext &oc,
				  DictionaryDatabase *dictionary,
				  Document &document)
{
	int err = 0;
	MetaData::const_iterator end = document.metaDataEnd();
	MetaData::const_iterator i;
	for (i = document.metaDataBegin(); err == 0 && i != end; ++i) {
		NameID nid;
		err = dictionary->lookupIDFromName(oc,
						   (*i)->getName(),
						   nid, /*define=*/true);
		if(err == 0) {
			DbtIn value;
			MetaDatum::setKeyDbt(document.getID(),
					     nid, (*i)->getType(),
					     oc.key());
			(*i)->setValueDbtFromThis(value);
			// could throw on error
			err = secondary_.put(oc.txn(), &oc.key(),
					     &value, 0);
		}
	}
	if(err == 0)
		for(i = document.metaDataBegin(); i != end; ++i)
			(*i)->setModified(false);
	return err;
}
Exemple #5
0
void
NsUpgradeReader::initDocInfo()
{
    // read doc node
    // read namespace info
    OperationContext oc;
    oc.set(NULL);
    const char metadataId[] =
    { NS_PROTOCOL_VERSION_COMPAT, NS_METADATA_ID, 0 };
    DbtOut data((void *)metadataId, strlen(metadataId) + 1);
    // reproduce old NsDocumentDatabase::getNodeRecord(), but
    // cannot deadlock -- no transaction
    DBXML_ASSERT(!oc.txn());
    id_.setDbtFromThis(oc.key());
    int ret = db_.get(oc.txn(), &oc.key(), &data, DB_GET_BOTH);
    uint32_t flags = 0;
    if (ret == 0) {
        const xmlbyte_t *ptr = (const xmlbyte_t *) data.data;
        ptr += 3;  // past version and id
        size_t len;
        ptr += NsFormat::unmarshalInt(ptr, &flags);
        if (flags & NSDOC_HASDECL) {
            ptr += NsFormat::unmarshalInt(ptr, &xmlDecl_);
            DBXML_ASSERT(xmlDecl_ == 0 || xmlDecl_ == 1);
        }
        if (flags & NSDOC_HASENCODE) {
            DBXML_ASSERT(!encStr_);
            encStr_ = NsUtil::nsStringDup(ptr, &len);
            ptr += len;
        }
        if (flags & NSDOC_HASSNIFF) {
            sniffStr_ = NsUtil::nsStringDup(ptr, &len);
            ptr += len;
        }
        if (flags & NSDOC_STANDYES)
            standStr_ = _standYes;
        if (flags & NSDOC_STANDNO)
            standStr_ = _standNo;
    }
    if (flags & NSDOC_NAMESPACE) {
        nsInfo_ = new NsNamespaceInfo();
        if (!nsInfo_)
            NsUtil::nsThrowException(XmlException::NO_MEMORY_ERROR,
                                     "new failed to allocate memory",
                                     __FILE__, __LINE__);
        nsInfo_->initialize();
        const char namespaceId[] =
        { NS_PROTOCOL_VERSION_COMPAT, NS_NAMESPACE_ID, 0 };

        DbtOut ndata((void *)namespaceId,
                     strlen(namespaceId) + 1);

        id_.setDbtFromThis(oc.key());
        ret = db_.get(oc.txn(), &oc.key(), &ndata, DB_GET_BOTH);
        if (ret == 0) {
            nsInfo_->load((const char*)
                          ((const char *)ndata.data)+3);
        }
    }
}
int StructuralStatsDatabase::addStats(OperationContext &context, const StructuralStatsDatabase &sdb)
{
	Cursor myCursor(db_, getTxn(context), CURSOR_WRITE, 0);
	if(myCursor.error() != 0) return myCursor.error();

	Cursor sdbCursor(const_cast<DbWrapper&>(sdb.db_), sdb.getTxn(context), CURSOR_READ, 0);
	if(sdbCursor.error() != 0) return sdbCursor.error();

	int err = 0;
	StructuralStats stats;
	StructuralStats current;
	bool nodeStats;

	while((err = sdbCursor.get(context.key(), context.data(), DB_NEXT)) == 0) {

		stats.reset();
		nodeStats = stats.unmarshal(context.data());

		err = myCursor.get(context.key(), context.data(), DB_SET);
		if(err == DB_NOTFOUND) {
			stats.marshal(context.data(), nodeStats);
			err = myCursor.put(context.key(), context.data(), DB_KEYLAST);
		} else if(err == 0) {
			current.unmarshal(context.data());
			current.add(stats);
			current.marshal(context.data(), nodeStats);
			err = myCursor.put(context.key(), context.data(), DB_CURRENT);
		} else break;
	}

	if(err != DB_NOTFOUND) return err;

	return 0;
}
int StructuralStatsDatabase::addStats(OperationContext &context, const StructuralStatsWriteCache &cache)
{
	Cursor myCursor(db_, getTxn(context), CURSOR_WRITE, 0);
	if(myCursor.error() != 0) return myCursor.error();

	int err = 0;
	StructuralStats current;

	StructuralStatsWriteCache::Map::const_iterator it = cache.cache_.begin();
	for(; err == 0 && it != cache.cache_.end(); ++it) {

		StructuralStatsWriteCache::InnerMap::const_iterator it2 = it->second.begin();
		for(; it2 != it->second.end(); ++it2) {

			marshalKey(it->first, it2->first, context.key());

			err = myCursor.get(context.key(), context.data(), DB_SET);
			if(err == DB_NOTFOUND) {
				it2->second.marshal(context.data(), it2->first == 0);
				err = myCursor.put(context.key(), context.data(), DB_KEYLAST);
			} else if(err == 0) {
				current.unmarshal(context.data());
				current.add(it2->second);
				current.marshal(context.data(), it2->first == 0);
				err = myCursor.put(context.key(), context.data(), DB_CURRENT);
			} else break;
		}
	}

	if(err != DB_NOTFOUND) return err;

	return 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;
}
void StructuralStatsDatabase::display(OperationContext &context, ostream &out, const DictionaryDatabase *ddb) const
{
	Cursor myCursor(const_cast<DbWrapper&>(db_), getTxn(context), CURSOR_WRITE, 0);
	if(myCursor.error() != 0) throw XmlException(myCursor.error());

	NameID id1;
	NameID id2;
	StructuralStats stats;

	int err = 0;
	while((err = myCursor.get(context.key(), context.data(), DB_NEXT)) == 0) {
		id1.reset();
		id2.reset();
		unmarshalKey(context.key(), id1, id2);
		stats.reset();
		stats.unmarshal(context.data());

		if(ddb) out << ddb->lookupName(context, id1);
		else out << id1;

		if(id2 != 0) {
			if(ddb) out << " -> " << ddb->lookupName(context, id2);
			else out << " -> " << id2;
		}

		out << ": ";

		stats.display(out);

		out << endl;
	}
}
Exemple #10
0
int PrimaryDatabase::appendPrimary(OperationContext &context, NameID &id,
				   const DbXmlDbt &data, u_int32_t flags)
{
	int err = put(context.txn(), &context.key(), &(const_cast<DbXmlDbt&>(data)),
		      flags | DB_APPEND);
	if (err == 0)
		id.setThisFromDbtAsId(context.key());
	return err;
}
int DocumentDatabase::getAllMetaData(OperationContext &context,
				     DictionaryDatabase *dictionary,
				     Document *document,
				     u_int32_t flags) const
{
	int err = 0;
	u_int32_t orig_flags = flags;
	const DocID &did = document->getID();

	//
	// Read each of the meta-data items from the document secondary
	// database.  Content is no longer considered metadata
	//
	Cursor cursor(const_cast<SecondaryDatabase&>(secondary_),
		context.txn(), CURSOR_READ, "DocumentMetaData", flags);
	orig_flags = flags = DB_CURSOR_GET_MASK(const_cast<SecondaryDatabase&>(secondary_),flags);
	flags |= DB_SET_RANGE;
	bool done = false;
	while (!done) {
		did.setDbtFromThis(context.key());
		DbtIn none;
		none.set_flags(DB_DBT_PARTIAL); // Don't pull back the data.
		// if DB_RMW set, don't get locks on this get, wait for a match
		err = cursor.get(context.key(), none, flags & (~DB_RMW));
		if (err == 0) {
			DocID db_did;
			NameID db_nid;
			XmlValue::Type type;
			MetaDatum::decodeKeyDbt(context.key(), db_did,
						db_nid, type);
			if (did == db_did) {
				Name name;
				err = dictionary->lookupNameFromID(context, db_nid, name);
				if(err == 0 && !document->containsMetaData(name)) {
					DbtOut *data = new DbtOut();
					err = cursor.get(context.key(), *data,
							 DB_CURRENT);
					if(err == 0) document->setMetaData(
						name, type, &data,
						/*modified*/false);
					delete data; // If not consumed by setThis..
				}
				flags = orig_flags | DB_NEXT;
			} else {
				err = 0;
				done = true;
			}
		} else if (err == DB_NOTFOUND) {
			err = 0;
			done = true;
		} else {
			done = true;
		}
	}
	return err;
}
int StructuralStatsDatabase::getStats(OperationContext &context, StructuralStats &stats) const
{
	Cursor myCursor(const_cast<DbWrapper&>(db_), getTxn(context), CURSOR_READ, 0);
	if(myCursor.error() != 0) return myCursor.error();

	StructuralStats current;

	// Loop over every node and every node's descendant information
	int err;
	while((err = myCursor.get(context.key(), context.data(), DB_NEXT)) == 0) {
		current.reset();
		current.unmarshal(context.data());
		stats.add(current);
	}

	if(err != DB_NOTFOUND && err != 0) return err;

	if(stats.sumSize_ == 0 && stats.numberOfNodes_ != 0) {
		// Fill in an estimate for the missing size values that you get with DLS
		stats.sumSize_ = NODE_SIZE * stats.numberOfNodes_;
		stats.sumChildSize_ = NODE_SIZE * stats.sumNumberOfChildren_;
		stats.sumDescendantSize_ = NODE_SIZE * stats.sumNumberOfDescendants_;
	}

	return 0;
}
// puts result in dbt, which may be context.data(), or may be user-provided
int DictionaryDatabase::lookupFromID(
	OperationContext &context, DbtOut &dbt,
	const NameID &id) const
{
	int err = 0;
	if (cache_.lookup(context, id, dbt, false))
		return 0;
	u_int32_t flags = (getTxn(context)) ? DB_READ_COMMITTED : 0;
	// primary key is the integer value of the id (database is
	// recno)
	id.setDbtFromThisAsId(context.key());
	MutexLock ml(mutex_);
	err = primary_->get(getTxn(context), &context.key(),
			    &dbt, flags);
	if (err == 0)
		cache_.insert(id.raw(), dbt);
	return err;
}
// 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;
}
// if toRemove is non-null, it specifies a list of Name IDs
// to remove; otherwise remove all metadata for the target document
int DocumentDatabase::removeMetaData(OperationContext &oc,
				     const DocID &id,
				     std::vector<NameID> *toRemove)
{
	Cursor cursor(const_cast<SecondaryDatabase&>(secondary_), oc.txn(),
		      CURSOR_WRITE, "DocumentMetaData_remove");

	DbtIn none;
	none.set_flags(DB_DBT_PARTIAL); // Don't pull back the data.

	id.setDbtFromThis(oc.key());

	DocID db_id;
	int err = cursor.get(oc.key(), none, DB_SET_RANGE);
	try {
		while(err == 0) {
			if (toRemove) {
				NameID nm_id;
				XmlValue::Type type;
				MetaDatum::decodeKeyDbt(oc.key(), db_id, nm_id, type);
				if ((id == db_id) && idInList(*toRemove, nm_id))
					cursor.del(0);
			} else {
				db_id.setThisFromDbt(oc.key());
				if (id == db_id)
					cursor.del(0);
			}
			if (id != db_id) // done with document?
				break;
			err = cursor.get(oc.key(), none, DB_NEXT);
		}
	} catch (...) {
		cursor.close();
		throw;
	}
	if(err == DB_NOTFOUND) {
		err = 0;
	}
	cursor.close();
	return err;
}
int DocumentDatabase::updateMetaData(OperationContext &oc,
				     DictionaryDatabase *dictionary,
				     Document &document)
{
	int err = 0;
	MetaData::const_iterator end = document.metaDataEnd();
	MetaData::const_iterator i;
	std::vector<NameID> toRemove;
	for(i = document.metaDataBegin(); err == 0 && i != end; ++i) {
		if((*i)->isModified()) {
			NameID nid;
			err = dictionary->lookupIDFromName(oc,
							   (*i)->getName(),
							   nid, /*define=*/true);
			if(err == 0) {
				if ((*i)->isRemoved())
					toRemove.push_back(nid);
				else {
					DbtIn value;
					MetaDatum::setKeyDbt(document.getID(),
							     nid,
							     (*i)->getType(),
							     oc.key());
					(*i)->setValueDbtFromThis(value);
					// could throw on error
					err = secondary_.put(oc.txn(),
							     &oc.key(),
							     &value, 0);
				}
			}
		}
	}
	if (toRemove.size() > 0) {
		err = removeMetaData(oc, document.getID(),
				     &toRemove);
	}
	if(err == 0)
		for(i = document.metaDataBegin(); i != end; ++i)
			(*i)->setModified(false);
	return err;
}
int StructuralStatsDatabase::getStats(OperationContext &context, const NameID &id1, StructuralStats &stats) const
{
	if(id1 == 0) return getStats(context, stats);

	Cursor myCursor(const_cast<DbWrapper&>(db_), getTxn(context), CURSOR_READ, 0);
	if(myCursor.error() != 0) return myCursor.error();

	NameID cid1, cid2;
	StructuralStats current;

	// Find the node information
	marshalKey(id1, 0, context.key());
	int err = myCursor.get(context.key(), context.data(), DB_SET);
	if(err == DB_NOTFOUND) return getStats(context, stats);

	// Loop over the node information and all it's descendant information
	while(err == 0) {
		cid1.reset();
		unmarshalKey(context.key(), cid1, cid2);
		if(id1 != cid1) break;

		current.reset();
		current.unmarshal(context.data());
		stats.add(current);

		err = myCursor.get(context.key(), context.data(), DB_NEXT);
	}

	if(err != DB_NOTFOUND && err != 0) return err;

	if(stats.sumSize_ == 0 && stats.numberOfNodes_ != 0) {
		// Fill in an estimate for the missing size values that you get with DLS
		stats.sumSize_ = NODE_SIZE * stats.numberOfNodes_;
		stats.sumChildSize_ = NODE_SIZE * stats.sumNumberOfChildren_;
		stats.sumDescendantSize_ = NODE_SIZE * stats.sumNumberOfDescendants_;
	}

	return 0;
}
int StructuralStatsDatabase::getStats(OperationContext &context, const NameID &id1, const NameID &id2,
	StructuralStats &stats) const
{
	if(id1 == 0) return getStats(context, stats);
	if(id2 == 0) return getStats(context, id1, stats);

	Cursor myCursor(const_cast<DbWrapper&>(db_), getTxn(context), CURSOR_READ, 0);
	if(myCursor.error() != 0) return myCursor.error();

	// Lookup the descendant information
	marshalKey(id1, id2, context.key());
	int err = myCursor.get(context.key(), context.data(), DB_SET);
	if(err == DB_NOTFOUND) return getStats(context, id1, stats);
	if(err != 0) return err;

	stats.unmarshal(context.data());

	// Lookup the node information
	marshalKey(id1, 0, context.key());
	err = myCursor.get(context.key(), context.data(), DB_SET);
	DBXML_ASSERT(err != DB_NOTFOUND);
	if(err != 0) return err;

	stats.unmarshal(context.data());

	if(stats.sumSize_ == 0 && stats.numberOfNodes_ != 0) {
		// Fill in an estimate for the missing size values that you get with DLS
		StructuralStats allStats;
		err = getStats(context, id1, allStats);
		if(err != 0) return err;

		stats.sumSize_ = allStats.sumSize_;
		stats.sumChildSize_ = allStats.sumChildSize_;
		stats.sumDescendantSize_ = allStats.sumDescendantSize_;
	}

	return 0;
}
int DocumentDatabase::getContent(OperationContext &context,
				 Document *document, u_int32_t flags) const
{
	DbtOut *data = new DbtOut();
	int err = 0;
	try {
		document->getID().setDbtFromThis(context.key());
		// NOTE: db_.get() does not throw on DB_NOTFOUND, but
		// try/catch anyway...
		err = getContent(context.txn(), context.key(), *data, flags);
	} catch (...) {
		delete data;
		throw; // re-throw
	}
 
	if(err == 0 && (data->size != 0)) 
		document->setContentAsDbt(&data); // Note: consumes data
	else 
		delete data;
	if (err == DB_NOTFOUND)
		err = 0; // allow no-content documents
	return err;
}
Exemple #20
0
int PrimaryDatabase::getPrimary(OperationContext &context, const NameID &id,
				DbtOut *data, u_int32_t flags) const
{
	id.setDbtFromThis(context.key());
	return get(context.txn(), &context.key(), data, flags);
}
Exemple #21
0
double IndexDatabase::percentage(OperationContext &context, Operation operation, Operation gto, Operation lto, const Key &key1, const Key &key2) const
{
	DbtOut &dbt1 = context.key();
	DbtOut &dbt2 = context.data();

	DB_KEY_RANGE krMin;
	getMinKeyDbt(key1, dbt1);
	key_range(context.txn(), &dbt1, &krMin, 0);

	DB_KEY_RANGE krMax;
	getMaxKeyDbt(key1, dbt1);
	key_range(context.txn(), &dbt1, &krMax, 0);

	// range is the % of the database keys that the keys for this index occupy.
	double range = krMax.less - krMin.less;
	double extent = 0.0;

	if (range > 0.0) {
		// extent is the % of the database keys that the keys for this index match this operation.
		DB_KEY_RANGE kr1;
		DB_KEY_RANGE kr2;

		switch(operation) {
		case DbWrapper::PREFIX: {
			key1.setDbtFromThis(dbt1);
			key_range(context.txn(), &dbt1, &kr1, 0);
			getNextKeyDbt(key1, dbt2);
			key_range(context.txn(), &dbt2, &kr2, 0);
			extent = kr2.less - kr1.less;
			break;
		}
		case DbWrapper::LTX:
		case DbWrapper::LTE: {
			key1.setDbtFromThis(dbt2);
			key_range(context.txn(), &dbt2, &kr2, 0);
			extent = kr2.less - krMin.less + (operation == DbWrapper::LTE ? kr2.equal : 0);
			break;
		}
		case DbWrapper::GTX:
		case DbWrapper::GTE: {
			key1.setDbtFromThis(dbt1);
			key_range(context.txn(), &dbt1, &kr1, 0);
			extent = krMax.less + krMax.equal - kr1.less + (operation == DbWrapper::GTX ? kr1.equal : 0);
			break;
		}
		case DbWrapper::RANGE: {
			key1.setDbtFromThis(dbt1);
			key_range(context.txn(), &dbt1, &kr1, 0);
			key2.setDbtFromThis(dbt2);
			key_range(context.txn(), &dbt2, &kr2, 0);
			extent = kr2.less - kr1.less + (lto == DbWrapper::LTE ? kr2.equal : 0) + (gto == DbWrapper::GTX ? kr1.equal : 0);
			break;
		}
		case DbWrapper::EQUALITY: {
			key1.setDbtFromThis(dbt2);
			key_range(context.txn(), &dbt2, &kr2, 0);
			extent = kr2.equal;
			break;
		}
		case DbWrapper::ALL: {
			extent = range;
			break;
		}
		default: {
			break;
		}
		}
	}

	// Return a small percentage in the case of a zero range or extent -
	// it's unlikely that zero is really the right answer
	if(range == 0 || extent == 0) return 0.001;

	// extent/range is the % of keys within this index that match this operation.
	return extent / range;
}
Exemple #22
0
int PrimaryDatabase::deletePrimary(OperationContext &context,
				   const NameID &id, u_int32_t flags)
{
	id.setDbtFromThis(context.key());
	return del(context.txn(), &context.key(), flags);
}
Exemple #23
0
int PrimaryDatabase::putPrimary(OperationContext &context, const NameID &id,
				const DbXmlDbt &data, u_int32_t flags)
{
	id.setDbtFromThis(context.key());
	return put(context.txn(), &context.key(), &(const_cast<DbXmlDbt&>(data)), flags);
}