|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1994
//
// File: keylist.hxx
//
// Contents:
//
// History: 17-Feb-1994 KyleP Created
//
//--------------------------------------------------------------------------
#pragma once
#include "partn.hxx"
#include "sort.hxx"
#include "pindex.hxx"
#include "pcomp.hxx"
class CKeyComp; class CKeyDeComp; class CRKeyHash;
#ifdef KEYLIST_ENABLED
//+---------------------------------------------------------------------------
//
// Class: CKeyList (wl)
//
// Purpose: Convert between key id and key. Enumeration of keys later
//
// History: 29-Oct-93 w-PatG Created.
// 17-Feb-94 KyleP Initial version
//
// Notes: The keylist is composed of three main parts: a directory,
// a [content] index, and a hash table. The index is a
// minimal version of the standard content index. No wid or
// occurrence information is stored and property ids are treated
// as key ids. maxWid is treated as maxKeyId. New key ids
// are allocated sequentially.
//
//----------------------------------------------------------------------------
const LONGLONG eSigKeyList = 0x205453494c59454bi64; // "KEYLIST"
class CKeyList : public CIndex { DECLARE_UNWIND public:
CKeyList();
CKeyList( PStorage & storage, WORKID objectId, INDEXID iid, KEYID kidMax );
//
// From CIndex
//
virtual ~CKeyList();
virtual unsigned Size () const;
virtual void Remove();
virtual CKeyCursor * QueryCursor();
//
// From CQueriable
//
virtual COccCursor * QueryCursor( const CKey * pkey, BOOL isRange, ULONG & cMaxNodes );
virtual COccCursor * QueryRangeCursor( const CKey * pkeyBegin, const CKey * pkeyEnd, ULONG & cMaxNodes );
virtual COccCursor * QuerySynCursor( CKeyArray & keyArr, BOOL isRange, ULONG & cMaxNodes );
//
// Bookeeping functions
//
WORKID ObjectId() const { return _pPhysIndex->ObjectId(); }
INDEXID GetNextIid ();
ULONG MaxKeyIdInUse() const { return _widMax; }
void FillRecord( CIndexRecord& record ) const;
//
// Translation
//
KEYID KeyToId( const CKey * pkey );
BOOL IdToKey( KEYID ulKid, CKey & rkey );
protected:
inline CKeyList ( PStorage & storage, WORKID objectid, INDEXID id, WORKID widMax, int dummy );
void Close();
const LONGLONG _sigKeyList;
PStorage * const _pstorage;
CPhysIndex * _pPhysIndex; CPhysHash * _pPhysHash; PDirectory * _pDir;
SStorageObject _obj; };
//+---------------------------------------------------------------------------
//
// Class: CWKeyList (wl)
//
// Purpose: Writeable version of keylist
//
// History: 17-Feb-94 KyleP Initial version
//
//----------------------------------------------------------------------------
const LONGLONG eSigWKeyList = 0x5453494c59454b57i64; // "WKEYLIST"
class CWKeyList : public CKeyList { DECLARE_UNWIND
public:
CWKeyList( PStorage & storage, WORKID objectid, INDEXID iid, unsigned size, CKeyList * pOldKeyList );
CWKeyList( PStorage & storage, WORKID objectid, INDEXID iid, CKeyList * pOldKeyList, CKeyBuf & splitKey, WORKID widMax );
virtual ~CWKeyList();
KEYID PutKey( CKeyBuf const * pkey, BitOffset & bitOff );
void Flush() { _pPhysIndex->Flush(); }
void Done( BOOL & fAbort );
private:
inline int Compare( CKeyBuf const * pk1, CKeyBuf const * pk2 );
void BuildHash( BOOL & fAbort );
ULONG GetKeyId() { return ++_widMax; }
void RestoreDirectory( CKeyBuf & splitKey, BitOffset & beginBitOff, BitOffset & endBitOff );
const LONGLONG _sigWKeyList; //
CKeyCursor * _pOldKeyCursor; CKeyComp * _pKeyComp; // Key compressor
ULONG _ulPage; // Last page written to directory
CKeyBuf _keyLast; // Last key written.
};
//+-------------------------------------------------------------------------
//
// Method: CKeyList::CKeyList
//
// Synopsis: Ctor for derived classes. Only initializes CIndex
//
// Arguments: [id] -- Index id
// [widMax] -- Max workid (keyid)
//
// Returns:
//
// History: 17-Feb-1994 KyleP Created
//
//--------------------------------------------------------------------------
inline CKeyList::CKeyList ( PStorage & storage, WORKID objectId, INDEXID id, WORKID widMax, int ) : CIndex( id, widMax, FALSE ), _sigKeyList(eSigKeyList), _pstorage ( &storage ), _pDir (0), _pPhysIndex(0), _pPhysHash(0), _obj ( storage.QueryObject(objectId) ) { END_CONSTRUCTION( CKeyList ); }
//+-------------------------------------------------------------------------
//
// Method: CWKeyList::Compare
//
// Synopsis: Compare two keys, sans 'type byte' (first byte of key)
//
// Arguments: [pk1] -- First key
// [pk2] -- Second key
//
// Returns: < 0, 0, > 0 if pk1 < pk2, pk1 == pk2, pk1 > pk2
//
// History: 17-Feb-1994 KyleP Created
//
//--------------------------------------------------------------------------
inline int CWKeyList::Compare( CKeyBuf const * pk1, CKeyBuf const * pk2 ) { Win4Assert( pk1 != 0 ); Win4Assert( pk2 != 0 );
Win4Assert( pk2->Count() > 1 );
unsigned long mincb = __min(pk1->Count(), pk2->Count()-1 );
int diff = memcmp( pk1->GetBuf(), pk2->GetBuf()+1, mincb);
if (diff == 0) { // this->buf == key.buf
diff = pk1->Count() - (pk2->Count()-1); } return(diff); }
//+---------------------------------------------------------------------------
//
// Class: SKeyList
//
// Purpose: Smart Pointer to key list
//
// History: 28-Oct-93 w-PatG Stolen from BartoszM
// 17-Feb-94 KyleP Initial version
//
//----------------------------------------------------------------------------
class SKeyList : INHERIT_UNWIND { DECLARE_UNWIND
public:
SKeyList ( CKeyList * pKeyList ) : _pKeyList(pKeyList) { END_CONSTRUCTION( SKeyList ); }
~SKeyList () { delete _pKeyList; }
CKeyList* operator-> () { return _pKeyList; }
CKeyList * Transfer() { CKeyList * temp = _pKeyList; _pKeyList = 0; return( temp ); }
private:
CKeyList * _pKeyList; };
//+--------------------------------------------------------------------------
//
// Class: CKeyListCursor
//
// Purpose: Smart pointer to a keylist key cursor
//
// History: 17-Jun-94 dlee Created
//
//---------------------------------------------------------------------------
class CKeyListCursor : INHERIT_UNWIND { DECLARE_UNWIND
public: CKeyListCursor(CKeyList *pKeyList) : _pCursor(0) { _pCursor = pKeyList->QueryCursor(); END_CONSTRUCTION(CKeyListCursor); } ~CKeyListCursor() { delete _pCursor; } CKeyCursor* operator->() { return(_pCursor); }
private: CKeyCursor *_pCursor; };
#else // !KEYLIST_ENABLED
//+---------------------------------------------------------------------------
//
// Class: CKeyList
//
// Purpose: A simple key list that just tracks the number of keys
// in the index.
//
// History: 3-12-96 srikants Created
//
// Notes:
//
//----------------------------------------------------------------------------
class CKeyList : public CIndex { INLINE_UNWIND( CKeyList )
public:
CKeyList();
CKeyList( KEYID kidMax, INDEXID iid );
KEYID MaxKeyIdInUse() const { return MaxWorkId(); }
void SetMaxKeyIdInUse( KEYID kidMax ) { SetMaxWorkId( kidMax ); }
void AddKey() { _widMax++; }
INDEXID GetNextIid (); void FillRecord( CIndexRecord& record ) const;
WORKID ObjectId() const { return 0; }
private:
//
// From CIndex
//
virtual unsigned Size () const { return 0; }
virtual void Remove() {
}
virtual CKeyCursor * QueryCursor() { return 0; }
//
// From CQueriable
//
virtual COccCursor * QueryCursor( CKey const * pkey, BOOL isRange, ULONG & cMaxNodes ) { return 0; }
virtual COccCursor * QueryRangeCursor( const CKey * pkeyBegin, const CKey * pkeyEnd, ULONG & cMaxNodes ) { return 0; }
virtual COccCursor * QuerySynCursor( CKeyArray & keyArr, BOOL isRange, ULONG & cMaxNodes ) { return 0; }
private:
int _iDummy1;
};
class CWKeyList : public CKeyList { INLINE_UNWIND( CWKeyList )
public:
CWKeyList( KEYID kidMax, INDEXID iid ) : CKeyList( kidMax, iid ) { END_CONSTRUCTION( CWKeyList ); }
private:
int _iDummy2;
};
#endif // !KEYLIST_ENABLED
|