#ifndef _H_APPLEDL_DBINDEX
#define _H_APPLEDL_DBINDEX
#include "MetaRecord.h"
namespace Security
{
class Table;
class DbConstIndex;
class DbIndex;
typedef constVector<Atom> DbOffsetVector;
typedef DbOffsetVector::const_iterator DbIndexIterator;
class DbQueryKey
{
friend class DbConstIndex;
friend class DbKeyComparator;
public:
DbQueryKey(const DbConstIndex &index);
enum { kQueryValue = 0 };
private:
WriteSection mKeyData;
uint32 mNumKeyValues;
const DbConstIndex &mIndex;
const ReadSection &mTableSection;
CSSM_DB_OPERATOR mOp;
};
class DbKeyComparator
{
public:
DbKeyComparator(const DbQueryKey &key) : mKey(key) {}
int operator () (uint32 keyOffset1, uint32 keyOffset2) const;
private:
const DbQueryKey &mKey;
};
class DbIndexKey {
public:
DbIndexKey(const ReadSection &key, const Range &keyRange, const DbIndex &index)
: mKeySection(key), mKeyRange(keyRange), mIndex(index) {}
bool operator < (const DbIndexKey &other) const;
uint32 keySize() const { return mKeyRange.mSize; }
const uint8 *keyData() const { return mKeySection.range(mKeyRange); }
private:
const ReadSection &mKeySection;
Range mKeyRange;
const DbIndex &mIndex;
};
class DbIndex
{
friend class DbIndexKey;
public:
uint32 indexId() const { return mIndexId; }
void appendAttribute(uint32 attributeId);
protected:
DbIndex(const MetaRecord &metaRecord, uint32 indexId, bool isUniqueIndex);
const MetaRecord &mMetaRecord;
typedef vector<const MetaAttribute *> AttributeVector;
AttributeVector mAttributes;
uint32 mIndexId;
bool mIsUniqueIndex;
};
class DbConstIndex : public DbIndex
{
friend class DbMutableIndex;
friend class DbQueryKey;
friend class DbKeyComparator;
public:
DbConstIndex(const Table &table, uint32 indexId, bool isUniqueIndex);
DbConstIndex(const Table &table, const ReadSection &indexSection);
const Table &table() const { return mTable; }
bool matchesQuery(const CSSM_QUERY &query, DbQueryKey *&queryKey) const;
void performQuery(const DbQueryKey &queryKey,
DbIndexIterator &begin, DbIndexIterator &end) const;
ReadSection getRecordSection(DbIndexIterator iter) const;
private:
DbOffsetVector mKeyOffsetVector;
DbOffsetVector mRecordNumberVector;
const Table &mTable;
};
class DbMutableIndex : public DbIndex
{
public:
DbMutableIndex(const DbConstIndex &index);
DbMutableIndex(const MetaRecord &metaRecord, uint32 indexId, bool isUniqueIndex);
~DbMutableIndex();
void insertRecord(uint32 recordNumber, const ReadSection &packedRecord);
void removeRecord(uint32 recordNumber);
uint32 writeIndex(WriteSection &ws, uint32 offset);
private:
void insertRecordSingle(uint32 recordOffset, const ReadSection &packedRecord);
void insertRecordMulti(uint32 recordOffset, const ReadSection &packedRecord,
uint32 attributeIndex, WriteSection &keyData, uint32 keySize);
WriteSection mIndexData;
uint32 mIndexDataSize;
typedef multimap<DbIndexKey, uint32> IndexMap;
IndexMap mMap;
};
}
#endif // _H_APPLEDL_DBINDEX