You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
421 lines
10 KiB
421 lines
10 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// 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
|
|
|