|
|
// Indicate.h
// Class CIndicatorSet by Ron Murray
// Created 8 September 1992
#ifndef __INDICATE_H__
#define __INDICATE_H__
#include "Defines.h"
#include "RefCnt.h"
#include "SaveLoad.h"
#include "Util.h"
#include "CallBKQ.h"
#include "Compress.h"
void ClearBits(PUINT pulBase, UINT iBit, UINT cBits); void SetBits (PUINT pulBase, UINT iBit, UINT cBits); void MoveBits (PUINT pulSrc, UINT iSrcFirst, PUINT pulDest, UINT iDestFirst, UINT cBits);
class CTokenList; class CAValRef; class CSegHashTable; class CTextDatabase; class CTextSet;
class CCompressedSet;
class CIndicatorSet : public CRCObject { friend class CTokenList; friend class CAValRef; friend class CSegHashTable; friend class CTextDatabase; friend class CTextSet; friend class CCompressedSet; friend class CTokenCollection; friend class CTitleCollection; friend class CFind;
friend void FoundValidToken(UINT iValue, PVOID pvTag, PVOID pvEnvironment);
public:
// Creators:
static CIndicatorSet* NewIndicatorSet(UINT cItems, BOOL fFillWithOnes= FALSE); static CIndicatorSet* NewIndicatorSet(UINT cItems, UINT iFirstOne, UINT cOnes); static CIndicatorSet* NewIndicatorSet(UINT cItems, PUINT paulBitVector, BOOL fFromFile= FALSE); static CIndicatorSet* NewIndicatorSet(UINT cItems, PUINT pafMasks, UINT fMask, UINT value); static CIndicatorSet* NewIndicatorSet(CIndicatorSet *pis); // To make a copy of an indicator set.
static CIndicatorSet* NewIndicatorSet(CCompressedSet *pcs, UINT cbits= 0); // To decompress a compressed set
// Destructor:
virtual ~CIndicatorSet();
// Reference Counting Routines --
DECLARE_REF_COUNTERS(CIndicatorSet)
// Save/Load Interface --
void StoreImage(CPersist *pDiskImage); static CIndicatorSet * CreateImage(CPersist *pDiskImage); static void SkipImage(CPersist *pDiskImage);
// Access Functions:
int ChangeBit(long iBit, UINT usMethod);
BOOL IsBitSet(long iBit); BOOL AnyOnes(); void ClearAll(); enum { CLEAR_BIT=0, SET_BIT, TOGGLE_BIT }; // usMethod values...
CIndicatorSet *CopyFrom(CIndicatorSet *pis); CIndicatorSet * ANDWith(CIndicatorSet *pis); CIndicatorSet *NANDWith(CIndicatorSet *pis); CIndicatorSet * ORWith(CIndicatorSet *pis); CIndicatorSet * NORWith(CIndicatorSet *pis); CIndicatorSet *LESSWith(CIndicatorSet *pis); CIndicatorSet * LEQWith(CIndicatorSet *pis); CIndicatorSet * EQVWith(CIndicatorSet *pis); CIndicatorSet * NEQWith(CIndicatorSet *pis); CIndicatorSet * GTRWith(CIndicatorSet *pis); // And Not (minus)
CIndicatorSet * GEQWith(CIndicatorSet *pis);
CIndicatorSet *Catenate(CIndicatorSet *pis);
CIndicatorSet *NEScan(); CIndicatorSet *Invert(); CIndicatorSet *ShiftIndicators(int cBitsDistance); // +ve => right shift
// -ve => left shift
CIndicatorSet *TakeIndicators(long cBits); // +ve => Take from left , pad on right
// -ve => Take from right, pad on left
CIndicatorSet *MarkedPartitions(CIndicatorSet *pisMarks, BOOL fPartitionedAtEnd= TRUE); inline void SetBit(long iBit) { InvalidateCache(); RawSetBit(iBit); }
inline void ClearBit(long iBit) { InvalidateCache(); RawClearBit(iBit); }
inline void ToggleBit(long iBit) { InvalidateCache(); RawToggleBit(iBit); }
int ActiveIndices(int iLowBound, int iHighBound, int * piOneBits);
UINT ItemCount(); // returns Rho IS
int SelectionCount(); // returns +/IS
int MarkedItems(int iMarked, int *piUnmarked, int cMarkedItems); // returns cMarkedItems Take iMarked Drop IS / Iota Rho IS
int PredecessorMarkCount(int iItem); // returns +/ iItem Take IS
protected:
void ConnectImage(CPersist *pDiskImage); inline void InvalidateCache() { m_fCountsValid= FALSE; } // Must be called after
// calling RawSetBit, RawClearBit
// or RawToggleBit.
inline void RawSetBit(long iBit) { ASSERT(UINT(iBit) < m_cEntries); m_paulBits[IDWORD_OF_IBIT(iBit)] |= 1 << IBIT_RESIDUE(iBit); }
inline void RawClearBit(long iBit) { ASSERT(UINT(iBit) < m_cEntries); m_paulBits[IDWORD_OF_IBIT(iBit)] &= ~(1 << IBIT_RESIDUE(iBit)); }
inline void RawToggleBit(long iBit) { ASSERT(UINT(iBit) < m_cEntries); m_paulBits[IDWORD_OF_IBIT(iBit)] ^= 1 << IBIT_RESIDUE(iBit); }
private:
// Constructor:
CIndicatorSet(); // Initializers:
void InitialIndicatorSet(UINT cItems, BOOL fFillWithOnes= FALSE); void InitialIndicatorSet(UINT cItems, UINT iFirstOne, UINT cOnes); void InitialIndicatorSet(UINT cItems, PUINT paulBitVector, BOOL fFromFile= FALSE); void InitialIndicatorSet(UINT cItems, PUINT pafMasks, UINT fMask, UINT value); void InitialIndicatorSet(CIndicatorSet *pis); // To make a copy of an indicator set.
void InitialIndicatorSet(CCompressedSet *pcs, UINT cbits= 0); // To decompress a compressed set
// Private member variables:
BOOL m_fFromFileImage; UINT m_cEntries; UINT m_how_constructed; // See construction types below.
enum CreationType {Unbuilt, From_Count, From_Bits};
UINT * m_paCumulativeSums; UINT * m_paulBits; BOOL m_fCountsValid;
enum { BITS_PER_SUM= 8192 };
// Private routines:
inline int BytesPerSum() { return BITS_PER_SUM/8; }
inline int CBrackets() { return (m_cEntries+BITS_PER_SUM-1)/BITS_PER_SUM; }
inline PBYTE PBCluster(int i) { return ((PBYTE) m_paulBits) + i * BytesPerSum(); }
void SetupFromBitVector(UINT cItems, BOOL fFromFile= FALSE); void ConstructBitCounts(); };
class CCmpEnumerator;
class CCompressedSet : public CRCObject { friend class CCmpEnumerator; public:
// Creators --
static CCompressedSet *NewCompressedSet(CDataRing *pdrIn, UINT cIndices, UINT iBase, UINT iLimit); static CCompressedSet *NewCompressedSet(PUINT paiSequence, UINT ciSequence, UINT iLimit); static CCompressedSet *NewCompressedSet(CIndicatorSet *pis); static CCompressedSet *NewCompressedSet(CCompressedSet *pcs);
// Destructor --
~CCompressedSet();
// Reference Counting Routines --
DECLARE_REF_COUNTERS(CCompressedSet)
// Save/Load Interface --
void StoreImage(CPersist *pDiskImage); static CCompressedSet * CreateImage(CPersist *pDiskImage); static void SkipImage(CPersist *pDiskImage);
// Access routines --
void IndicateMembers(CIndicatorSet *pis);
UINT ItemCount(); UINT SelectionCount();
protected:
void ConnectImage(CPersist *pDiskImage);
private:
// Constructor --
CCompressedSet();
// Internal routines --
static BOOL ScanDWords (PVOID pv, PUINT pdw, PUINT pcdw); static BOOL DumpIndicatorBits(PVOID pv, PUINT pdw, PUINT pcdw); static void StoreDWords (PVOID pv, PUINT pdw, UINT cdw); static void SetBits (PVOID pv, PUINT pdw, UINT cdw);
// Private data members --
BOOL m_fFromFile; UINT m_cPositions; union { UINT m_iRefFirst; PUINT m_pdwCompressed; };
union { UINT m_iRefSecond; UINT m_cdwCompressed; };
union { RefBits m_rb; UINT m_iRefThird; }; };
class CCmpEnumerator : public CDWInputQueue {
public:
// Creator --
static CCmpEnumerator *NewEnumerator(CCompressedSet *pcs);
// Destructor --
~CCmpEnumerator();
protected:
// Initialing --
void Initial(CCompressedSet *pcs);
// Constructor --
CCmpEnumerator();
private:
// Internal routines --
static BOOL ReadSmall(PVOID pv, PUINT pdw, PUINT pcdw); static BOOL ReadLarge(PVOID pv, PUINT pdw, PUINT pcdw);
// Private data members --
CCompressedSet *m_pcs; UINT m_iNext; CExpandor *m_pex; };
// In some cases we know that cBits will always lie in the interval 0..31.
// In those situations we can use RawShiftLeft and RawShiftRight. Note the
// use of ASSERT to verify our assumption in the debugging environment.
inline UINT RawShiftLeft(UINT ulValue, UINT cBits) { ASSERT(cBits < 32);
return(ulValue << cBits); }
inline UINT RawShiftRight(UINT ulValue, UINT cBits) { ASSERT(cBits < 32);
return(ulValue >> cBits); }
inline BOOL CIndicatorSet::IsBitSet(long iBit) { // Returns the value of entry slot iBit.
ASSERT(iBit >= 0 && iBit < long(m_cEntries));
return 1 & RawShiftRight(m_paulBits[IDWORD_OF_IBIT(iBit)], IBIT_RESIDUE(iBit)); }
inline UINT CCompressedSet::ItemCount() { ASSERT(m_cPositions >= (m_rb.fRefPair? 3 : m_rb.cReferences)); return m_cPositions; }
inline UINT CCompressedSet::SelectionCount() { ASSERT(m_cPositions >= (m_rb.fRefPair? 3 : m_rb.cReferences)); return m_rb.fRefPair? 3 : m_rb.cReferences; }
#endif // __INDICATE_H__
|