diff options
Diffstat (limited to 'comm/mailnews/db/mork/morkRow.h')
-rw-r--r-- | comm/mailnews/db/mork/morkRow.h | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/comm/mailnews/db/mork/morkRow.h b/comm/mailnews/db/mork/morkRow.h new file mode 100644 index 0000000000..e8a8c728ac --- /dev/null +++ b/comm/mailnews/db/mork/morkRow.h @@ -0,0 +1,208 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _MORKROW_ +#define _MORKROW_ 1 + +#ifndef _MORK_ +# include "mork.h" +#endif + +#ifndef _MORKCELL_ +# include "morkCell.h" +#endif + +// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 + +class nsIMdbRow; +class nsIMdbCell; +#define morkDerived_kRow /*i*/ 0x5277 /* ascii 'Rw' */ + +#define morkRow_kMaxGcUses 0x0FF /* max for 8-bit unsigned int */ +#define morkRow_kMaxLength 0x0FFFF /* max for 16-bit unsigned int */ +#define morkRow_kMinusOneRid ((mork_rid)-1) + +#define morkRow_kTag 'r' /* magic signature for mRow_Tag */ + +#define morkRow_kNotedBit ((mork_u1)(1 << 0)) /* space has change notes */ +#define morkRow_kRewriteBit ((mork_u1)(1 << 1)) /* must rewrite all cells */ +#define morkRow_kDirtyBit ((mork_u1)(1 << 2)) /* row has been changed */ + +class morkRow { // row of cells + + public: // state is public because the entire Mork system is private + morkRowSpace* mRow_Space; // mRow_Space->SpaceScope() is the row scope + morkRowObject* mRow_Object; // refcount & other state for object sharing + morkCell* mRow_Cells; + mdbOid mRow_Oid; + + mork_delta mRow_Delta; // space to note a single column change + + mork_u2 mRow_Length; // physical count of cells in mRow_Cells + mork_u2 mRow_Seed; // count changes in mRow_Cells structure + + mork_u1 mRow_GcUses; // persistent references from tables + mork_u1 mRow_Pad; // for u1 alignment + mork_u1 mRow_Flags; // one-byte flags slot + mork_u1 mRow_Tag; // one-byte tag (need u4 alignment pad) + + public: // interpreting mRow_Delta + mork_bool HasRowDelta() const { return (mRow_Delta != 0); } + + void ClearRowDelta() { mRow_Delta = 0; } + + void SetRowDelta(mork_column inCol, mork_change inChange) { + morkDelta_Init(mRow_Delta, inCol, inChange); + } + + mork_column GetDeltaColumn() const { return morkDelta_Column(mRow_Delta); } + mork_change GetDeltaChange() const { return morkDelta_Change(mRow_Delta); } + + public: // noting row changes + void NoteRowSetAll(morkEnv* ev); + void NoteRowSetCol(morkEnv* ev, mork_column inCol); + void NoteRowAddCol(morkEnv* ev, mork_column inCol); + void NoteRowCutCol(morkEnv* ev, mork_column inCol); + + public: // flags bit twiddling + void SetRowNoted() { mRow_Flags |= morkRow_kNotedBit; } + void SetRowRewrite() { mRow_Flags |= morkRow_kRewriteBit; } + void SetRowDirty() { mRow_Flags |= morkRow_kDirtyBit; } + + void ClearRowNoted() { mRow_Flags &= (mork_u1)~morkRow_kNotedBit; } + void ClearRowRewrite() { mRow_Flags &= (mork_u1)~morkRow_kRewriteBit; } + void SetRowClean() { + mRow_Flags = 0; + mRow_Delta = 0; + } + + mork_bool IsRowNoted() const { return (mRow_Flags & morkRow_kNotedBit) != 0; } + + mork_bool IsRowRewrite() const { + return (mRow_Flags & morkRow_kRewriteBit) != 0; + } + + mork_bool IsRowClean() const { return (mRow_Flags & morkRow_kDirtyBit) == 0; } + + mork_bool IsRowDirty() const { return (mRow_Flags & morkRow_kDirtyBit) != 0; } + + mork_bool IsRowUsed() const { return mRow_GcUses != 0; } + + public: // other row methods + morkRow() {} + explicit morkRow(const mdbOid* inOid) : mRow_Oid(*inOid) {} + void InitRow(morkEnv* ev, const mdbOid* inOid, morkRowSpace* ioSpace, + mork_size inLength, morkPool* ioPool); + // if inLength is nonzero, cells will be allocated from ioPool + + morkRowObject* AcquireRowObject(morkEnv* ev, morkStore* ioStore); + nsIMdbRow* AcquireRowHandle(morkEnv* ev, morkStore* ioStore); + nsIMdbCell* AcquireCellHandle(morkEnv* ev, morkCell* ioCell, + mdb_column inColumn, mork_pos inPos); + + mork_u2 AddRowGcUse(morkEnv* ev); + mork_u2 CutRowGcUse(morkEnv* ev); + + mork_bool MaybeDirtySpaceStoreAndRow(); + + public: // internal row methods + void cut_all_index_entries(morkEnv* ev); + + // void cut_cell_from_space_index(morkEnv* ev, morkCell* ioCell); + + mork_count CountOverlap(morkEnv* ev, morkCell* ioVector, mork_fill inFill); + // Count cells in ioVector that change existing cells in this row when + // ioVector is added to the row (as in TakeCells()). This is the set + // of cells with the same columns in ioVector and mRow_Cells, which do + // not have exactly the same value in mCell_Atom, and which do not both + // have change status equal to morkChange_kCut (because cutting a cut + // cell still yields a cell that has been cut). CountOverlap() also + // modifies the change attribute of any cell in ioVector to kDup when + // the change was previously kCut and the same column cell was found + // in this row with change also equal to kCut; this tells callers later + // they need not look for that cell in the row again on a second pass. + + void MergeCells(morkEnv* ev, morkCell* ioVector, mork_fill inVecLength, + mork_fill inOldRowFill, mork_fill inOverlap); + // MergeCells() is the part of TakeCells() that does the insertion. + // inOldRowFill is the old value of mRow_Length, and inOverlap is the + // number of cells in the intersection that must be updated. + + void TakeCells(morkEnv* ev, morkCell* ioVector, mork_fill inVecLength, + morkStore* ioStore); + + morkCell* NewCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos, + morkStore* ioStore); + morkCell* GetCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos) const; + morkCell* CellAt(morkEnv* ev, mork_pos inPos) const; + + mork_aid GetCellAtomAid(morkEnv* ev, mdb_column inColumn) const; + // GetCellAtomAid() finds the cell with column inColumn, and sees if the + // atom has a token ID, and returns the atom's ID if there is one. Or + // else zero is returned if there is no such column, or no atom, or if + // the atom has no ID to return. This method is intended to support + // efficient updating of column indexes for rows in a row space. + + public: // external row methods + void DirtyAllRowContent(morkEnv* ev); + + morkStore* GetRowSpaceStore(morkEnv* ev) const; + + void AddColumn(morkEnv* ev, mdb_column inColumn, const mdbYarn* inYarn, + morkStore* ioStore); + + morkAtom* GetColumnAtom(morkEnv* ev, mdb_column inColumn); + + void NextColumn(morkEnv* ev, mdb_column* ioColumn, mdbYarn* outYarn); + + void SeekColumn(morkEnv* ev, mdb_pos inPos, mdb_column* outColumn, + mdbYarn* outYarn); + + void CutColumn(morkEnv* ev, mdb_column inColumn); + + morkRowCellCursor* NewRowCellCursor(morkEnv* ev, mdb_pos inPos); + + void EmptyAllCells(morkEnv* ev); + void AddRow(morkEnv* ev, const morkRow* inSourceRow); + void SetRow(morkEnv* ev, const morkRow* inSourceRow); + void CutAllColumns(morkEnv* ev); + + void OnZeroRowGcUse(morkEnv* ev); + // OnZeroRowGcUse() is called when CutRowGcUse() returns zero. + + public: // dynamic typing + mork_bool IsRow() const { return mRow_Tag == morkRow_kTag; } + + public: // hash and equal + mork_u4 HashRow() const { + return (mRow_Oid.mOid_Scope << 16) ^ mRow_Oid.mOid_Id; + } + + mork_bool EqualRow(const morkRow* ioRow) const { + return ((mRow_Oid.mOid_Scope == ioRow->mRow_Oid.mOid_Scope) && + (mRow_Oid.mOid_Id == ioRow->mRow_Oid.mOid_Id)); + } + + mork_bool EqualOid(const mdbOid* ioOid) const { + return ((mRow_Oid.mOid_Scope == ioOid->mOid_Scope) && + (mRow_Oid.mOid_Id == ioOid->mOid_Id)); + } + + public: // errors + static void ZeroColumnError(morkEnv* ev); + static void LengthBeyondMaxError(morkEnv* ev); + static void NilCellsError(morkEnv* ev); + static void NonRowTypeError(morkEnv* ev); + static void NonRowTypeWarning(morkEnv* ev); + static void GcUsesUnderflowWarning(morkEnv* ev); + + private: // copying is not allowed + morkRow(const morkRow& other); + morkRow& operator=(const morkRow& other); +}; + +// 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789 + +#endif /* _MORKROW_ */ |