Back to index

lightning-sunbird  0.9+nobinonly
morkRow.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-  */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #ifndef _MORKROW_
00039 #define _MORKROW_ 1
00040 
00041 #ifndef _MORK_
00042 #include "mork.h"
00043 #endif
00044 
00045 #ifndef _MORKCELL_
00046 #include "morkCell.h"
00047 #endif
00048 
00049 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
00050 
00051 class nsIMdbRow;
00052 class nsIMdbCell;
00053 #define morkDerived_kRow  /*i*/ 0x5277 /* ascii 'Rw' */
00054 
00055 #define morkRow_kMaxGcUses 0x0FF /* max for 8-bit unsigned int */
00056 #define morkRow_kMaxLength 0x0FFFF /* max for 16-bit unsigned int */
00057 #define morkRow_kMinusOneRid ((mork_rid) -1)
00058 
00059 #define morkRow_kTag 'r' /* magic signature for mRow_Tag */
00060 
00061 #define morkRow_kNotedBit   ((mork_u1) (1 << 0)) /* space has change notes */
00062 #define morkRow_kRewriteBit ((mork_u1) (1 << 1)) /* must rewrite all cells */
00063 #define morkRow_kDirtyBit   ((mork_u1) (1 << 2)) /* row has been changed */
00064 
00065 class morkRow{ // row of cells
00066 
00067 public: // state is public because the entire Mork system is private
00068 
00069   morkRowSpace*   mRow_Space;  // mRow_Space->SpaceScope() is the row scope 
00070   morkRowObject*  mRow_Object; // refcount & other state for object sharing
00071   morkCell*       mRow_Cells;
00072   mdbOid          mRow_Oid;
00073   
00074   mork_delta      mRow_Delta;   // space to note a single column change
00075 
00076   mork_u2         mRow_Length;     // physical count of cells in mRow_Cells 
00077   mork_u2         mRow_Seed;       // count changes in mRow_Cells structure
00078 
00079   mork_u1         mRow_GcUses;  // persistent references from tables
00080   mork_u1         mRow_Pad;     // for u1 alignment
00081   mork_u1         mRow_Flags;   // one-byte flags slot
00082   mork_u1         mRow_Tag;     // one-byte tag (need u4 alignment pad)
00083 
00084 public: // interpreting mRow_Delta
00085   
00086   mork_bool HasRowDelta() const { return ( mRow_Delta != 0 ); }
00087   
00088   void ClearRowDelta() { mRow_Delta = 0; }
00089   
00090   void SetRowDelta(mork_column inCol, mork_change inChange)
00091   { morkDelta_Init(mRow_Delta, inCol, inChange); }
00092   
00093   mork_column  GetDeltaColumn() const { return morkDelta_Column(mRow_Delta); }
00094   mork_change  GetDeltaChange() const { return morkDelta_Change(mRow_Delta); }
00095 
00096 public: // noting row changes
00097 
00098   void NoteRowSetAll(morkEnv* ev);
00099   void NoteRowSetCol(morkEnv* ev, mork_column inCol);
00100   void NoteRowAddCol(morkEnv* ev, mork_column inCol);
00101   void NoteRowCutCol(morkEnv* ev, mork_column inCol);
00102 
00103 public: // flags bit twiddling
00104 
00105   void SetRowNoted() { mRow_Flags |= morkRow_kNotedBit; }
00106   void SetRowRewrite() { mRow_Flags |= morkRow_kRewriteBit; }
00107   void SetRowDirty() { mRow_Flags |= morkRow_kDirtyBit; }
00108 
00109   void ClearRowNoted() { mRow_Flags &= (mork_u1) ~morkRow_kNotedBit; }
00110   void ClearRowRewrite() { mRow_Flags &= (mork_u1) ~morkRow_kRewriteBit; }
00111   void SetRowClean() { mRow_Flags = 0; mRow_Delta = 0; }
00112   
00113   mork_bool IsRowNoted() const
00114   { return ( mRow_Flags & morkRow_kNotedBit ) != 0; }
00115   
00116   mork_bool IsRowRewrite() const
00117   { return ( mRow_Flags & morkRow_kRewriteBit ) != 0; }
00118    
00119   mork_bool IsRowClean() const
00120   { return ( mRow_Flags & morkRow_kDirtyBit ) == 0; }
00121   
00122   mork_bool IsRowDirty() const
00123   { return ( mRow_Flags & morkRow_kDirtyBit ) != 0; }
00124   
00125   mork_bool IsRowUsed() const
00126   { return mRow_GcUses != 0; }
00127 
00128 public: // other row methods
00129   morkRow( ) { }
00130   morkRow(const mdbOid* inOid) :mRow_Oid(*inOid) { }
00131   void InitRow(morkEnv* ev, const mdbOid* inOid, morkRowSpace* ioSpace,
00132     mork_size inLength, morkPool* ioPool);
00133     // if inLength is nonzero, cells will be allocated from ioPool
00134 
00135   morkRowObject* AcquireRowObject(morkEnv* ev, morkStore* ioStore);
00136   nsIMdbRow* AcquireRowHandle(morkEnv* ev, morkStore* ioStore);
00137   nsIMdbCell* AcquireCellHandle(morkEnv* ev, morkCell* ioCell,
00138     mdb_column inColumn, mork_pos inPos);
00139   
00140   mork_u2 AddRowGcUse(morkEnv* ev);
00141   mork_u2 CutRowGcUse(morkEnv* ev);
00142 
00143   
00144   mork_bool MaybeDirtySpaceStoreAndRow();
00145 
00146 public: // internal row methods
00147 
00148   void cut_all_index_entries(morkEnv* ev);
00149 
00150   // void cut_cell_from_space_index(morkEnv* ev, morkCell* ioCell);
00151 
00152   mork_count CountOverlap(morkEnv* ev, morkCell* ioVector, mork_fill inFill);
00153   // Count cells in ioVector that change existing cells in this row when
00154   // ioVector is added to the row (as in TakeCells()).   This is the set
00155   // of cells with the same columns in ioVector and mRow_Cells, which do
00156   // not have exactly the same value in mCell_Atom, and which do not both
00157   // have change status equal to morkChange_kCut (because cutting a cut
00158   // cell still yields a cell that has been cut).  CountOverlap() also
00159   // modifies the change attribute of any cell in ioVector to kDup when
00160   // the change was previously kCut and the same column cell was found
00161   // in this row with change also equal to kCut; this tells callers later
00162   // they need not look for that cell in the row again on a second pass.
00163 
00164   void MergeCells(morkEnv* ev, morkCell* ioVector,
00165     mork_fill inVecLength, mork_fill inOldRowFill, mork_fill inOverlap);
00166   // MergeCells() is the part of TakeCells() that does the insertion.
00167   // inOldRowFill is the old value of mRow_Length, and inOverlap is the
00168   // number of cells in the intersection that must be updated.
00169 
00170   void TakeCells(morkEnv* ev, morkCell* ioVector, mork_fill inVecLength,
00171     morkStore* ioStore);
00172 
00173   morkCell* NewCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos,
00174     morkStore* ioStore);
00175   morkCell* GetCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos) const;
00176   morkCell* CellAt(morkEnv* ev, mork_pos inPos) const;
00177 
00178   mork_aid GetCellAtomAid(morkEnv* ev, mdb_column inColumn) const;
00179   // GetCellAtomAid() finds the cell with column inColumn, and sees if the
00180   // atom has a token ID, and returns the atom's ID if there is one.  Or
00181   // else zero is returned if there is no such column, or no atom, or if
00182   // the atom has no ID to return.  This method is intended to support
00183   // efficient updating of column indexes for rows in a row space.
00184 
00185 public: // external row methods
00186 
00187   void DirtyAllRowContent(morkEnv* ev);
00188 
00189   morkStore* GetRowSpaceStore(morkEnv* ev) const;
00190 
00191   void AddColumn(morkEnv* ev, mdb_column inColumn,
00192     const mdbYarn* inYarn, morkStore* ioStore);
00193 
00194   morkAtom* GetColumnAtom(morkEnv* ev, mdb_column inColumn);
00195 
00196   void NextColumn(morkEnv* ev, mdb_column* ioColumn, mdbYarn* outYarn);
00197 
00198   void SeekColumn(morkEnv* ev, mdb_pos inPos, 
00199          mdb_column* outColumn, mdbYarn* outYarn);
00200 
00201   void CutColumn(morkEnv* ev, mdb_column inColumn);
00202 
00203   morkRowCellCursor* NewRowCellCursor(morkEnv* ev, mdb_pos inPos);
00204   
00205   void EmptyAllCells(morkEnv* ev);
00206   void AddRow(morkEnv* ev, const morkRow* inSourceRow);
00207   void SetRow(morkEnv* ev, const morkRow* inSourceRow);
00208   void CutAllColumns(morkEnv* ev);
00209 
00210   void OnZeroRowGcUse(morkEnv* ev);
00211   // OnZeroRowGcUse() is called when CutRowGcUse() returns zero.
00212 
00213 public: // dynamic typing
00214 
00215   mork_bool IsRow() const { return mRow_Tag == morkRow_kTag; }
00216 
00217 public: // hash and equal
00218 
00219   mork_u4 HashRow() const
00220   {
00221     return (mRow_Oid.mOid_Scope << 16) ^ mRow_Oid.mOid_Id;
00222   }
00223 
00224   mork_bool EqualRow(const morkRow* ioRow) const
00225   {
00226     return
00227     (
00228       ( mRow_Oid.mOid_Scope == ioRow->mRow_Oid.mOid_Scope ) 
00229       && ( mRow_Oid.mOid_Id == ioRow->mRow_Oid.mOid_Id )
00230     );
00231   }
00232 
00233   mork_bool EqualOid(const mdbOid* ioOid) const
00234   {
00235     return
00236     (
00237       ( mRow_Oid.mOid_Scope == ioOid->mOid_Scope ) 
00238       && ( mRow_Oid.mOid_Id == ioOid->mOid_Id )
00239     );
00240   }
00241 
00242 public: // errors
00243   static void ZeroColumnError(morkEnv* ev);
00244   static void LengthBeyondMaxError(morkEnv* ev);
00245   static void NilCellsError(morkEnv* ev);
00246   static void NonRowTypeError(morkEnv* ev);
00247   static void NonRowTypeWarning(morkEnv* ev);
00248   static void GcUsesUnderflowWarning(morkEnv* ev);
00249 
00250 private: // copying is not allowed
00251   morkRow(const morkRow& other);
00252   morkRow& operator=(const morkRow& other);
00253 };
00254 
00255 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
00256 
00257 #endif /* _MORKROW_ */
00258