add FindRow api, fix lots of warnings, speed up msg threading

This commit is contained in:
bienvenu%netscape.com 1999-05-04 02:55:30 +00:00
Родитель 10dc94a5a3
Коммит 9f481ea375
126 изменённых файлов: 2552 добавлений и 4897 удалений

Просмотреть файл

@ -939,16 +939,54 @@ public:
nsIMdbEnv* ev, // context
const mdbOid* inOid, // hypothetical row oid
mdb_bool* outHasRow) = 0; // whether GetRow() might succeed
virtual mdb_err GetRowRefCount( // get number of tables that contain a row
nsIMdbEnv* ev, // context
const mdbOid* inOid, // hypothetical row oid
mdb_count* outRefCount) = 0; // number of tables containing inRowKey
virtual mdb_err GetRow( // access one row with specific oid
nsIMdbEnv* ev, // context
const mdbOid* inOid, // hypothetical row oid
nsIMdbRow** acqRow) = 0; // acquire specific row (or null)
virtual mdb_err GetRowRefCount( // get number of tables that contain a row
nsIMdbEnv* ev, // context
const mdbOid* inOid, // hypothetical row oid
mdb_count* outRefCount) = 0; // number of tables containing inRowKey
virtual mdb_err FindRow(nsIMdbEnv* ev, // search for row with matching cell
mdb_scope inRowScope, // row scope for row ids
mdb_column inColumn, // the column to search (and maintain an index)
const mdbYarn* inTargetCellValue, // cell value for which to search
mdbOid* outRowOid, // out row oid on match (or {0,-1} for no match)
nsIMdbRow** acqRow) = 0; // acquire matching row (or nil for no match)
// FindRow() searches for one row that has a cell in column inColumn with
// a contained value with the same form (i.e. charset) and is byte-wise
// identical to the blob described by yarn inTargetCellValue. Both content
// and form of the yarn must be an exact match to find a matching row.
//
// (In other words, both a yarn's blob bytes and form are significant. The
// form is not expected to vary in columns used for identity anyway. This
// is intended to make the cost of FindRow() cheaper for MDB implementors,
// since any cell value atomization performed internally must necessarily
// make yarn form significant in order to avoid data loss in atomization.)
//
// FindRow() can lazily create an index on attribute inColumn for all rows
// with that attribute in row space scope inRowScope, so that subsequent
// calls to FindRow() will perform faster. Such an index might or might
// not be persistent (but this seems desirable if it is cheap to do so).
// Note that lazy index creation in readonly DBs is not very feasible.
//
// This FindRow() interface assumes that attribute inColumn is effectively
// an alternative means of unique identification for a row in a rowspace,
// so correct behavior is only guaranteed when no duplicates for this col
// appear in the given set of rows. (If more than one row has the same cell
// value in this column, no more than one will be found; and cutting one of
// two duplicate rows can cause the index to assume no other such row lives
// in the row space, so future calls return nil for negative search results
// even though some duplicate row might still live within the rowspace.)
//
// In other words, the FindRow() implementation is allowed to assume simple
// hash tables mapping unqiue column keys to associated row values will be
// sufficient, where any duplication is not recorded because only one copy
// of a given key need be remembered. Implementors are not required to sort
// all rows by the specified column.
// } ----- end row methods -----
// { ----- begin table methods -----
@ -1116,6 +1154,7 @@ public:
nsIMdbRow** acqRow) = 0; // create new row
// Note this row must be added to some table or cell child before the
// store is closed in order to make this row persist across sesssions.
// } ----- end row methods -----
// { ----- begin inport/export methods -----

Просмотреть файл

@ -230,7 +230,7 @@ morkArray::AppendSlot(morkEnv* ev, void* ioSlot)
mork_fill fill = mArray_Fill;
if ( this->Grow(ev, fill+1) )
{
outPos = fill;
outPos = (mork_pos) fill;
mArray_Slots[ fill ] = ioSlot;
mArray_Fill = fill + 1;
// note Grow() increments mArray_Seed
@ -269,6 +269,7 @@ morkArray::AddSlot(morkEnv* ev, mork_pos inPos, void* ioSlot)
void
morkArray::CutSlot(morkEnv* ev, mork_pos inPos)
{
MORK_USED_1(ev);
mork_fill fill = mArray_Fill;
if ( inPos >= 0 && inPos < (mork_pos) fill ) // cutting slot in used array portion?
{

Просмотреть файл

@ -204,15 +204,40 @@ morkAtom::AliasYarn(mdbYarn* outYarn) const
return ( atom != 0 );
}
mork_aid
morkAtom::GetBookAtomAid() const // zero or book atom's ID
{
return ( this->IsBook() )? ((morkBookAtom*) this)->mBookAtom_Id : 0;
}
mork_scope
morkAtom::GetBookAtomSpaceScope(morkEnv* ev) const // zero or book's space's scope
{
mork_scope outScope = 0;
if ( this->IsBook() )
{
const morkBookAtom* bookAtom = (const morkBookAtom*) this;
morkAtomSpace* space = bookAtom->mBookAtom_Space;
if ( space->IsAtomSpace() )
outScope = space->mSpace_Scope;
else
space->NonAtomSpaceTypeError(ev);
}
return outScope;
}
void
morkAtom::MakeCellUseForever(morkEnv* ev)
{
MORK_USED_1(ev);
mAtom_CellUses = morkAtom_kForeverCellUses;
}
mork_u1
morkAtom::AddCellUse(morkEnv* ev)
{
MORK_USED_1(ev);
if ( mAtom_CellUses < morkAtom_kMaxCellUses ) // not already maxed out?
++mAtom_CellUses;
@ -260,6 +285,7 @@ morkAtom::AtomSizeOverflowError(morkEnv* ev)
void
morkOidAtom::InitRowOidAtom(morkEnv* ev, const mdbOid& inOid)
{
MORK_USED_1(ev);
mAtom_CellUses = 0;
mAtom_Kind = morkAtom_kKindRowOid;
mAtom_Change = morkChange_kNil;
@ -270,6 +296,7 @@ morkOidAtom::InitRowOidAtom(morkEnv* ev, const mdbOid& inOid)
void
morkOidAtom::InitTableOidAtom(morkEnv* ev, const mdbOid& inOid)
{
MORK_USED_1(ev);
mAtom_CellUses = 0;
mAtom_Kind = morkAtom_kKindTableOid;
mAtom_Change = morkChange_kNil;
@ -301,6 +328,7 @@ void
morkBigAnonAtom::InitBigAnonAtom(morkEnv* ev, const morkBuf& inBuf,
mork_cscode inForm)
{
MORK_USED_1(ev);
mAtom_CellUses = 0;
mAtom_Kind = morkAtom_kKindBigAnon;
mAtom_Change = morkChange_kNil;

Просмотреть файл

@ -60,6 +60,14 @@ public:
mork_bool IsBook() const { return this->IsWeeBook() || this->IsBigBook(); }
public: // atom space scope if IsBook() is true, or else zero:
mork_scope GetBookAtomSpaceScope(morkEnv* ev) const;
// zero or book's space's scope
mork_aid GetBookAtomAid() const;
// zero or book atom's ID
public: // empty construction does nothing
morkAtom() { }

Просмотреть файл

@ -44,6 +44,14 @@
#include "morkAtom.h"
#endif
#ifndef _MORKINTMAP_
#include "morkIntMap.h"
#endif
#ifndef _MORKROW_
#include "morkRow.h"
#endif
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
// ````` ````` ````` ````` `````
@ -103,6 +111,7 @@ morkAtomAidMap::CloseAtomAidMap(morkEnv* ev) // called by CloseMorkNode();
morkAtomAidMap::Equal(morkEnv* ev, const void* inKeyA,
const void* inKeyB) const
{
MORK_USED_1(ev);
return (*(const morkBookAtom**) inKeyA)->EqualAid(
*(const morkBookAtom**) inKeyB);
}
@ -110,6 +119,7 @@ morkAtomAidMap::Equal(morkEnv* ev, const void* inKeyA,
/*virtual*/ mork_u4 //
morkAtomAidMap::Hash(morkEnv* ev, const void* inKey) const
{
MORK_USED_1(ev);
return (*(const morkBookAtom**) inKey)->HashAid();
}
// } ===== end morkMap poly interface =====
@ -261,3 +271,35 @@ morkAtomBodyMap::GetAtom(morkEnv* ev, const morkBookAtom* inAtom)
}
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
morkAtomRowMap::~morkAtomRowMap()
{
}
morkAtomRowMap::morkAtomRowMap(morkEnv* ev, const morkUsage& inUsage,
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_column inIndexColumn)
: morkIntMap(ev, inUsage, sizeof(mork_aid), ioHeap, ioSlotHeap,
/*inHoldChanges*/ morkBool_kFalse)
, mAtomRowMap_IndexColumn( inIndexColumn )
{
if ( ev->Good() )
mNode_Derived = morkDerived_kAtomRowMap;
}
void morkAtomRowMap::AddRow(morkEnv* ev, morkRow* ioRow)
// add ioRow only if it contains a cell in mAtomRowMap_IndexColumn.
{
mork_aid aid = ioRow->GetCellAtomAid(ev, mAtomRowMap_IndexColumn);
if ( aid )
this->AddAid(ev, aid, ioRow);
}
void morkAtomRowMap::CutRow(morkEnv* ev, morkRow* ioRow)
// cut ioRow only if it contains a cell in mAtomRowMap_IndexColumn.
{
mork_aid aid = ioRow->GetCellAtomAid(ev, mAtomRowMap_IndexColumn);
if ( aid )
this->CutAid(ev, aid);
}
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

Просмотреть файл

@ -31,6 +31,10 @@
#include "morkMap.h"
#endif
#ifndef _MORKINTMAP_
#include "morkIntMap.h"
#endif
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#define morkDerived_kAtomAidMap /*i*/ 0x6141 /* ascii 'aA' */
@ -81,6 +85,15 @@ public: // other map methods
// GetAid() returns the atom equal to inAid, or else nil
// note the atoms are owned elsewhere, usuall by morkAtomSpace
public: // typesafe refcounting inlines calling inherited morkNode methods
static void SlotWeakAtomAidMap(morkAtomAidMap* me,
morkEnv* ev, morkAtomAidMap** ioSlot)
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
static void SlotStrongAtomAidMap(morkAtomAidMap* me,
morkEnv* ev, morkAtomAidMap** ioSlot)
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
};
@ -157,6 +170,15 @@ public: // other map methods
// GetAtom() returns the atom equal to inAtom, or else nil
// note the atoms are owned elsewhere, usuall by morkAtomSpace
public: // typesafe refcounting inlines calling inherited morkNode methods
static void SlotWeakAtomBodyMap(morkAtomBodyMap* me,
morkEnv* ev, morkAtomBodyMap** ioSlot)
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
static void SlotStrongAtomBodyMap(morkAtomBodyMap* me,
morkEnv* ev, morkAtomBodyMap** ioSlot)
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
};
class morkAtomBodyMapIter: public morkMapIter{ // typesafe wrapper class
@ -182,6 +204,88 @@ public:
{ return this->CutHere(ev, outAtomPtr, /*val*/ (void*) 0); }
};
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#define morkDerived_kAtomRowMap /*i*/ 0x6152 /* ascii 'aR' */
/*| morkAtomRowMap: maps morkAtom* -> morkRow*
|*/
class morkAtomRowMap : public morkIntMap { // for mapping atoms to rows
public:
mork_column mAtomRowMap_IndexColumn; // row column being indexed
public:
virtual ~morkAtomRowMap();
morkAtomRowMap(morkEnv* ev, const morkUsage& inUsage,
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_column inIndexColumn);
public: // adding and cutting from morkRow instance candidate
void AddRow(morkEnv* ev, morkRow* ioRow);
// add ioRow only if it contains a cell in mAtomRowMap_IndexColumn.
void CutRow(morkEnv* ev, morkRow* ioRow);
// cut ioRow only if it contains a cell in mAtomRowMap_IndexColumn.
public: // other map methods
mork_bool AddAid(morkEnv* ev, mork_aid inAid, morkRow* ioRow)
{ return this->AddInt(ev, inAid, ioRow); }
// the AddAid() boolean return equals ev->Good().
mork_bool CutAid(morkEnv* ev, mork_aid inAid)
{ return this->CutInt(ev, inAid); }
// The CutAid() boolean return indicates whether removal happened.
morkRow* GetAid(morkEnv* ev, mork_aid inAid)
{ return (morkRow*) this->GetInt(ev, inAid); }
// Note the returned space does NOT have an increase in refcount for this.
public: // dynamic type identification
mork_bool IsAtomRowMap() const
{ return IsNode() && mNode_Derived == morkDerived_kAtomRowMap; }
public: // typesafe refcounting inlines calling inherited morkNode methods
static void SlotWeakAtomRowMap(morkAtomRowMap* me,
morkEnv* ev, morkAtomRowMap** ioSlot)
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
static void SlotStrongAtomRowMap(morkAtomRowMap* me,
morkEnv* ev, morkAtomRowMap** ioSlot)
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
};
class morkAtomRowMapIter: public morkMapIter{ // typesafe wrapper class
public:
morkAtomRowMapIter(morkEnv* ev, morkAtomRowMap* ioMap)
: morkMapIter(ev, ioMap) { }
morkAtomRowMapIter( ) : morkMapIter() { }
void InitAtomRowMapIter(morkEnv* ev, morkAtomRowMap* ioMap)
{ this->InitMapIter(ev, ioMap); }
mork_change*
FirstAtomAndRow(morkEnv* ev, morkAtom** outAtom, morkRow** outRow)
{ return this->First(ev, outAtom, outRow); }
mork_change*
NextAtomAndRow(morkEnv* ev, morkAtom** outAtom, morkRow** outRow)
{ return this->Next(ev, outAtom, outRow); }
mork_change*
HereAtomAndRow(morkEnv* ev, morkAtom** outAtom, morkRow** outRow)
{ return this->Here(ev, outAtom, outRow); }
mork_change*
CutHereAtomAndRow(morkEnv* ev, morkAtom** outAtom, morkRow** outRow)
{ return this->CutHere(ev, outAtom, outRow); }
};
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#endif /* _MORKATOMMAP_ */

Просмотреть файл

@ -186,28 +186,28 @@ morkAtomSpace::MakeBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom)
morkBookAtom* outAtom = 0;
if ( ev->Good() )
{
if ( mSpace_Store->mStore_CanAutoAssignAtomIdentity )
{
morkPool* pool = this->GetSpaceStorePool();
morkBookAtom* atom = pool->NewBookAtomCopy(ev, inAtom);
if ( atom )
{
mork_aid id = this->MakeNewAtomId(ev, atom);
if ( id )
{
outAtom = atom;
atom->mBookAtom_Space = this;
mAtomSpace_AtomAids.AddAtom(ev, atom);
mAtomSpace_AtomBodies.AddAtom(ev, atom);
if ( mSpace_Scope == morkAtomSpace_kColumnScope )
outAtom->MakeCellUseForever(ev);
}
else
pool->ZapAtom(ev, atom);
}
}
else
mSpace_Store->CannotAutoAssignAtomIdentityError(ev);
if ( mSpace_Store->mStore_CanAutoAssignAtomIdentity )
{
morkPool* pool = this->GetSpaceStorePool();
morkBookAtom* atom = pool->NewBookAtomCopy(ev, inAtom);
if ( atom )
{
mork_aid id = this->MakeNewAtomId(ev, atom);
if ( id )
{
outAtom = atom;
atom->mBookAtom_Space = this;
mAtomSpace_AtomAids.AddAtom(ev, atom);
mAtomSpace_AtomBodies.AddAtom(ev, atom);
if ( mSpace_Scope == morkAtomSpace_kColumnScope )
outAtom->MakeCellUseForever(ev);
}
else
pool->ZapAtom(ev, atom);
}
}
else
mSpace_Store->CannotAutoAssignAtomIdentityError(ev);
}
return outAtom;
}

Просмотреть файл

@ -235,6 +235,7 @@ void
morkBuilder::LogGlitch(morkEnv* ev, const morkGlitch& inGlitch,
const char* inKind)
{
MORK_USED_2(inGlitch,inKind);
ev->NewWarning("parsing glitch");
}
@ -256,6 +257,7 @@ morkBuilder::OnNewPort(morkEnv* ev, const morkPlace& inPlace)
// mp:PortItem ::= mp:Content | mp:Group | OnPortGlitch
// mp:Content ::= mp:PortRow | mp:Dict | mp:Table | mp:Row
{
MORK_USED_2(ev,inPlace);
// mParser_InPort = morkBool_kTrue;
mBuilder_PortForm = 0;
mBuilder_PortRowScope = (mork_scope) 'r';
@ -272,6 +274,7 @@ morkBuilder::OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch)
morkBuilder::OnPortEnd(morkEnv* ev, const morkSpan& inSpan)
// mp:Start ::= OnNewPort mp:PortItem* OnPortEnd
{
MORK_USED_2(ev,inSpan);
// ev->StubMethodOnlyError();
// nothing to do?
// mParser_InPort = morkBool_kFalse;
@ -280,6 +283,7 @@ morkBuilder::OnPortEnd(morkEnv* ev, const morkSpan& inSpan)
/*virtual*/ void
morkBuilder::OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid)
{
MORK_USED_2(inPlace,inGid);
// mParser_InGroup = morkBool_kTrue;
ev->StubMethodOnlyError();
}
@ -293,6 +297,7 @@ morkBuilder::OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch)
/*virtual*/ void
morkBuilder::OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan)
{
MORK_USED_1(inSpan);
// mParser_InGroup = morkBool_kFalse;
ev->StubMethodOnlyError();
}
@ -300,6 +305,7 @@ morkBuilder::OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan)
/*virtual*/ void
morkBuilder::OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan)
{
MORK_USED_1(inSpan);
// mParser_InGroup = morkBool_kFalse;
ev->StubMethodOnlyError();
}
@ -308,6 +314,7 @@ morkBuilder::OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan)
morkBuilder::OnNewPortRow(morkEnv* ev, const morkPlace& inPlace,
const morkMid& inMid, mork_change inChange)
{
MORK_USED_3(inMid,inPlace,inChange);
// mParser_InPortRow = morkBool_kTrue;
ev->StubMethodOnlyError();
}
@ -321,6 +328,7 @@ morkBuilder::OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch)
/*virtual*/ void
morkBuilder::OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan)
{
MORK_USED_1(inSpan);
// mParser_InPortRow = morkBool_kFalse;
ev->StubMethodOnlyError();
}
@ -334,6 +342,7 @@ morkBuilder::OnNewTable(morkEnv* ev, const morkPlace& inPlace,
// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
// mp:MetaItem ::= mp:Cell | OnMetaGlitch
{
MORK_USED_2(inPlace,inChange);
// mParser_InTable = morkBool_kTrue;
mBuilder_TableForm = mBuilder_PortForm;
mBuilder_TableRowScope = mBuilder_PortRowScope;
@ -355,6 +364,7 @@ morkBuilder::OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch)
morkBuilder::OnTableEnd(morkEnv* ev, const morkSpan& inSpan)
// mp:Table ::= OnNewTable mp:TableItem* OnTableEnd
{
MORK_USED_1(inSpan);
// mParser_InTable = morkBool_kFalse;
if ( mBuilder_Table )
{
@ -381,6 +391,7 @@ morkBuilder::OnNewMeta(morkEnv* ev, const morkPlace& inPlace)
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
{
MORK_USED_2(ev,inPlace);
// mParser_InMeta = morkBool_kTrue;
}
@ -395,6 +406,7 @@ morkBuilder::OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch)
morkBuilder::OnMetaEnd(morkEnv* ev, const morkSpan& inSpan)
// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
{
MORK_USED_2(ev,inSpan);
// mParser_InMeta = morkBool_kFalse;
}
@ -410,6 +422,7 @@ morkBuilder::OnNewRow(morkEnv* ev, const morkPlace& inPlace,
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
{
MORK_USED_2(inPlace,inChange);
// mParser_InRow = morkBool_kTrue;
if ( mBuilder_Table )
{
@ -485,6 +498,7 @@ morkBuilder::FlushBuilderCells(morkEnv* ev)
morkBuilder::OnRowEnd(morkEnv* ev, const morkSpan& inSpan)
// mp:Row ::= OnNewRow mp:RowItem* OnRowEnd
{
MORK_USED_1(inSpan);
// mParser_InRow = morkBool_kFalse;
if ( mBuilder_Row )
{
@ -502,6 +516,7 @@ morkBuilder::OnNewDict(morkEnv* ev, const morkPlace& inPlace)
// mp:Dict ::= OnNewDict mp:DictItem* OnDictEnd
// mp:DictItem ::= OnAlias | OnAliasGlitch | mp:Meta | OnDictGlitch
{
MORK_USED_2(ev,inPlace);
// mParser_InDict = morkBool_kTrue;
mBuilder_CellForm = mBuilder_DictForm = mBuilder_PortForm;
@ -518,6 +533,7 @@ morkBuilder::OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch)
morkBuilder::OnDictEnd(morkEnv* ev, const morkSpan& inSpan)
// mp:Dict ::= OnNewDict mp:DictItem* OnDictEnd
{
MORK_USED_2(ev,inSpan);
// mParser_InDict = morkBool_kFalse;
mBuilder_DictForm = 0;
@ -528,6 +544,7 @@ morkBuilder::OnDictEnd(morkEnv* ev, const morkSpan& inSpan)
morkBuilder::OnAlias(morkEnv* ev, const morkSpan& inSpan,
const morkMid& inMid)
{
MORK_USED_1(inSpan);
if ( mParser_InDict )
{
morkMid mid = inMid; // local copy for modification
@ -583,6 +600,7 @@ morkBuilder::OnNewCell(morkEnv* ev, const morkPlace& inPlace,
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
{
MORK_USED_1(inPlace);
// mParser_InCell = morkBool_kTrue;
mBuilder_CellAtomScope = mBuilder_RowAtomScope;
@ -699,6 +717,7 @@ morkBuilder::OnCellForm(morkEnv* ev, mork_cscode inCharsetFormat)
morkBuilder::OnCellEnd(morkEnv* ev, const morkSpan& inSpan)
// mp:Cell ::= OnNewCell mp:CellItem? OnCellEnd
{
MORK_USED_2(ev,inSpan);
// mParser_InCell = morkBool_kFalse;
mBuilder_MetaTokenSlot = 0;
@ -711,6 +730,7 @@ morkBuilder::OnValue(morkEnv* ev, const morkSpan& inSpan,
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
{
MORK_USED_1(inSpan);
morkStore* store = mBuilder_Store;
morkCell* cell = mBuilder_Cell;
if ( cell )
@ -751,6 +771,7 @@ morkBuilder::OnValueMid(morkEnv* ev, const morkSpan& inSpan,
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
{
MORK_USED_1(inSpan);
morkStore* store = mBuilder_Store;
morkCell* cell = mBuilder_Cell;
@ -779,7 +800,7 @@ morkBuilder::OnValueMid(morkEnv* ev, const morkSpan& inSpan,
mork_token* metaSlot = mBuilder_MetaTokenSlot;
if ( metaSlot )
{
mork_scope valScope = valOid->mOid_Scope;
mork_scope valScope = valOid->mOid_Scope;
if ( !valScope || valScope == morkStore_kColumnSpaceScope )
{
if ( ev->Good() && valMid.HasSomeId() )
@ -810,6 +831,7 @@ morkBuilder::OnRowMid(morkEnv* ev, const morkSpan& inSpan,
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
{
MORK_USED_1(inSpan);
morkStore* store = mBuilder_Store;
morkCell* cell = mBuilder_Cell;
if ( cell )
@ -846,6 +868,7 @@ morkBuilder::OnTableMid(morkEnv* ev, const morkSpan& inSpan,
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
{
MORK_USED_1(inSpan);
morkStore* store = mBuilder_Store;
morkCell* cell = mBuilder_Cell;
if ( cell )

Просмотреть файл

@ -57,12 +57,14 @@ morkCell::SetYarn(morkEnv* ev, const mdbYarn* inYarn, morkStore* ioStore)
void
morkCell::GetYarn(morkEnv* ev, mdbYarn* outYarn) const
{
MORK_USED_1(ev);
mCell_Atom->GetYarn(outYarn);
}
void
morkCell::AliasYarn(morkEnv* ev, mdbYarn* outYarn) const
{
MORK_USED_1(ev);
mCell_Atom->AliasYarn(outYarn);
}

Просмотреть файл

@ -156,7 +156,7 @@ morkCellObject::ResyncWithRow(morkEnv* ev)
morkCell* cell = row->GetCell(ev, mCellObject_Col, &pos);
if ( cell )
{
mCellObject_Pos = pos;
mCellObject_Pos = (mork_u2) pos;
mCellObject_Cell = cell;
mCellObject_RowSeed = row->mRow_Seed;
}

Просмотреть файл

@ -31,19 +31,19 @@
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
/* ----- ----- ----- ----- MORK_OBSOLETE ----- ----- ----- ----- */
#ifdef MORK_OBSOLETE
#if defined(MORK_OBSOLETE) || defined(MORK_ALONE)
#include <Types.h>
#include "plstr.h"
//#include "plstr.h"
static void // copied almost verbatim from the IronDoc debugger sources:
mork_mac_break_string(register const char* inMessage) /*i*/
{
Str255 pascalStr; // to hold Pascal string version of inMessage
mork_u4 length = PL_strlen(inMessage);
mork_u4 length = MORK_STRLEN(inMessage);
// if longer than maximum 255 bytes, just copy 255 bytes worth
pascalStr[ 0 ] = (length > 255)? 255 : length;
pascalStr[ 0 ] = (mork_u1) ((length > 255)? 255 : length);
if ( length ) // anything to copy? */
{
register mork_u1* p = ((mork_u1*) &pascalStr) + 1; // after length byte
@ -64,13 +64,15 @@
void mork_assertion_signal(const char* inMessage)
{
#ifdef MORK_OBSOLETE
#if defined(MORK_OBSOLETE) || defined(MORK_ALONE)
mork_mac_break_string(inMessage);
#endif /*MORK_OBSOLETE*/
#if defined(MORK_WIN) || defined(MORK_MAC)
// asm { int 3 }
#ifndef MORK_ALONE
NS_ASSERTION(0, inMessage);
#endif /*MORK_ALONE*/
#endif /*MORK_WIN*/
}

Просмотреть файл

@ -30,6 +30,10 @@
#endif
// { %%%%% begin platform defs peculiar to Mork %%%%%
//#define XP_MAC 1
//#define MORK_ALONE 1
#ifdef XP_MAC
#define MORK_MAC 1
#endif
@ -59,7 +63,10 @@
#include "errno.h"
#include "string.h"
#include "memory.h"
#ifndef MORK_ALONE
#include "nsDebug.h"
#endif /*MORK_ALONE*/
#define MORK_ISPRINT(c) isprint(c)

Просмотреть файл

@ -92,7 +92,7 @@ morkDeque::IndexOf(const morkLink* member) const /*i*/
{
++count;
if ( member == link )
return count;
return (mork_pos) count;
}
return 0;
}

Просмотреть файл

@ -185,15 +185,15 @@ morkEnv::OidAsHex(void* outBuf, const mdbOid& inOid)
mork_scope scope = inOid.mOid_Scope;
if ( scope < 0x80 && morkCh_IsName((mork_ch) scope) )
{
*p++ = (mork_u1) scope;
*p = 0; // null termination
outSize += 2;
*p++ = (mork_u1) scope;
*p = 0; // null termination
outSize += 2;
}
else
{
*p++ = '^';
mork_size scopeSize = this->TokenAsHex(p, scope);
outSize += scopeSize + 2;
*p++ = '^';
mork_size scopeSize = this->TokenAsHex(p, scope);
outSize += scopeSize + 2;
}
return outSize;
}
@ -205,20 +205,20 @@ morkEnv::HexToByte(mork_ch inFirstHex, mork_ch inSecondHex)
mork_u1 hi = 0; // high four hex bits
mork_flags f = morkCh_GetFlags(inFirstHex);
if ( morkFlags_IsDigit(f) )
hi = inFirstHex - '0';
hi = (mork_u1) (inFirstHex - (mork_ch) '0');
else if ( morkFlags_IsUpper(f) )
hi = (inFirstHex - 'A') + 10;
hi = (mork_u1) ((inFirstHex - (mork_ch) 'A') + 10);
else if ( morkFlags_IsLower(f) )
hi = (inFirstHex - 'a') + 10;
hi = (mork_u1) ((inFirstHex - (mork_ch) 'a') + 10);
mork_u1 lo = 0; // low four hex bits
f = morkCh_GetFlags(inSecondHex);
if ( morkFlags_IsDigit(f) )
lo = inSecondHex - '0';
lo = (mork_u1) (inSecondHex - (mork_ch) '0');
else if ( morkFlags_IsUpper(f) )
lo = (inSecondHex - 'A') + 10;
lo = (mork_u1) ((inSecondHex - (mork_ch) 'A') + 10);
else if ( morkFlags_IsLower(f) )
lo = (inSecondHex - 'a') + 10;
lo = (mork_u1) ((inSecondHex - (mork_ch) 'a') + 10);
return (mork_u1) ((hi << 4) | lo);
}
@ -240,7 +240,7 @@ morkEnv::TokenAsHex(void* outBuf, mork_token inToken)
}
*p = 0; // end the string with a null byte
char* s = (char*) outBuf; // first byte in string
mork_size size = p - s; // distance from start
mork_size size = (mork_size) (p - s); // distance from start
// now reverse the string in place:
// note that p starts on the null byte, so we need predecrement:
@ -311,7 +311,7 @@ morkEnv::NewErrorAndCode(const char* inString, mork_u2 inCode)
MORK_ASSERT(morkBool_kFalse); // get developer's attention
++mEnv_ErrorCount;
mEnv_ErrorCode = (inCode)? inCode: morkEnv_kGenericError;
mEnv_ErrorCode = (mork_u4) ((inCode)? inCode: morkEnv_kGenericError);
if ( mEnv_ErrorHook )
mEnv_ErrorHook->OnErrorString(this->AsMdbEnv(), inString);

Просмотреть файл

@ -373,6 +373,7 @@ morkStdioFile::AcquireBud(morkEnv* ev, nsIMdbHeap* ioHeap)
// behavior is exhibited by the file, so crashes protect old files.
// Note that AcquireBud() is an illegal operation on readonly files.
{
MORK_USED_1(ioHeap);
morkFile* outFile = 0;
if ( this->IsOpenAndActiveFile() )
{
@ -491,7 +492,7 @@ morkStdioFile::Read(morkEnv* ev, void* outBuf, mork_size inSize)
FILE* file = (FILE*) mStdioFile_File;
if ( file )
{
long count = MORK_FILEREAD(outBuf, inSize, file);
long count = (long) MORK_FILEREAD(outBuf, inSize, file);
if ( count >= 0 )
{
outCount = (mork_num) count;

Просмотреть файл

@ -132,10 +132,10 @@ public: // non-poly morkFile methods
mork_bool FileIoOpen() const { return mFile_IoOpen == 'O'; }
mork_bool FileActive() const { return mFile_Active == 'A'; }
void SetFileFrozen(mork_bool b) { mFile_Frozen = (b)? 'F' : 0; }
void SetFileDoTrace(mork_bool b) { mFile_DoTrace = (b)? 'T' : 0; }
void SetFileIoOpen(mork_bool b) { mFile_IoOpen = (b)? 'O' : 0; }
void SetFileActive(mork_bool b) { mFile_Active = (b)? 'A' : 0; }
void SetFileFrozen(mork_bool b) { mFile_Frozen = (mork_u1) ((b)? 'F' : 0); }
void SetFileDoTrace(mork_bool b) { mFile_DoTrace = (mork_u1) ((b)? 'T' : 0); }
void SetFileIoOpen(mork_bool b) { mFile_IoOpen = (mork_u1) ((b)? 'O' : 0); }
void SetFileActive(mork_bool b) { mFile_Active = (mork_u1) ((b)? 'A' : 0); }
mork_bool IsOpenActiveAndMutableFile() const

Просмотреть файл

@ -147,6 +147,7 @@ void morkHandle::NonOpenObjectError(morkEnv* ev) const
void morkHandle::NewBadMagicHandleError(morkEnv* ev, mork_magic inMagic) const
{
MORK_USED_1(inMagic);
ev->NewError("wrong mHandle_Magic");
}
@ -393,6 +394,7 @@ morkHandle::Handle_CloseMdbObject(nsIMdbEnv* mev)
/*virtual*/ mdb_err
morkHandle::Handle_IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen)
{
MORK_USED_1(mev);
mdb_err outErr = 0;
MORK_ASSERT(outOpen);

Просмотреть файл

@ -100,7 +100,7 @@ public: // morkHandle memory management operators
{ return ioPool.NewHandle(ev, inSize); }
void* operator new(size_t inSize, morkHandleFace* ioFace)
{ return ioFace; }
{ MORK_USED_1(inSize); return ioFace; }
void operator delete(void* ioAddress)
{ morkNode::OnDeleteAssert(ioAddress); }

Просмотреть файл

@ -97,12 +97,14 @@ morkIntMap::CloseIntMap(morkEnv* ev) // called by CloseMorkNode();
/*virtual*/ mork_bool // *((mork_u4*) inKeyA) == *((mork_u4*) inKeyB)
morkIntMap::Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const
{
MORK_USED_1(ev);
return *((const mork_u4*) inKeyA) == *((const mork_u4*) inKeyB);
}
/*virtual*/ mork_u4 // some integer function of *((mork_u4*) inKey)
morkIntMap::Hash(morkEnv* ev, const void* inKey) const
{
MORK_USED_1(ev);
return *((const mork_u4*) inKey);
}
// } ===== end morkMap poly interface =====
@ -145,4 +147,115 @@ morkIntMap::HasInt(morkEnv* ev, mork_u4 inKey)
(mork_change**) 0);
}
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#ifdef MORK_POINTER_MAP_IMPL
// ````` ````` ````` ````` `````
// { ===== begin morkNode interface =====
/*public virtual*/ void
morkPointerMap::CloseMorkNode(morkEnv* ev) // ClosePointerMap() only if open
{
if ( this->IsOpenNode() )
{
this->MarkClosing();
this->ClosePointerMap(ev);
this->MarkShut();
}
}
/*public virtual*/
morkPointerMap::~morkPointerMap() // assert ClosePointerMap() executed earlier
{
MORK_ASSERT(this->IsShutNode());
}
/*public non-poly*/
morkPointerMap::morkPointerMap(morkEnv* ev,
const morkUsage& inUsage, nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
: morkMap(ev, inUsage, ioHeap, sizeof(void*), sizeof(void*),
morkPointerMap_kStartSlotCount, ioSlotHeap,
/*inHoldChanges*/ morkBool_kFalse)
{
if ( ev->Good() )
mNode_Derived = morkDerived_kPointerMap;
}
/*public non-poly*/ void
morkPointerMap::ClosePointerMap(morkEnv* ev) // called by CloseMorkNode();
{
if ( this )
{
if ( this->IsNode() )
{
this->CloseMap(ev);
this->MarkShut();
}
else
this->NonNodeError(ev);
}
else
ev->NilPointerError();
}
// } ===== end morkNode methods =====
// ````` ````` ````` ````` `````
// { ===== begin morkMap poly interface =====
/*virtual*/ mork_bool // *((void**) inKeyA) == *((void**) inKeyB)
morkPointerMap::Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const
{
MORK_USED_1(ev);
return *((const void**) inKeyA) == *((const void**) inKeyB);
}
/*virtual*/ mork_u4 // some integer function of *((mork_u4*) inKey)
morkPointerMap::Hash(morkEnv* ev, const void* inKey) const
{
MORK_USED_1(ev);
return *((const mork_u4*) inKey);
}
// } ===== end morkMap poly interface =====
mork_bool
morkPointerMap::AddPointer(morkEnv* ev, void* inKey, void* ioAddress)
// the AddPointer() method return value equals ev->Good().
{
if ( ev->Good() )
{
this->Put(ev, &inKey, &ioAddress,
/*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0);
}
return ev->Good();
}
mork_bool
morkPointerMap::CutPointer(morkEnv* ev, void* inKey)
{
return this->Cut(ev, &inKey, /*key*/ (void*) 0, /*val*/ (void*) 0,
(mork_change**) 0);
}
void*
morkPointerMap::GetPointer(morkEnv* ev, void* inKey)
// Note the returned val does NOT have an increase in refcount for this.
{
void* val = 0; // old val in the map
this->Get(ev, &inKey, /*key*/ (void*) 0, &val, (mork_change**) 0);
return val;
}
mork_bool
morkPointerMap::HasPointer(morkEnv* ev, void* inKey)
// Note the returned val does NOT have an increase in refcount for this.
{
return this->Get(ev, &inKey, /*key*/ (void*) 0, /*val*/ (void*) 0,
(mork_change**) 0);
}
#endif /*MORK_POINTER_MAP_IMPL*/
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

Просмотреть файл

@ -35,7 +35,7 @@
#define morkDerived_kIntMap /*i*/ 0x694D /* ascii 'iM' */
#define morkIntMap_kStartSlotCount 512
#define morkIntMap_kStartSlotCount 256
/*| morkIntMap: maps mork_token -> morkNode
|*/
@ -71,10 +71,10 @@ public: // other map methods
mork_bool AddInt(morkEnv* ev, mork_u4 inKey, void* ioAddress);
// the AddInt() boolean return equals ev->Good().
mork_bool CutInt(morkEnv* ev, mork_token inKey);
mork_bool CutInt(morkEnv* ev, mork_u4 inKey);
// The CutInt() boolean return indicates whether removal happened.
void* GetInt(morkEnv* ev, mork_token inKey);
void* GetInt(morkEnv* ev, mork_u4 inKey);
// Note the returned node does NOT have an increase in refcount for this.
mork_bool HasInt(morkEnv* ev, mork_u4 inKey);
@ -82,6 +82,77 @@ public: // other map methods
};
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#ifdef MORK_POINTER_MAP_IMPL
#define morkDerived_kPointerMap /*i*/ 0x704D /* ascii 'pM' */
#define morkPointerMap_kStartSlotCount 256
/*| morkPointerMap: maps void* -> void*
**|
**| This pointer map class is equivalent to morkIntMap when sizeof(mork_u4)
**| equals sizeof(void*). However, when these two sizes are different,
**| then we cannot use the same hash table structure very easily without
**| being very careful about the size and usage assumptions of those
**| clients using the smaller data type. So we just go ahead and use
**| morkPointerMap for hash tables using pointer key types.
|*/
class morkPointerMap : public morkMap { // for mapping tokens to maps
// { ===== begin morkNode interface =====
public: // morkNode virtual methods
virtual void CloseMorkNode(morkEnv* ev); // ClosePointerMap() only if open
virtual ~morkPointerMap(); // assert that ClosePointerMap() executed earlier
public: // morkMap construction & destruction
// keySize for morkPointerMap equals sizeof(mork_u4)
morkPointerMap(morkEnv* ev, const morkUsage& inUsage,
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap);
void ClosePointerMap(morkEnv* ev); // called by CloseMorkNode();
public: // dynamic type identification
mork_bool IsPointerMap() const
{ return IsNode() && mNode_Derived == morkDerived_kPointerMap; }
// } ===== end morkNode methods =====
// { ===== begin morkMap poly interface =====
virtual mork_bool // *((void**) inKeyA) == *((void**) inKeyB)
Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const;
virtual mork_u4 // some integer function of *((mork_u4*) inKey)
Hash(morkEnv* ev, const void* inKey) const;
// } ===== end morkMap poly interface =====
public: // other map methods
mork_bool AddPointer(morkEnv* ev, void* inKey, void* ioAddress);
// the AddPointer() boolean return equals ev->Good().
mork_bool CutPointer(morkEnv* ev, void* inKey);
// The CutPointer() boolean return indicates whether removal happened.
void* GetPointer(morkEnv* ev, void* inKey);
// Note the returned node does NOT have an increase in refcount for this.
mork_bool HasPointer(morkEnv* ev, void* inKey);
// Note the returned node does NOT have an increase in refcount for this.
public: // typesafe refcounting inlines calling inherited morkNode methods
static void SlotWeakIntMap(morkIntMap* me,
morkEnv* ev, morkIntMap** ioSlot)
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
static void SlotStrongIntMap(morkIntMap* me,
morkEnv* ev, morkIntMap** ioSlot)
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
};
#endif /*MORK_POINTER_MAP_IMPL*/
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#endif /* _MORKINTMAP_ */

Просмотреть файл

@ -636,6 +636,9 @@ morkMap::Cut(morkEnv* ev, const void* inKey,
outCut = morkBool_kTrue;
morkAssoc* assoc = *ref;
mork_pos i = assoc - mMap_Assocs; /* index of assoc */
if ( outKey || outVal )
this->get_assoc(outKey, outVal, i);
*ref = assoc->mAssoc_Next; /* unlink the found assoc */
this->push_free_assoc(assoc); /* and put it in free list */
@ -747,6 +750,7 @@ morkMapIter::morkMapIter(morkEnv* ev, morkMap* ioMap)
void
morkMapIter::CloseMapIter(morkEnv* ev)
{
MORK_USED_1(ev);
mMapIter_Map = 0;
mMapIter_Seed = 0;

Просмотреть файл

@ -368,13 +368,16 @@ morkNode::SlotStrongNode(morkNode* me, morkEnv* ev, morkNode** ioSlot)
// expression 'morkNode::SlotStrongNode((morkNode*) 0, ev, &slot)'.
{
morkNode* node = *ioSlot;
if ( node )
if ( me != node )
{
*ioSlot = 0;
node->CutStrongRef(ev);
if ( node )
{
*ioSlot = 0;
node->CutStrongRef(ev);
}
if ( me && me->AddStrongRef(ev) )
*ioSlot = me;
}
if ( me && me->AddStrongRef(ev) )
*ioSlot = me;
}
/*public static*/ void
@ -386,13 +389,16 @@ morkNode::SlotWeakNode(morkNode* me, morkEnv* ev, morkNode** ioSlot)
// expression 'morkNode::SlotWeakNode((morkNode*) 0, ev, &slot)'.
{
morkNode* node = *ioSlot;
if ( node )
if ( me != node )
{
*ioSlot = 0;
node->CutWeakRef(ev);
if ( node )
{
*ioSlot = 0;
node->CutWeakRef(ev);
}
if ( me && me->AddWeakRef(ev) )
*ioSlot = me;
}
if ( me && me->AddWeakRef(ev) )
*ioSlot = me;
}
/*public non-poly*/ mork_uses

Просмотреть файл

@ -198,7 +198,7 @@ public: // other morkNode methods
mork_bool BadRefs() const { return mNode_Refs < mNode_Uses; }
mork_uses StrongRefsOnly() const { return mNode_Uses; }
mork_refs WeakRefsOnly() const { return ( mNode_Refs - mNode_Uses ); }
mork_refs WeakRefsOnly() const { return (mork_refs) ( mNode_Refs - mNode_Uses ); }
// (this refcounting derives from public domain IronDoc node refcounts)
mork_refs AddStrongRef(morkEnv* ev);

Просмотреть файл

@ -211,6 +211,7 @@ morkParser::NonUsableParserError(morkEnv* ev) //
/*protected non-poly*/ void
morkParser::StartParse(morkEnv* ev)
{
MORK_USED_1(ev);
mParser_InCell = morkBool_kFalse;
mParser_InMeta = morkBool_kFalse;
mParser_InDict = morkBool_kFalse;
@ -792,6 +793,7 @@ morkParser::EofInsteadOfHexError(morkEnv* ev)
/*static*/ void
morkParser::ExpectedHexDigitError(morkEnv* ev, int c)
{
MORK_USED_1(c);
ev->NewWarning("expected hex digit");
}
@ -969,6 +971,45 @@ morkParser::NonParserTypeError(morkEnv* ev)
ev->NewError("non morkParser");
}
mork_bool morkParser::MatchPattern(morkEnv* ev, const char* inPattern)
{
// if an error occurs, we want original inPattern in the debugger:
const char* pattern = inPattern; // mutable copy
morkStream* s = mParser_Stream;
register int c;
while ( *inPattern && ev->Good() )
{
char byte = *pattern++;
if ( (c = s->Getc(ev)) != byte )
{
ev->NewError("byte not in expected pattern");
}
}
return ev->Good();
}
void morkParser::ReadGroup(morkEnv* ev)
/* groups must be ignored until properly terminated */
// zm:Group ::= zm:GroupStart zm:Content zm:GroupEnd /* transaction */
// zm:GroupStart ::= zm:S? '@$${' zm:Id '{@' /* transaction id has own space */
// zm:GroupEnd ::= zm:GroupCommit | zm:GroupAbort
// zm:GroupCommit ::= zm:S? '@$$}' zm:Id '}@' /* id matches start id */
// zm:GroupAbort ::= zm:S? '@$$}~~' zm:Id '}@' /* id matches start id */
/* We must allow started transactions to be aborted in summary files. */
/* Note '$$' will never occur unescaped in values we will see in Mork. */
{
if ( this->MatchPattern(ev, "$${") )
{
//morkMid cellMid = &mParser_CellMid;
//if ( this->ReadMid(ev, cellMid) )
//{
// if ( this->MatchPattern(ev, "}@") )
// {
// }
//}
}
}
void morkParser::ReadDict(morkEnv* ev)
// zm:Dict ::= zm:S? '<' zm:DictItem* zm:S? '>'
// zm:DictItem ::= zm:MetaDict | zm:Alias
@ -1060,6 +1101,10 @@ morkParser::OnPortState(morkEnv* ev)
this->ReadDict(ev);
break;
case '@': // group
this->ReadGroup(ev);
break;
case '+': // plus
mParser_Change = morkChange_kAdd;
break;
@ -1181,7 +1226,7 @@ morkParser::ParseMore( // return count of bytes consumed now
*outPos = endPos;
if ( endPos > startPos )
outCount = endPos - startPos;
outCount = (mdb_count) (endPos - startPos);
}
else
{

Просмотреть файл

@ -476,6 +476,7 @@ protected: // protected parser helper methods
void ReadTable(morkEnv* ev);
void ReadTableMeta(morkEnv* ev);
void ReadDict(morkEnv* ev);
void ReadGroup(morkEnv* ev);
void ReadMeta(morkEnv* ev, int inEndMeta);
void ReadAlias(morkEnv* ev);
mork_id ReadHex(morkEnv* ev, int* outNextChar);
@ -483,6 +484,8 @@ protected: // protected parser helper methods
morkBuf* ReadName(morkEnv* ev, int c);
mork_bool ReadMid(morkEnv* ev, morkMid* outMid);
mork_bool MatchPattern(morkEnv* ev, const char* inPattern);
void EndSpanOnThisByte(morkEnv* ev, morkSpan* ioSpan);
void StartSpanOnLastByte(morkEnv* ev, morkSpan* ioSpan);

Просмотреть файл

@ -189,6 +189,7 @@ morkPool::NewCells(morkEnv* ev, mork_size inSize)
void
morkPool::ZapCells(morkEnv* ev, morkCell* ioVector, mork_size inSize)
{
MORK_USED_1(inSize);
if ( ioVector )
mPool_Heap->Free(ev->AsMdbEnv(), ioVector);
}
@ -214,7 +215,7 @@ morkPool::AddRowCells(morkEnv* ev, morkRow* ioRow, mork_size inNewSize)
}
oldCells = ioRow->mRow_Cells;
ioRow->mRow_Cells = newCells;
ioRow->mRow_Length = inNewSize;
ioRow->mRow_Length = (mork_u2) inNewSize;
++ioRow->mRow_Seed;
if ( oldCells )
@ -251,7 +252,7 @@ morkPool::CutRowCells(morkEnv* ev, morkRow* ioRow,
}
oldCells = ioRow->mRow_Cells;
ioRow->mRow_Cells = newCells;
ioRow->mRow_Length = inNewSize;
ioRow->mRow_Length = (mork_u2) inNewSize;
++ioRow->mRow_Seed;
if ( oldCells )

Просмотреть файл

@ -86,7 +86,7 @@ morkPortTableCursor::morkPortTableCursor(morkEnv* ev,
{
if ( ev->Good() )
{
if ( ioStore )
if ( ioStore && ioSlotHeap )
{
mCursor_Pos = -1;
mCursor_Seed = 0; // let the iterator do it's own seed handling

Просмотреть файл

@ -69,8 +69,13 @@
mork_u2
morkRow::AddTableUse(morkEnv* ev)
{
if ( mRow_TableUses < morkRow_kMaxTableUses ) // not already maxed out?
++mRow_TableUses;
if ( this->IsRow() )
{
if ( mRow_TableUses < morkRow_kMaxTableUses ) // not already maxed out?
++mRow_TableUses;
}
else
this->NonRowTypeError(ev);
return mRow_TableUses;
}
@ -78,13 +83,18 @@ morkRow::AddTableUse(morkEnv* ev)
mork_u2
morkRow::CutTableUse(morkEnv* ev)
{
if ( mRow_TableUses ) // any outstanding uses to cut?
if ( this->IsRow() )
{
if ( mRow_TableUses < morkRow_kMaxTableUses ) // not frozen at max?
--mRow_TableUses;
if ( mRow_TableUses ) // any outstanding uses to cut?
{
if ( mRow_TableUses < morkRow_kMaxTableUses ) // not frozen at max?
--mRow_TableUses;
}
else
this->TableUsesUnderflowWarning(ev);
}
else
this->TableUsesUnderflowWarning(ev);
this->NonRowTypeError(ev);
return mRow_TableUses;
}
@ -142,7 +152,7 @@ morkRow::InitRow(morkEnv* ev, const mdbOid* inOid, morkRowSpace* ioSpace,
mRow_Cells = 0;
mRow_Oid = *inOid;
mRow_Length = inLength;
mRow_Length = (mork_u2) inLength;
mRow_Seed = (mork_u2) this; // "random" assignment
mRow_TableUses = 0;
@ -300,7 +310,7 @@ morkRow::TakeCells(morkEnv* ev, morkCell* ioVector, mork_fill inVecLength,
if ( ioVector && inVecLength && ev->Good() )
{
++mRow_Seed; // intend to change structure of mRow_Cells
mork_pos length = (mork_pos) mRow_Length;
mork_size length = (mork_size) mRow_Length;
mork_count overlap = this->CountOverlap(ev, ioVector, inVecLength);
@ -328,8 +338,8 @@ morkRow::NewCell(morkEnv* ev, mdb_column inColumn,
mork_pos* outPos, morkStore* ioStore)
{
++mRow_Seed; // intend to change structure of mRow_Cells
mork_pos length = (mork_pos) mRow_Length;
*outPos = length;
mork_size length = (mork_size) mRow_Length;
*outPos = (mork_pos) length;
morkPool* pool = ioStore->StorePool();
if ( pool->AddRowCells(ev, this, length + 1) )
{
@ -344,6 +354,7 @@ morkRow::NewCell(morkEnv* ev, mdb_column inColumn,
morkCell*
morkRow::CellAt(morkEnv* ev, mork_pos inPos) const
{
MORK_USED_1(ev);
morkCell* cells = mRow_Cells;
if ( cells && inPos < mRow_Length && inPos >= 0 )
{
@ -355,6 +366,7 @@ morkRow::CellAt(morkEnv* ev, mork_pos inPos) const
morkCell*
morkRow::GetCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos) const
{
MORK_USED_1(ev);
morkCell* cells = mRow_Cells;
if ( cells )
{
@ -375,6 +387,42 @@ morkRow::GetCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos) const
return (morkCell*) 0;
}
mork_aid
morkRow::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.
{
if ( this && this->IsRow() )
{
morkCell* cells = mRow_Cells;
if ( cells )
{
morkCell* end = cells + mRow_Length;
while ( cells < end )
{
mork_column col = cells->GetColumn();
if ( col == inColumn ) // found desired column?
{
morkAtom* atom = cells->mCell_Atom;
if ( atom && atom->IsBook() )
return ((morkBookAtom*) atom)->mBookAtom_Id;
else
return 0;
}
else
++cells;
}
}
}
else
this->NonRowTypeError(ev);
return 0;
}
void
morkRow::EmptyAllCells(morkEnv* ev)
{
@ -396,12 +444,46 @@ morkRow::EmptyAllCells(morkEnv* ev)
}
}
void
morkRow::cut_all_index_entries(morkEnv* ev)
{
morkRowSpace* rowSpace = mRow_Space;
if ( rowSpace->mRowSpace_IndexCount ) // any indexes?
{
morkCell* cells = mRow_Cells;
if ( cells )
{
morkCell* end = cells + mRow_Length;
--cells; // prepare for preincrement:
while ( ++cells < end )
{
morkAtom* atom = cells->mCell_Atom;
if ( atom )
{
mork_aid atomAid = atom->GetBookAtomAid();
if ( atomAid )
{
mork_column col = cells->GetColumn();
morkAtomRowMap* map = rowSpace->FindMap(ev, col);
if ( map ) // cut row from index for this column?
map->CutAid(ev, atomAid);
}
}
}
}
}
}
void
morkRow::CutAllColumns(morkEnv* ev)
{
morkStore* store = this->GetRowSpaceStore(ev);
if ( store )
{
morkRowSpace* rowSpace = mRow_Space;
if ( rowSpace->mRowSpace_IndexCount ) // any indexes?
this->cut_all_index_entries(ev);
morkPool* pool = store->StorePool();
pool->CutRowCells(ev, this, /*newSize*/ 0);
}
@ -415,6 +497,9 @@ morkRow::SetRow(morkEnv* ev, const morkRow* inSourceRow)
morkStore* srcStore = inSourceRow->GetRowSpaceStore(ev);
if ( store && srcStore )
{
morkRowSpace* rowSpace = mRow_Space;
mork_count indexes = rowSpace->mRowSpace_IndexCount; // any indexes?
mork_bool sameStore = ( store == srcStore ); // identical stores?
morkPool* pool = store->StorePool();
if ( pool->CutRowCells(ev, this, /*newSize*/ 0) )
@ -432,17 +517,17 @@ morkRow::SetRow(morkEnv* ev, const morkRow* inSourceRow)
while ( ++dst < dstEnd && ++src < srcEnd && ev->Good() )
{
morkAtom* atom = src->mCell_Atom;
mork_column col = src->GetColumn();
mork_column dstCol = src->GetColumn();
if ( sameStore ) // source and dest in same store?
{
dst->SetColumnAndChange(col, morkChange_kAdd);
dst->SetColumnAndChange(dstCol, morkChange_kAdd);
dst->mCell_Atom = atom;
if ( atom ) // another ref to non-nil atom?
atom->AddCellUse(ev);
}
else // need to dup items from src store in a dest store
{
mork_column dstCol = store->CopyToken(ev, col, srcStore);
dstCol = store->CopyToken(ev, dstCol, srcStore);
if ( dstCol )
{
dst->SetColumnAndChange(dstCol, morkChange_kAdd);
@ -452,6 +537,16 @@ morkRow::SetRow(morkEnv* ev, const morkRow* inSourceRow)
atom->AddCellUse(ev);
}
}
if ( indexes && atom )
{
mork_aid atomAid = atom->GetBookAtomAid();
if ( atomAid )
{
morkAtomRowMap* map = rowSpace->FindMap(ev, dstCol);
if ( map )
map->AddAid(ev, atomAid, this);
}
}
}
}
}
@ -473,12 +568,14 @@ void
morkRow::OnZeroTableUse(morkEnv* ev)
// OnZeroTableUse() is called when CutTableUse() returns zero.
{
MORK_USED_1(ev);
// ev->NewWarning("need to implement OnZeroTableUse");
}
void
morkRow::DirtyAllRowContent(morkEnv* ev)
{
MORK_USED_1(ev);
this->SetRowDirty();
morkCell* cells = mRow_Cells;
@ -527,6 +624,20 @@ void morkRow::CutColumn(morkEnv* ev, mdb_column inColumn)
morkStore* store = this->GetRowSpaceStore(ev);
if ( store )
{
morkRowSpace* rowSpace = mRow_Space;
morkAtomRowMap* map = ( rowSpace->mRowSpace_IndexCount )?
rowSpace->FindMap(ev, inColumn) : (morkAtomRowMap*) 0;
if ( map ) // this row attribute is indexed by row space?
{
morkAtom* oldAtom = cell->mCell_Atom;
if ( oldAtom ) // need to cut an entry from the index?
{
mork_aid oldAid = oldAtom->GetBookAtomAid();
if ( oldAid ) // cut old row attribute from row index in space?
map->CutAid(ev, oldAid);
}
}
morkPool* pool = store->StorePool();
cell->SetAtom(ev, (morkAtom*) 0, pool);
@ -553,6 +664,25 @@ void morkRow::CutColumn(morkEnv* ev, mdb_column inColumn)
}
}
// void morkRow::cut_cell_from_space_index(morkEnv* ev, morkCell* ioCell)
// {
// morkAtom* oldAtom = ioCell->mCell_Atom;
// if ( oldAtom )
// {
// mork_column col = ioCell->GetColumn();
// morkRowSpace* rowSpace = mRow_Space;
// morkAtomRowMap* map = ( rowSpace->mRowSpace_IndexCount )?
// rowSpace->FindMap(ev, col) : (morkAtomRowMap*) 0;
//
// if ( map ) // col is indexed by row space?
// {
// mork_aid oldAid = oldAtom->GetBookAtomAid();
// if ( oldAid ) // cut old row attribute from row index in space?
// map->CutAid(ev, oldAid);
// }
// }
// }
void morkRow::AddColumn(morkEnv* ev, mdb_column inColumn,
const mdbYarn* inYarn, morkStore* ioStore)
{
@ -570,7 +700,31 @@ void morkRow::AddColumn(morkEnv* ev, mdb_column inColumn,
// cell->SetYarn(ev, inYarn, ioStore);
morkAtom* atom = ioStore->YarnToAtom(ev, inYarn);
if ( atom )
{
morkRowSpace* rowSpace = mRow_Space;
morkAtomRowMap* map = ( rowSpace->mRowSpace_IndexCount )?
rowSpace->FindMap(ev, inColumn) : (morkAtomRowMap*) 0;
if ( map ) // inColumn is indexed by row space?
{
morkAtom* oldAtom = cell->mCell_Atom;
if ( oldAtom && oldAtom != atom ) // cut old cell from index?
{
mork_aid oldAid = oldAtom->GetBookAtomAid();
if ( oldAid ) // cut old row attribute from row index in space?
map->CutAid(ev, oldAid);
}
}
cell->SetAtom(ev, atom, ioStore->StorePool()); // refcounts atom
if ( map ) // inColumn is indexed by row space?
{
mork_aid newAid = atom->GetBookAtomAid();
if ( newAid ) // add new row attribute to row index in space?
map->AddAid(ev, newAid, this);
}
}
}
}
}

Просмотреть файл

@ -74,6 +74,10 @@ public: // other row methods
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
@ -100,6 +104,13 @@ public: // internal row methods
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);
@ -132,7 +143,7 @@ public: // hash and equal
return (mRow_Oid.mOid_Scope << 16) ^ mRow_Oid.mOid_Id;
}
mork_u4 EqualRow(const morkRow* ioRow) const
mork_bool EqualRow(const morkRow* ioRow) const
{
return
(
@ -141,7 +152,7 @@ public: // hash and equal
);
}
mork_u4 EqualOid(const mdbOid* ioOid) const
mork_bool EqualOid(const mdbOid* ioOid) const
{
return
(

Просмотреть файл

@ -103,12 +103,14 @@ morkRowMap::CloseRowMap(morkEnv* ev) // called by CloseMorkNode();
morkRowMap::Equal(morkEnv* ev, const void* inKeyA,
const void* inKeyB) const
{
MORK_USED_1(ev);
return (*(const morkRow**) inKeyA)->EqualRow(*(const morkRow**) inKeyB);
}
/*virtual*/ mork_u4 //
morkRowMap::Hash(morkEnv* ev, const void* inKey) const
{
MORK_USED_1(ev);
return (*(const morkRow**) inKey)->HashRow();
}
// } ===== end morkMap poly interface =====

Просмотреть файл

@ -68,6 +68,10 @@
#include "morkRow.h"
#endif
#ifndef _MORKATOMMAP_
#include "morkAtomMap.h"
#endif
#ifndef _MORKROWOBJECT_
#include "morkRowObject.h"
#endif
@ -99,14 +103,29 @@ morkRowSpace::morkRowSpace(morkEnv* ev,
const morkUsage& inUsage, mork_scope inScope, morkStore* ioStore,
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
: morkSpace(ev, inUsage, inScope, ioStore, ioHeap, ioSlotHeap)
, mRowSpace_SlotHeap( ioSlotHeap )
, mRowSpace_Rows(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap,
morkRowSpace_kStartRowMapSlotCount)
, mRowSpace_Tables(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap)
, mRowSpace_NextTableId( 1 )
, mRowSpace_NextRowId( 1 )
, mRowSpace_IndexCount( 0 )
{
morkAtomRowMap** cache = mRowSpace_IndexCache;
morkAtomRowMap** cacheEnd = cache + morkRowSpace_kPrimeCacheSize;
while ( cache < cacheEnd )
*cache++ = 0; // put nil into every slot of cache table
if ( ev->Good() )
mNode_Derived = morkDerived_kRowSpace;
{
if ( ioSlotHeap )
{
mNode_Derived = morkDerived_kRowSpace;
}
else
ev->NilPointerError();
}
}
/*public non-poly*/ void
@ -116,11 +135,20 @@ morkRowSpace::CloseRowSpace(morkEnv* ev) // called by CloseMorkNode();
{
if ( this->IsNode() )
{
morkAtomRowMap** cache = mRowSpace_IndexCache;
morkAtomRowMap** cacheEnd = cache + morkRowSpace_kPrimeCacheSize;
--cache; // prepare for preincrement:
while ( ++cache < cacheEnd )
{
if ( *cache )
morkAtomRowMap::SlotStrongAtomRowMap(0, ev, cache);
}
mRowSpace_Tables.CloseMorkNode(ev);
morkStore* store = mSpace_Store;
if ( store )
this->CutAllRows(ev, &store->mStore_Pool);
this->CutAllRows(ev, &store->mStore_Pool);
mRowSpace_Rows.CloseMorkNode(ev);
this->CloseSpace(ev);
@ -187,18 +215,22 @@ morkRowSpace::CutAllRows(morkEnv* ev, morkPool* ioPool)
for ( c = i.FirstRow(ev, &r); c && ev->Good();
c = i.NextRow(ev, &r) )
{
if ( r->IsRow() )
if ( r )
{
if ( r->mRow_Object )
if ( r->IsRow() )
{
morkRowObject::SlotWeakRowObject((morkRowObject*) 0, ev,
&r->mRow_Object);
}
if ( r )
if ( r->mRow_Object )
{
morkRowObject::SlotWeakRowObject((morkRowObject*) 0, ev,
&r->mRow_Object);
}
ioPool->ZapRow(ev, r);
}
else
r->NonRowTypeWarning(ev);
}
else
r->NonRowTypeWarning(ev);
ev->NilPointerError();
i.CutHereRow(ev, /*key*/ (morkRow**) 0);
}
@ -346,6 +378,136 @@ morkRowSpace::MakeNewRowId(morkEnv* ev)
return outRid;
}
morkAtomRowMap*
morkRowSpace::make_index(morkEnv* ev, mork_column inCol)
{
morkAtomRowMap* outMap = 0;
nsIMdbHeap* heap = mRowSpace_SlotHeap;
if ( heap ) // have expected heap for allocations?
{
morkAtomRowMap* map = new(*heap, ev)
morkAtomRowMap(ev, morkUsage::kHeap, heap, heap, inCol);
if ( map ) // able to create new map index?
{
if ( ev->Good() ) // no errors during construction?
{
morkRowMapIter i(ev, &mRowSpace_Rows);
mork_change* c = 0;
morkRow* row = 0;
mork_aid aidKey = 0;
for ( c = i.FirstRow(ev, &row); c && ev->Good();
c = i.NextRow(ev, &row) ) // another row in space?
{
aidKey = row->GetCellAtomAid(ev, inCol);
if ( aidKey ) // row has indexed attribute?
map->AddAid(ev, aidKey, row); // include in map
}
}
if ( ev->Good() ) // no errors constructing index?
outMap = map; // return from function
else
map->CutStrongRef(ev); // discard map on error
}
}
else
ev->NilPointerError();
return outMap;
}
morkAtomRowMap*
morkRowSpace::ForceMap(morkEnv* ev, mork_column inCol)
{
morkAtomRowMap* outMap = this->FindMap(ev, inCol);
if ( !outMap && ev->Good() ) // no such existing index?
{
if ( mRowSpace_IndexCount < morkRowSpace_kMaxIndexCount )
{
morkAtomRowMap* map = this->make_index(ev, inCol);
if ( map ) // created a new index for col?
{
mork_count wrap = 0; // count times wrap-around occurs
morkAtomRowMap** slot = mRowSpace_IndexCache; // table
morkAtomRowMap** end = slot + morkRowSpace_kPrimeCacheSize;
slot += ( inCol % morkRowSpace_kPrimeCacheSize ); // hash
while ( *slot ) // empty slot not yet found?
{
if ( ++slot >= end ) // wrap around?
{
slot = mRowSpace_IndexCache; // back to table start
if ( ++wrap > 1 ) // wrapped more than once?
{
ev->NewError("no free cache slots"); // disaster
break; // end while loop
}
}
}
if ( ev->Good() ) // everything went just fine?
{
++mRowSpace_IndexCount; // note another new map
*slot = map; // install map in the hash table
outMap = map; // return the new map from function
}
else
map->CutStrongRef(ev); // discard map on error
}
}
else
ev->NewError("too many indexes"); // why so many indexes?
}
return outMap;
}
morkAtomRowMap*
morkRowSpace::FindMap(morkEnv* ev, mork_column inCol)
{
if ( mRowSpace_IndexCount && ev->Good() )
{
mork_count wrap = 0; // count times wrap-around occurs
morkAtomRowMap** slot = mRowSpace_IndexCache; // table
morkAtomRowMap** end = slot + morkRowSpace_kPrimeCacheSize;
slot += ( inCol % morkRowSpace_kPrimeCacheSize ); // hash
morkAtomRowMap* map = *slot;
while ( map ) // another used slot to examine?
{
if ( inCol == map->mAtomRowMap_IndexColumn ) // found col?
return map;
if ( ++slot >= end ) // wrap around?
{
slot = mRowSpace_IndexCache;
if ( ++wrap > 1 ) // wrapped more than once?
return (morkAtomRowMap*) 0; // stop searching
}
map = *slot;
}
}
return (morkAtomRowMap*) 0;
}
morkRow*
morkRowSpace::FindRow(morkEnv* ev, mork_column inCol, const mdbYarn* inYarn)
{
morkRow* outRow = 0;
morkAtom* atom = mSpace_Store->YarnToAtom(ev, inYarn);
if ( atom ) // have or created an atom corresponding to input yarn?
{
mork_aid atomAid = atom->GetBookAtomAid();
if ( atomAid ) // atom has an identity for use in hash table?
{
morkAtomRowMap* map = this->ForceMap(ev, inCol);
if ( map ) // able to find or create index for col?
{
outRow = map->GetAid(ev, atomAid); // search for row
}
}
}
return outRow;
}
morkRow*
morkRowSpace::NewRowWithOid(morkEnv* ev, const mdbOid* inOid)

Просмотреть файл

@ -43,12 +43,21 @@
#include "morkTable.h"
#endif
#ifndef _MORKARRAY_
#include "morkArray.h"
#endif
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#define morkDerived_kRowSpace /*i*/ 0x7253 /* ascii 'rS' */
#define morkRowSpace_kStartRowMapSlotCount 512
#define morkRowSpace_kMaxIndexCount 8 /* no more indexes than this */
#define morkRowSpace_kPrimeCacheSize 17 /* should be prime number */
class morkAtomRowMap;
/*| morkRowSpace:
|*/
class morkRowSpace : public morkSpace { //
@ -76,11 +85,18 @@ class morkRowSpace : public morkSpace { //
public: // state is public because the entire Mork system is private
nsIMdbHeap* mRowSpace_SlotHeap;
morkRowMap mRowSpace_Rows; // hash table of morkRow instances
morkTableMap mRowSpace_Tables; // all the tables in this row scope
mork_tid mRowSpace_NextTableId; // for auto-assigning table IDs
mork_rid mRowSpace_NextRowId; // for auto-assigning row IDs
mork_tid mRowSpace_NextTableId; // for auto-assigning table IDs
mork_rid mRowSpace_NextRowId; // for auto-assigning row IDs
mork_count mRowSpace_IndexCount; // if nonzero, row indexes exist
// every nonzero slot in IndexCache is a strong ref to a morkAtomRowMap:
morkAtomRowMap* mRowSpace_IndexCache[ morkRowSpace_kPrimeCacheSize ];
// { ===== begin morkNode interface =====
public: // morkNode virtual methods
@ -131,6 +147,14 @@ public: // other space methods
morkRow* NewRowWithOid(morkEnv* ev, const mdbOid* inOid);
morkRow* NewRow(morkEnv* ev);
morkRow* FindRow(morkEnv* ev, mork_column inColumn, const mdbYarn* inYarn);
morkAtomRowMap* ForceMap(morkEnv* ev, mork_column inColumn);
morkAtomRowMap* FindMap(morkEnv* ev, mork_column inColumn);
protected: // internal utilities
morkAtomRowMap* make_index(morkEnv* ev, mork_column inColumn);
public: // typesafe refcounting inlines calling inherited morkNode methods
static void SlotWeakRowSpace(morkRowSpace* me,
morkEnv* ev, morkRowSpace** ioSlot)

Просмотреть файл

@ -57,7 +57,7 @@ morkSpool::FlushSink(morkEnv* ev) // sync mSpool_Coil->mBuf_Fill
mork_u1* end = mSink_End;
if ( at >= body && at <= end ) // expected cursor order?
{
mork_fill fill = at - body; // current content size
mork_fill fill = (mork_fill) (at - body); // current content size
if ( fill <= coil->mBlob_Size )
coil->mBuf_Fill = fill;
else
@ -90,7 +90,7 @@ morkSpool::SpillPutc(morkEnv* ev, int c) // grow coil and write byte
if ( at >= body && at <= end ) // expected cursor order?
{
mork_size size = coil->mBlob_Size;
mork_fill fill = at - body; // current content size
mork_fill fill = (mork_fill) (at - body); // current content size
if ( fill <= size ) // less content than medium size?
{
coil->mBuf_Fill = fill;
@ -121,7 +121,7 @@ morkSpool::SpillPutc(morkEnv* ev, int c) // grow coil and write byte
{
if ( at < end ) // morkSink::Putc() would succeed?
{
*at++ = c;
*at++ = (mork_u1) c;
mSink_At = at;
coil->mBuf_Fill = fill + 1;
}
@ -201,14 +201,14 @@ morkSpool::Seek(morkEnv* ev, mork_pos inPos)
morkCoil* coil = mSpool_Coil;
if ( coil )
{
mork_size minSize = inPos + 64;
mork_size minSize = (mork_size) (inPos + 64);
if ( coil->mBlob_Size < minSize )
coil->GrowCoil(ev, minSize);
if ( ev->Good() )
{
coil->mBuf_Fill = inPos;
coil->mBuf_Fill = (mork_fill) inPos;
mork_u1* body = (mork_u1*) coil->mBuf_Body;
if ( body )
{
@ -246,7 +246,7 @@ morkSpool::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
{
// note coil->mBuf_Fill can be stale after morkSink::Putc():
mork_pos fill = at - body; // current content size
mork_num space = end - at; // space left in body
mork_num space = (mork_num) (end - at); // space left in body
if ( space < inSize ) // not enough to hold write?
{
mork_size minGrowth = space + 16;
@ -258,7 +258,7 @@ morkSpool::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
{
mSink_At = at = body + fill;
mSink_End = end = body + coil->mBlob_Size;
space = end - at; // space left in body
space = (mork_num) (end - at); // space left in body
}
else
coil->NilBufBodyError(ev);

Просмотреть файл

@ -94,7 +94,7 @@ morkSpace::morkSpace(morkEnv* ev,
{
if ( ev->Good() )
{
if ( ioStore )
if ( ioStore && ioSlotHeap )
{
morkStore::SlotWeakStore(ioStore, ev, &mSpace_Store);
if ( ev->Good() )

Просмотреть файл

@ -274,6 +274,7 @@ morkStore::CloseStore(morkEnv* ev) // called by CloseMorkNode();
void
morkStore::RenumberAllCollectableContent(morkEnv* ev)
{
MORK_USED_1(ev);
// do nothing currently
}
@ -367,6 +368,7 @@ morkStore::StageStringAsBookAtom(morkEnv* ev, const char* inString,
morkAtomSpace* morkStore::LazyGetOidAtomSpace(morkEnv* ev)
{
MORK_USED_1(ev);
if ( !mStore_OidAtomSpace )
{
}
@ -551,6 +553,7 @@ mork_bool
morkStore::OpenStoreFile(morkEnv* ev, mork_bool inFrozen,
const char* inFilePath, const mdbOpenPolicy* inOpenPolicy)
{
MORK_USED_1(inOpenPolicy);
morkFile::SlotStrongFile((morkFile*) 0, ev, &mStore_File);
if ( ev->Good() )
{
@ -571,6 +574,7 @@ mork_bool
morkStore::CreateStoreFile(morkEnv* ev,
const char* inFilePath, const mdbOpenPolicy* inOpenPolicy)
{
MORK_USED_1(inOpenPolicy);
morkFile::SlotStrongFile((morkFile*) 0, ev, &mStore_File);
if ( ev->Good() )
{
@ -736,6 +740,7 @@ morkStore::MidToAtom(morkEnv* ev, const morkMid& inMid)
morkStore::SmallTokenToOneByteYarn(morkEnv* ev, mdb_token inToken,
mdbYarn* outYarn)
{
MORK_USED_1(ev);
if ( outYarn->mYarn_Buf && outYarn->mYarn_Size ) // any space in yarn at all?
{
mork_u1* buf = (mork_u1*) outYarn->mYarn_Buf; // for byte arithmetic
@ -1028,10 +1033,14 @@ mork_bool
morkStore::HasTableKind(morkEnv* ev, mdb_scope inRowScope,
mdb_kind inTableKind, mdb_count* outTableCount)
{
MORK_USED_2(inRowScope,inTableKind);
mork_bool outBool = morkBool_kFalse;
mdb_count tableCount = 0;
ev->StubMethodOnlyError();
if ( outTableCount )
*outTableCount = tableCount;
return outBool;
}
@ -1059,6 +1068,22 @@ morkStore::GetTableKind(morkEnv* ev, mdb_scope inRowScope,
return outTable;
}
morkRow*
morkStore::FindRow(morkEnv* ev, mdb_scope inScope, mdb_column inColumn,
const mdbYarn* inYarn)
{
morkRow* outRow = 0;
if ( ev->Good() )
{
morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inScope);
if ( rowSpace )
{
outRow = rowSpace->FindRow(ev, inColumn, inYarn);
}
}
return outRow;
}
morkRow*
morkStore::GetRow(morkEnv* ev, const mdbOid* inOid)
{

Просмотреть файл

@ -294,6 +294,9 @@ public: // other store methods
morkTable* GetTableKind(morkEnv* ev, mdb_scope inRowScope,
mdb_kind inTableKind, mdb_count* outTableCount,
mdb_bool* outMustBeUnique);
morkRow* FindRow(morkEnv* ev, mdb_scope inScope, mdb_column inColumn,
const mdbYarn* inTargetCellValue);
morkRow* GetRow(morkEnv* ev, const mdbOid* inOid);
morkTable* GetTable(morkEnv* ev, const mdbOid* inOid);

Просмотреть файл

@ -381,6 +381,7 @@ morkStream::AcquireBud(morkEnv* ev, nsIMdbHeap* ioHeap)
// behavior is exhibited by the file, so crashes protect old files.
// Note that AcquireBud() is an illegal operation on readonly files.
{
MORK_USED_1(ioHeap);
morkFile* outFile = 0;
morkFile* file = mStream_ContentFile;
if ( this->IsOpenAndActiveFile() && file )
@ -508,7 +509,7 @@ morkStream::Read(morkEnv* ev, void* outBuf, mork_size inSize)
mork_u1* buf = mStream_Buf;
if ( at >= buf && at <= end ) // expected cursor order?
{
mork_num remaining = end - at; // bytes left in buffer
mork_num remaining = (mork_num) (end - at); // bytes left in buffer
mork_num quantum = inSize; // number of bytes to copy
if ( quantum > remaining ) // more than buffer content?
@ -534,7 +535,7 @@ morkStream::Read(morkEnv* ev, void* outBuf, mork_size inSize)
// exhausted the local buffer, so we need to show
// it is now empty, and adjust the current buf pos.
mork_num posDelta = (at - buf); // old buf content
mork_num posDelta = (mork_num) (at - buf); // old buf content
mStream_BufPos += posDelta; // past now empty buf
mStream_At = mStream_ReadEnd = buf; // empty buffer
@ -569,7 +570,7 @@ morkStream::Read(morkEnv* ev, void* outBuf, mork_size inSize)
if ( ev->Bad() )
outActual = 0;
return outActual;
return (mork_size) outActual;
}
/*public virtual*/ mork_pos
@ -658,7 +659,7 @@ morkStream::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
mork_u1* buf = mStream_Buf;
if ( at >= buf && at <= end ) // expected cursor order?
{
mork_num space = end - at; // space left in buffer
mork_num space = (mork_num) (end - at); // space left in buffer
mork_num quantum = inSize; // number of bytes to write
if ( quantum > space ) // more than buffer size?
@ -695,7 +696,7 @@ morkStream::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
if ( ev->Good() ) // no errors?
{
space = end - at; // space left in buffer
space = (mork_num) (end - at); // space left in buffer
if ( space > inSize ) // write to buffer?
{
mStream_Dirty = morkBool_kTrue; // ensure flush
@ -817,7 +818,7 @@ morkStream::spill_buf(morkEnv* ev) // spill/flush from buffer to file
mork_u1* at = mStream_At;
if ( at >= buf && at <= mStream_WriteEnd ) // order?
{
mork_num count = at - buf; // the number of bytes buffered
mork_num count = (mork_num) (at - buf); // bytes buffered
if ( count ) // anything to write to the string?
{
if ( count > mStream_BufSize ) // no more than max?

Просмотреть файл

@ -210,7 +210,7 @@ public: // public non-poly morkStream methods
{ this->PutString(ev, inString); }
void Ungetc(int c) /*i*/
{ if ( mStream_At > mStream_Buf && c > 0 ) *--mStream_At = c; }
{ if ( mStream_At > mStream_Buf && c > 0 ) *--mStream_At = (mork_u1) c; }
// Note Getc() returns EOF consistently after any fill_getc() error occurs.
int Getc(morkEnv* ev) /*i*/
@ -220,7 +220,7 @@ public: // public non-poly morkStream methods
{
mStream_Dirty = morkBool_kTrue;
if ( mStream_At < mStream_WriteEnd )
*mStream_At++ = c;
*mStream_At++ = (mork_u1) c;
else
spill_putc(ev, c);
}

Просмотреть файл

@ -162,6 +162,7 @@ morkTable::CloseTable(morkEnv* ev) /*i*/ // called by CloseMorkNode();
mork_u2
morkTable::AddCellUse(morkEnv* ev)
{
MORK_USED_1(ev);
if ( mTable_CellUses < morkTable_kMaxCellUses ) // not already maxed out?
++mTable_CellUses;
@ -266,6 +267,7 @@ morkTable::AcquireTableHandle(morkEnv* ev)
mork_pos
morkTable::ArrayHasOid(morkEnv* ev, const mdbOid* inOid)
{
MORK_USED_1(ev);
mork_count count = mTable_RowArray.mArray_Fill;
mork_pos pos = -1;
while ( ++pos < count )

Просмотреть файл

@ -111,8 +111,13 @@ morkThumb::morkThumb(morkEnv* ev,
{
if ( ev->Good() )
{
mThumb_Magic = inMagic;
mNode_Derived = morkDerived_kThumb;
if ( ioSlotHeap )
{
mThumb_Magic = inMagic;
mNode_Derived = morkDerived_kThumb;
}
else
ev->NilPointerError();
}
}
@ -218,7 +223,7 @@ morkThumb::Make_OpenFileStore(morkEnv* ev, nsIMdbHeap* ioHeap,
morkBuilder* builder = ioStore->LazyGetBuilder(ev);
if ( builder )
{
outThumb->mThumb_Total = fileEof;
outThumb->mThumb_Total = (mork_count) fileEof;
morkStore::SlotStrongStore(ioStore, ev, &outThumb->mThumb_Store);
morkBuilder::SlotStrongBuilder(builder, ev,
&outThumb->mThumb_Builder);
@ -277,6 +282,7 @@ morkThumb::Make_CompressCommit(morkEnv* ev,
void morkThumb::GetProgress(morkEnv* ev, mdb_count* outTotal,
mdb_count* outCurrent, mdb_bool* outDone, mdb_bool* outBroken)
{
MORK_USED_1(ev);
if ( outTotal )
*outTotal = mThumb_Total;
if ( outCurrent )
@ -350,6 +356,7 @@ void morkThumb::DoMore(morkEnv* ev, mdb_count* outTotal,
void morkThumb::CancelAndBreakThumb(morkEnv* ev)
{
MORK_USED_1(ev);
mThumb_Broken = morkBool_kTrue;
}
@ -359,6 +366,7 @@ morkStore*
morkThumb::ThumbToOpenStore(morkEnv* ev)
// for orkinFactory::ThumbToOpenStore() after OpenFileStore()
{
MORK_USED_1(ev);
return mThumb_Store;
}
@ -376,7 +384,7 @@ void morkThumb::DoMore_OpenFileStore(morkEnv* ev)
builder->ParseMore(ev, &pos, &mThumb_Done, &mThumb_Broken);
// mThumb_Total = builder->mBuilder_TotalCount;
// mThumb_Current = builder->mBuilder_DoneCount;
mThumb_Current = pos;
mThumb_Current = (mork_count) pos;
}
else
{

Просмотреть файл

@ -1027,7 +1027,7 @@ morkWriter::WriteTokenToTokenMetaCell(morkEnv* ev,
{
morkStream* stream = mWriter_Stream;
mork_bool isKindCol = ( morkStore_kKindColumn == inCol );
mork_u1 valSep = ( isKindCol )? '^' : '=';
mork_u1 valSep = (mork_u1) (( isKindCol )? '^' : '=');
char buf[ 128 ]; // buffer for staging the two hex IDs
char* p = buf;
@ -1096,6 +1096,50 @@ morkWriter::WriteStringToTokenDictCell(morkEnv* ev,
// mWriter_LineSize += stream->Write(ev, yarnBuf, fill + 1); // +1 for ')'
}
void
morkWriter::ChangeDictAtomScope(morkEnv* ev, mork_scope inScope)
{
if ( inScope != mWriter_DictAtomScope )
{
ev->NewWarning("unexpected atom scope change");
morkStream* stream = mWriter_Stream;
if ( mWriter_LineSize )
stream->PutLineBreak(ev);
mWriter_LineSize = 0;
char buf[ 128 ]; // buffer for staging the two hex IDs
char* p = buf;
*p++ = '<'; // we always start with open paren
*p++ = '('; // we always start with open paren
*p++ = (char) morkStore_kAtomScopeColumn;
mork_size scopeSize = 1; // default to one byte
if ( inScope >= 0x80 )
{
*p++ = '^'; // indicates col is hex ID
scopeSize = ev->TokenAsHex(p, inScope);
p += scopeSize;
}
else
{
*p++ = '='; // indicates col is imm byte
*p++ = (char) (mork_u1) inScope;
}
*p++ = ')';
*p++ = '>';
*p = 0;
mork_size pending = scopeSize + 6;
this->IndentOverMaxLine(ev, pending, morkWriter_kDictAliasDepth);
mWriter_LineSize += stream->Write(ev, buf, pending);
mWriter_DictAtomScope = inScope;
}
}
void
morkWriter::ChangeDictForm(morkEnv* ev, mork_cscode inNewForm)
{
@ -1111,10 +1155,20 @@ morkWriter::ChangeDictForm(morkEnv* ev, mork_cscode inNewForm)
*p++ = '<'; // we always start with open paren
*p++ = '('; // we always start with open paren
*p++ = (char) morkStore_kFormColumn;
*p++ = '^'; // indicates col is hex ID
mork_size formSize = ev->TokenAsHex(p, inNewForm);
p += formSize;
mork_size formSize = 1; // default to one byte
if ( inNewForm >= 0x80 )
{
*p++ = '^'; // indicates col is hex ID
formSize = ev->TokenAsHex(p, inNewForm);
p += formSize;
}
else
{
*p++ = '='; // indicates col is imm byte
*p++ = (char) (mork_u1) inNewForm;
}
*p++ = ')';
*p++ = '>';
*p = 0;
@ -1246,6 +1300,8 @@ morkWriter::EndTable(morkEnv* ev)
morkStream* stream = mWriter_Stream;
stream->Putc(ev, '}'); // end table
++mWriter_LineSize;
mWriter_TableAtomScope = 'v'; // (a=v)
}
mork_bool
@ -1284,6 +1340,10 @@ morkWriter::PutRowDict(morkEnv* ev, morkRow* ioRow)
if ( atom->AliasYarn(&yarn) )
{
mork_scope atomScope = atom->GetBookAtomSpaceScope(ev);
if ( atomScope && atomScope != mWriter_DictAtomScope )
this->ChangeDictAtomScope(ev, atomScope);
if ( mWriter_DidStartDict && yarn.mYarn_Form != mWriter_DictForm )
this->ChangeDictForm(ev, yarn.mYarn_Form);
@ -1354,6 +1414,9 @@ morkWriter::PutRowCells(morkEnv* ev, morkRow* ioRow)
mdbYarn yarn; // to ref content inside atom
atom->AliasYarn(&yarn);
if ( yarn.mYarn_Form != mWriter_DictForm )
this->ChangeDictForm(ev, yarn.mYarn_Form);
if ( atom->IsBook() ) // is it possible to write atom ID?
{
this->IndentAsNeeded(ev, morkWriter_kRowCellDepth);
@ -1375,7 +1438,8 @@ morkWriter::PutRowCells(morkEnv* ev, morkRow* ioRow)
p += yarnFill;
}
*p++ = ')';
mWriter_LineSize += stream->Write(ev, buf, p - buf);
mork_size distance = (mork_size) (p - buf);
mWriter_LineSize += stream->Write(ev, buf, distance);
}
else
{
@ -1392,9 +1456,6 @@ morkWriter::PutRowCells(morkEnv* ev, morkRow* ioRow)
}
else // must write an anonymous atom
{
if ( yarn.mYarn_Form != mWriter_DictForm )
this->ChangeDictForm(ev, yarn.mYarn_Form);
mork_size pending = yarn.mYarn_Fill + colSize +
morkWriter_kYarnEscapeSlop + 2;
this->IndentOverMaxLine(ev, pending, morkWriter_kRowCellDepth);

Просмотреть файл

@ -204,8 +204,11 @@ public: // typing & errors
static void NilWriterStreamError(morkEnv* ev);
static void UnsupportedPhaseError(morkEnv* ev);
public: // inlines
public: // utitlities
void ChangeDictForm(morkEnv* ev, mork_cscode inNewForm);
void ChangeDictAtomScope(morkEnv* ev, mork_scope inScope);
public: // inlines
mork_bool DidStartDict() const { return mWriter_DidStartDict; }
mork_bool DidEndDict() const { return mWriter_DidEndDict; }
@ -225,7 +228,7 @@ public: // inlines
mWriter_LineSize = mWriter_Stream->PutIndent(ev, inDepth);
}
public: // iterative/asynchronouse writing
public: // iterative/asynchronous writing
mork_bool WriteMore(morkEnv* ev); // call until IsWritingDone() is true

Просмотреть файл

@ -292,6 +292,7 @@ orkinCell::IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen)
orkinCell::SetBlob(nsIMdbEnv* mev,
nsIMdbBlob* ioBlob)
{
MORK_USED_1(ioBlob);
mdb_err outErr = 0;
morkCell* cell = 0;
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
@ -331,6 +332,7 @@ orkinCell::GetBlobFill(nsIMdbEnv* mev,
// with a yarn instance that had mYarn_Buf==nil and mYarn_Size==0.
{
mdb_err outErr = 0;
mdb_fill fill = 0;
morkCell* cell = 0;
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
&outErr, &cell);
@ -339,6 +341,8 @@ orkinCell::GetBlobFill(nsIMdbEnv* mev,
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outFill )
*outFill = fill;
return outErr;
} // size of blob
@ -418,6 +422,7 @@ orkinCell::AliasYarn(nsIMdbEnv* mev,
/*virtual*/ mdb_err
orkinCell::SetColumn(nsIMdbEnv* mev, mdb_column inColumn)
{
MORK_USED_1(inColumn);
mdb_err outErr = 0;
morkCell* cell = 0;
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
@ -462,6 +467,12 @@ orkinCell::GetCellInfo( // all cell metainfo except actual content
// in to memory when you don't actually want to use the content.
{
mdb_err outErr = 0;
mdb_bool isRowChild = morkBool_kFalse;
mdbOid childOid;
childOid.mOid_Scope = 0;
childOid.mOid_Id = 0;
mork_fill blobFill = 0;
mdb_column column = 0;
morkCell* cell = 0;
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
&outErr, &cell);
@ -471,6 +482,14 @@ orkinCell::GetCellInfo( // all cell metainfo except actual content
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outIsRowChild )
*outIsRowChild = isRowChild;
if ( outChildOid )
*outChildOid = childOid;
if ( outBlobFill )
*outBlobFill = blobFill;
if ( outColumn )
*outColumn = column;
return outErr;
}
@ -594,6 +613,7 @@ orkinCell::SetChildRow( // access table of specific attribute
nsIMdbEnv* mev, // context
nsIMdbRow* ioRow)
{
MORK_USED_1(ioRow);
mdb_err outErr = 0;
morkCell* cell = 0;
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
@ -614,6 +634,7 @@ orkinCell::GetChildRow( // access row of specific attribute
nsIMdbRow** acqRow) // acquire child row (or nil if no child)
{
mdb_err outErr = 0;
nsIMdbRow* outRow = 0;
morkCell* cell = 0;
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
&outErr, &cell);
@ -623,6 +644,8 @@ orkinCell::GetChildRow( // access row of specific attribute
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( acqRow )
*acqRow = outRow;
return outErr;
}
@ -633,6 +656,7 @@ orkinCell::SetChildTable( // access table of specific attribute
nsIMdbEnv* mev, // context
nsIMdbTable* inTable) // table must be bound inside this same db port
{
MORK_USED_1(inTable);
mdb_err outErr = 0;
morkCell* cell = 0;
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
@ -653,6 +677,7 @@ orkinCell::GetChildTable( // access table of specific attribute
nsIMdbTable** acqTable) // acquire child tabdle (or nil if no chil)
{
mdb_err outErr = 0;
nsIMdbTable* outTable = 0;
morkCell* cell = 0;
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
&outErr, &cell);
@ -662,6 +687,8 @@ orkinCell::GetChildTable( // access table of specific attribute
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( acqTable )
*acqTable = outTable;
return outErr;
}

Просмотреть файл

@ -71,7 +71,7 @@ protected: // morkHandle memory management operators
{ return ioPool.NewHandle(ev, inSize); }
void* operator new(size_t inSize, morkHandleFace* ioFace)
{ return ioFace; }
{ MORK_USED_1(inSize); return ioFace; }
void operator delete(void* ioAddress)
{ morkNode::OnDeleteAssert(ioAddress); }

Просмотреть файл

@ -77,6 +77,7 @@ orkinEnv::MakeEnv(morkEnv* ev, morkEnv* ioObject)
morkEnv*
orkinEnv::CanUseEnv(mork_bool inMutable, mdb_err* outErr) const
{
MORK_USED_1(inMutable);
morkEnv* outEnv = 0;
mdb_err err = morkEnv_kBadEnvError;
if ( this->IsHandle() )

Просмотреть файл

@ -73,7 +73,7 @@ protected: // morkHandle memory management operators
{ return ioPool.NewHandle(ev, inSize); }
void* operator new(size_t inSize, morkHandleFace* ioFace)
{ return ioFace; }
{ MORK_USED_1(inSize); return ioFace; }
void operator delete(void* ioAddress)
{ morkNode::OnDeleteAssert(ioAddress); }

Просмотреть файл

@ -346,13 +346,19 @@ orkinFactory::MakeHeap(nsIMdbEnv* mev, nsIMdbHeap** acqHeap)
orkinFactory::MakeRow(nsIMdbEnv* mev, nsIMdbHeap* ioHeap,
nsIMdbRow** acqRow)
{
MORK_USED_1(ioHeap);
mdb_err outErr = 0;
nsIMdbRow* outRow = 0;
morkEnv* ev = this->CanUseFactory(mev,
/*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( acqRow )
*acqRow = outRow;
return outErr;
}
// ioHeap can be nil, causing the heap associated with ev to be used
@ -368,6 +374,10 @@ orkinFactory::CanOpenFilePort(
mdbYarn* outFormatVersion)
{
mdb_err outErr = 0;
if ( outFormatVersion )
{
outFormatVersion->mYarn_Fill = 0;
}
mdb_bool canOpenAsPort = morkBool_kFalse;
morkEnv* ev = this->CanUseFactory(mev,
/*inMutable*/ morkBool_kFalse, &outErr);
@ -385,6 +395,7 @@ orkinFactory::CanOpenFilePort(
if ( outCanOpen )
*outCanOpen = canOpenAsPort;
return outErr;
}
@ -396,6 +407,7 @@ orkinFactory::OpenFilePort(
const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
nsIMdbThumb** acqThumb)
{
MORK_USED_1(ioHeap);
mdb_err outErr = 0;
nsIMdbThumb* outThumb = 0;
morkEnv* ev = this->CanUseFactory(mev,
@ -438,7 +450,7 @@ orkinFactory::ThumbToOpenPort( // redeeming a completed thumb from OpenFilePort(
morkStore* store = thumb->ThumbToOpenStore(ev);
if ( store )
{
store->mStore_CanAutoAssignAtomIdentity = morkBool_kTrue;
store->mStore_CanAutoAssignAtomIdentity = morkBool_kTrue;
outPort = orkinStore::MakeStore(ev, store);
}
}
@ -458,6 +470,7 @@ mork_bool
orkinFactory::CanOpenMorkTextFile(morkEnv* ev,
const mdbYarn* inFirst512Bytes)
{
MORK_USED_1(ev);
mork_bool outBool = morkBool_kFalse;
mork_size headSize = MORK_STRLEN(morkWriter_kFileHeader);
const mdbYarn* y = inFirst512Bytes;
@ -481,6 +494,10 @@ orkinFactory::CanOpenFileStore(
{
mdb_bool canOpenAsStore = morkBool_kFalse;
mdb_bool canOpenAsPort = morkBool_kFalse;
if ( outFormatVersion )
{
outFormatVersion->mYarn_Fill = 0;
}
mdb_err outErr = 0;
morkEnv* ev = this->CanUseFactory(mev,
/*inMutable*/ morkBool_kFalse, &outErr);
@ -576,7 +593,7 @@ orkinFactory::ThumbToOpenStore( // redeem completed thumb from OpenFileStore()
morkStore* store = thumb->ThumbToOpenStore(ev);
if ( store )
{
store->mStore_CanAutoAssignAtomIdentity = morkBool_kTrue;
store->mStore_CanAutoAssignAtomIdentity = morkBool_kTrue;
outStore = orkinStore::MakeStore(ev, store);
}
}
@ -616,7 +633,7 @@ orkinFactory::CreateNewFileStore( // create a new db with minimal content
if ( store )
{
store->mStore_CanAutoAssignAtomIdentity = morkBool_kTrue;
store->mStore_CanAutoAssignAtomIdentity = morkBool_kTrue;
if ( store->CreateStoreFile(ev, inFilePath, inOpenPolicy) )
outStore = orkinStore::MakeStore(ev, store);

Просмотреть файл

@ -73,7 +73,7 @@ protected: // morkHandle memory management operators
{ return ioPool.NewHandle(ev, inSize); }
void* operator new(size_t inSize, morkHandleFace* ioFace)
{ return ioFace; }
{ MORK_USED_1(inSize); return ioFace; }
void operator delete(void* ioAddress)
{ morkNode::OnDeleteAssert(ioAddress); }

Просмотреть файл

@ -50,6 +50,7 @@ orkinHeap::Alloc(nsIMdbEnv* ev, // allocate a piece of memory
mdb_size inSize, // requested size of new memory block
void** outBlock) // memory block of inSize bytes, or nil
{
MORK_USED_1(ev);
mdb_err outErr = 0;
void* block = new char[ inSize ];
if ( !block )
@ -65,6 +66,7 @@ orkinHeap::Alloc(nsIMdbEnv* ev, // allocate a piece of memory
orkinHeap::Free(nsIMdbEnv* ev, // free block allocated earlier by Alloc()
void* inBlock)
{
MORK_USED_1(ev);
MORK_ASSERT(inBlock);
if ( inBlock )
delete [] inBlock;

Просмотреть файл

@ -211,6 +211,7 @@ orkinPortTableCursor::IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen)
orkinPortTableCursor::GetCount(nsIMdbEnv* mev, mdb_count* outCount)
{
mdb_err outErr = 0;
mdb_count count = 0;
morkEnv* ev =
this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -218,6 +219,8 @@ orkinPortTableCursor::GetCount(nsIMdbEnv* mev, mdb_count* outCount)
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outCount )
*outCount = count;
return outErr;
}
@ -225,6 +228,7 @@ orkinPortTableCursor::GetCount(nsIMdbEnv* mev, mdb_count* outCount)
orkinPortTableCursor::GetSeed(nsIMdbEnv* mev, mdb_seed* outSeed)
{
mdb_err outErr = 0;
mdb_seed seed = 0;
morkEnv* ev =
this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -232,12 +236,15 @@ orkinPortTableCursor::GetSeed(nsIMdbEnv* mev, mdb_seed* outSeed)
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outSeed )
*outSeed = seed;
return outErr;
}
/*virtual*/ mdb_err
orkinPortTableCursor::SetPos(nsIMdbEnv* mev, mdb_pos inPos)
{
MORK_USED_1(inPos);
mdb_err outErr = 0;
morkEnv* ev =
this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
@ -253,6 +260,7 @@ orkinPortTableCursor::SetPos(nsIMdbEnv* mev, mdb_pos inPos)
orkinPortTableCursor::GetPos(nsIMdbEnv* mev, mdb_pos* outPos)
{
mdb_err outErr = 0;
mdb_pos pos = 0;
morkEnv* ev =
this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -260,12 +268,16 @@ orkinPortTableCursor::GetPos(nsIMdbEnv* mev, mdb_pos* outPos)
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outPos )
*outPos = pos;
return outErr;
}
/*virtual*/ mdb_err
orkinPortTableCursor::SetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool inFail)
{
MORK_USED_1(inFail);
mdb_err outErr = 0;
morkEnv* ev =
this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
@ -281,6 +293,7 @@ orkinPortTableCursor::SetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool inFail)
orkinPortTableCursor::GetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool* outFail)
{
mdb_err outErr = 0;
mdb_bool fail = 0;
morkEnv* ev =
this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -288,6 +301,8 @@ orkinPortTableCursor::GetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool* outFail
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outFail )
*outFail = fail;
return outErr;
}
// } ----- end attribute methods -----
@ -300,6 +315,7 @@ orkinPortTableCursor::GetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool* outFail
/*virtual*/ mdb_err
orkinPortTableCursor::SetPort(nsIMdbEnv* mev, nsIMdbPort* ioPort)
{
MORK_USED_1(ioPort);
mdb_err outErr = 0;
morkEnv* ev =
this->CanUsePortTableCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);

Просмотреть файл

@ -80,7 +80,7 @@ protected: // morkHandle memory management operators
{ return ioPool.NewHandle(ev, inSize); }
void* operator new(size_t inSize, morkHandleFace* ioFace)
{ return ioFace; }
{ MORK_USED_1(inSize); return ioFace; }
void operator delete(void* ioAddress)
{ morkNode::OnDeleteAssert(ioAddress); }

Просмотреть файл

@ -370,6 +370,7 @@ orkinRow::GetOid(nsIMdbEnv* mev,
orkinRow::BecomeContent(nsIMdbEnv* mev,
const mdbOid* inOid)
{
MORK_USED_1(inOid);
mdb_err outErr = 0;
morkRow* row = 0;
morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
@ -424,7 +425,7 @@ orkinRow::GetRowCellCursor( // make a cursor starting iteration at inRowPos
{
if ( ev->Good() )
{
cursor->mCursor_Seed = inPos;
cursor->mCursor_Seed = (mork_seed) inPos;
outCursor = cursor->AcquireRowCellCursorHandle(ev);
}
else
@ -678,7 +679,6 @@ orkinRow::SetRow( // make exact duplicate of another row
}
return outErr;
}
// } ----- end row methods -----
// } ===== end nsIMdbRow methods =====

Просмотреть файл

@ -74,7 +74,7 @@ protected: // morkHandle memory management operators
{ return ioPool.NewHandle(ev, inSize); }
void* operator new(size_t inSize, morkHandleFace* ioFace)
{ return ioFace; }
{ MORK_USED_1(inSize); return ioFace; }
void operator delete(void* ioAddress)
{ morkNode::OnDeleteAssert(ioAddress); }

Просмотреть файл

@ -455,7 +455,9 @@ orkinRowCellCursor::SeekCell( // same as SetRow() followed by MakeCell()
mdb_column* outColumn, // column for this particular cell
nsIMdbCell** acqCell)
{
MORK_USED_1(inPos);
mdb_err outErr = 0;
mdb_column column = 0;
nsIMdbCell* outCell = 0;
morkRow* row = 0;
morkEnv* ev =
@ -468,6 +470,8 @@ orkinRowCellCursor::SeekCell( // same as SetRow() followed by MakeCell()
}
if ( acqCell )
*acqCell = outCell;
if ( outColumn )
*outColumn = column;
return outErr;
}
// } ----- end cell seeking methods -----
@ -480,7 +484,10 @@ orkinRowCellCursor::NextCell( // get next cell in the row
mdb_column* outColumn, // column for this particular cell
mdb_pos* outPos)
{
MORK_USED_1(ioCell);
mdb_err outErr = 0;
mdb_pos pos = -1;
mdb_column column = 0;
morkRow* row = 0;
morkEnv* ev =
this->CanUseRowCellCursor(mev, /*mut*/ morkBool_kFalse, &outErr, &row);
@ -490,6 +497,10 @@ orkinRowCellCursor::NextCell( // get next cell in the row
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outColumn )
*outColumn = column;
if ( outPos )
*outPos = pos;
return outErr;
}
@ -504,6 +515,9 @@ orkinRowCellCursor::PickNextCell( // get next cell in row within filter set
// cols, since this might imply a potential excessive consumption of time
// over many cursor calls when looking for column and filter intersection.
{
MORK_USED_2(ioCell,inFilterSet);
mdb_pos pos = -1;
mdb_column column = 0;
mdb_err outErr = 0;
morkRow* row = 0;
morkEnv* ev =
@ -514,6 +528,10 @@ orkinRowCellCursor::PickNextCell( // get next cell in row within filter set
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outColumn )
*outColumn = column;
if ( outPos )
*outPos = pos;
return outErr;
}

Просмотреть файл

@ -81,7 +81,7 @@ protected: // morkHandle memory management operators
{ return ioPool.NewHandle(ev, inSize); }
void* operator new(size_t inSize, morkHandleFace* ioFace)
{ return ioFace; }
{ MORK_USED_1(inSize); return ioFace; }
void operator delete(void* ioAddress)
{ morkNode::OnDeleteAssert(ioAddress); }

Просмотреть файл

@ -228,19 +228,23 @@ orkinStore::IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen)
orkinStore::GetIsPortReadonly(nsIMdbEnv* mev, mdb_bool* outBool)
{
mdb_err outErr = 0;
mdb_bool isReadOnly = morkBool_kFalse;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outBool )
*outBool = isReadOnly;
return outErr;
}
/*virtual*/ mdb_err
orkinStore::GetIsStore(nsIMdbEnv* mev, mdb_bool* outBool)
{
if ( outBool )
MORK_USED_1(mev);
if ( outBool )
*outBool = morkBool_kTrue;
return 0;
}
@ -265,6 +269,7 @@ orkinStore::GetIsStoreAndDirty(nsIMdbEnv* mev, mdb_bool* outBool)
orkinStore::GetUsagePolicy(nsIMdbEnv* mev,
mdbUsagePolicy* ioUsagePolicy)
{
MORK_USED_1(ioUsagePolicy);
mdb_err outErr = 0;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -279,6 +284,7 @@ orkinStore::GetUsagePolicy(nsIMdbEnv* mev,
orkinStore::SetUsagePolicy(nsIMdbEnv* mev,
const mdbUsagePolicy* inUsagePolicy)
{
MORK_USED_1(inUsagePolicy);
mdb_err outErr = 0;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -315,13 +321,17 @@ orkinStore::SessionMemoryPurge( // request specific footprint decrease
mdb_size inDesiredBytesFreed, // approximate number of bytes wanted
mdb_size* outEstimatedBytesFreed) // approximate bytes actually freed
{
MORK_USED_1(inDesiredBytesFreed);
mdb_err outErr = 0;
mdb_size estimate = 0;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
// ev->StubMethodOnlyError(); // okay to do nothing?
outErr = ev->AsErr();
}
if ( outEstimatedBytesFreed )
*outEstimatedBytesFreed = estimate;
return outErr;
}
@ -331,12 +341,15 @@ orkinStore::PanicMemoryPurge( // desperately free all possible memory
mdb_size* outEstimatedBytesFreed) // approximate bytes actually freed
{
mdb_err outErr = 0;
mdb_size estimate = 0;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
// ev->StubMethodOnlyError(); // okay to do nothing?
outErr = ev->AsErr();
}
if ( outEstimatedBytesFreed )
*outEstimatedBytesFreed = estimate;
return outErr;
}
// } ----- end memory policy methods -----
@ -349,6 +362,10 @@ orkinStore::GetPortFilePath(
mdbYarn* outFormatVersion) // file format description
{
mdb_err outErr = 0;
if ( outFormatVersion )
outFormatVersion->mYarn_Fill = 0;
if ( outFilePath )
outFilePath->mYarn_Fill = 0;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
@ -366,6 +383,8 @@ orkinStore::BestExportFormat( // determine preferred export format
mdbYarn* outFormatVersion) // file format description
{
mdb_err outErr = 0;
if ( outFormatVersion )
outFormatVersion->mYarn_Fill = 0;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
@ -381,6 +400,8 @@ orkinStore::CanExportToFormat( // can export content in given specific format?
const char* inFormatVersion, // file format description
mdb_bool* outCanExport) // whether ExportSource() might succeed
{
MORK_USED_1(inFormatVersion);
mdb_bool canExport = morkBool_kFalse;
mdb_err outErr = 0;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -388,6 +409,8 @@ orkinStore::CanExportToFormat( // can export content in given specific format?
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outCanExport )
*outCanExport = canExport;
return outErr;
}
@ -400,13 +423,17 @@ orkinStore::ExportToFormat( // export content in given specific format
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the export will be finished.
{
MORK_USED_2(inFilePath,inFormatVersion);
mdb_err outErr = 0;
nsIMdbThumb* outThumb = 0;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( acqThumb )
*acqThumb = outThumb;
return outErr;
}
@ -547,6 +574,71 @@ orkinStore::GetRowRefCount( // get number of tables that contain a row
*outRefCount = count;
return outErr;
}
/*virtual*/ mdb_err
orkinStore::FindRow(nsIMdbEnv* mev, // search for row with matching cell
mdb_scope inRowScope, // row scope for row ids
mdb_column inColumn, // the column to search (and maintain an index)
const mdbYarn* inTargetCellValue, // cell value for which to search
mdbOid* outRowOid, // out row oid on match (or {0,-1} for no match)
nsIMdbRow** acqRow) // acquire matching row (or nil for no match)
// FindRow() searches for one row that has a cell in column inColumn with
// a contained value with the same form (i.e. charset) and is byte-wise
// identical to the blob described by yarn inTargetCellValue. Both content
// and form of the yarn must be an exact match to find a matching row.
//
// (In other words, both a yarn's blob bytes and form are significant. The
// form is not expected to vary in columns used for identity anyway. This
// is intended to make the cost of FindRow() cheaper for MDB implementors,
// since any cell value atomization performed internally must necessarily
// make yarn form significant in order to avoid data loss in atomization.)
//
// FindRow() can lazily create an index on attribute inColumn for all rows
// with that attribute in row space scope inRowScope, so that subsequent
// calls to FindRow() will perform faster. Such an index might or might
// not be persistent (but this seems desirable if it is cheap to do so).
// Note that lazy index creation in readonly DBs is not very feasible.
//
// This FindRow() interface assumes that attribute inColumn is effectively
// an alternative means of unique identification for a row in a rowspace,
// so correct behavior is only guaranteed when no duplicates for this col
// appear in the given set of rows. (If more than one row has the same cell
// value in this column, no more than one will be found; and cutting one of
// two duplicate rows can cause the index to assume no other such row lives
// in the row space, so future calls return nil for negative search results
// even though some duplicate row might still live within the rowspace.)
//
// In other words, the FindRow() implementation is allowed to assume simple
// hash tables mapping unqiue column keys to associated row values will be
// sufficient, where any duplication is not recorded because only one copy
// of a given key need be remembered. Implementors are not required to sort
// all rows by the specified column.
{
mdb_err outErr = 0;
nsIMdbRow* outRow = 0;
mdbOid rowOid;
rowOid.mOid_Scope = 0;
rowOid.mOid_Id = (mdb_id) -1;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
morkStore* store = (morkStore*) mHandle_Object;
morkRow* row = store->FindRow(ev, inRowScope, inColumn, inTargetCellValue);
if ( row && ev->Good() )
{
outRow = row->AcquireRowHandle(ev, store);
if ( outRow )
rowOid = row->mRow_Oid;
}
outErr = ev->AsErr();
}
if ( acqRow )
*acqRow = outRow;
return outErr;
}
// } ----- end row methods -----
// { ----- begin table methods -----
@ -735,6 +827,9 @@ orkinStore::RowScopeHasAssignedIds(nsIMdbEnv* mev,
mdb_bool* outCallerAssigned, // nonzero if caller assigned specified
mdb_bool* outStoreAssigned) // nonzero if store db assigned specified
{
MORK_USED_1(inRowScope);
mdb_bool storeAssigned = morkBool_kFalse;
mdb_bool callerAssigned = morkBool_kFalse;
mdb_err outErr = 0;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -742,6 +837,10 @@ orkinStore::RowScopeHasAssignedIds(nsIMdbEnv* mev,
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outCallerAssigned )
*outCallerAssigned = callerAssigned;
if ( outStoreAssigned )
*outStoreAssigned = storeAssigned;
return outErr;
}
@ -751,6 +850,9 @@ orkinStore::SetCallerAssignedIds(nsIMdbEnv* mev,
mdb_bool* outCallerAssigned, // nonzero if caller assigned specified
mdb_bool* outStoreAssigned) // nonzero if store db assigned specified
{
MORK_USED_1(inRowScope);
mdb_bool storeAssigned = morkBool_kFalse;
mdb_bool callerAssigned = morkBool_kFalse;
mdb_err outErr = 0;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -758,6 +860,10 @@ orkinStore::SetCallerAssignedIds(nsIMdbEnv* mev,
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outCallerAssigned )
*outCallerAssigned = callerAssigned;
if ( outStoreAssigned )
*outStoreAssigned = storeAssigned;
return outErr;
}
@ -767,13 +873,20 @@ orkinStore::SetStoreAssignedIds(nsIMdbEnv* mev,
mdb_bool* outCallerAssigned, // nonzero if caller assigned specified
mdb_bool* outStoreAssigned) // nonzero if store db assigned specified
{
MORK_USED_1(inRowScope);
mdb_err outErr = 0;
mdb_bool storeAssigned = morkBool_kFalse;
mdb_bool callerAssigned = morkBool_kFalse;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outCallerAssigned )
*outCallerAssigned = callerAssigned;
if ( outStoreAssigned )
*outStoreAssigned = storeAssigned;
return outErr;
}
// } ----- end row scope methods -----
@ -836,6 +949,8 @@ orkinStore::ImportContent( // import content from port
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the import will be finished.
{
MORK_USED_2(inRowScope,ioPort);
nsIMdbThumb* outThumb = 0;
mdb_err outErr = 0;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -843,6 +958,8 @@ orkinStore::ImportContent( // import content from port
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( acqThumb )
*acqThumb = outThumb;
return outErr;
}
// } ----- end inport/export methods -----
@ -854,6 +971,7 @@ orkinStore::ShareAtomColumnsHint( // advise re shared col content atomizing
mdb_scope inScopeHint, // zero, or suggested shared namespace
const mdbColumnSet* inColumnSet) // cols desired tokenized together
{
MORK_USED_2(inColumnSet,inScopeHint);
mdb_err outErr = 0;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -869,6 +987,7 @@ orkinStore::AvoidAtomColumnsHint( // advise col w/ poor atomizing prospects
nsIMdbEnv* mev, // context
const mdbColumnSet* inColumnSet) // cols with poor atomizing prospects
{
MORK_USED_1(inColumnSet);
mdb_err outErr = 0;
morkEnv* ev = this->CanUseStore(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )

Просмотреть файл

@ -73,7 +73,7 @@ protected: // morkHandle memory management operators
{ return ioPool.NewHandle(ev, inSize); }
void* operator new(size_t inSize, morkHandleFace* ioFace)
{ return ioFace; }
{ MORK_USED_1(inSize); return ioFace; }
void operator delete(void* ioAddress)
{ morkNode::OnDeleteAssert(ioAddress); }
@ -218,16 +218,54 @@ public: // type identification
nsIMdbEnv* ev, // context
const mdbOid* inOid, // hypothetical row oid
mdb_bool* outHasRow); // whether GetRow() might succeed
virtual mdb_err GetRowRefCount( // get number of tables that contain a row
nsIMdbEnv* ev, // context
const mdbOid* inOid, // hypothetical row oid
mdb_count* outRefCount); // number of tables containing inRowKey
virtual mdb_err GetRow( // access one row with specific oid
nsIMdbEnv* ev, // context
const mdbOid* inOid, // hypothetical row oid
nsIMdbRow** acqRow); // acquire specific row (or null)
virtual mdb_err GetRowRefCount( // get number of tables that contain a row
nsIMdbEnv* ev, // context
const mdbOid* inOid, // hypothetical row oid
mdb_count* outRefCount); // number of tables containing inRowKey
virtual mdb_err FindRow(nsIMdbEnv* ev, // search for row with matching cell
mdb_scope inRowScope, // row scope for row ids
mdb_column inColumn, // the column to search (and maintain an index)
const mdbYarn* inTargetCellValue, // cell value for which to search
mdbOid* outRowOid, // out row oid on match (or {0,-1} for no match)
nsIMdbRow** acqRow); // acquire matching row (or nil for no match)
// FindRow() searches for one row that has a cell in column inColumn with
// a contained value with the same form (i.e. charset) and is byte-wise
// identical to the blob described by yarn inTargetCellValue. Both content
// and form of the yarn must be an exact match to find a matching row.
//
// (In other words, both a yarn's blob bytes and form are significant. The
// form is not expected to vary in columns used for identity anyway. This
// is intended to make the cost of FindRow() cheaper for MDB implementors,
// since any cell value atomization performed internally must necessarily
// make yarn form significant in order to avoid data loss in atomization.)
//
// FindRow() can lazily create an index on attribute inColumn for all rows
// with that attribute in row space scope inRowScope, so that subsequent
// calls to FindRow() will perform faster. Such an index might or might
// not be persistent (but this seems desirable if it is cheap to do so).
// Note that lazy index creation in readonly DBs is not very feasible.
//
// This FindRow() interface assumes that attribute inColumn is effectively
// an alternative means of unique identification for a row in a rowspace,
// so correct behavior is only guaranteed when no duplicates for this col
// appear in the given set of rows. (If more than one row has the same cell
// value in this column, no more than one will be found; and cutting one of
// two duplicate rows can cause the index to assume no other such row lives
// in the row space, so future calls return nil for negative search results
// even though some duplicate row might still live within the rowspace.)
//
// In other words, the FindRow() implementation is allowed to assume simple
// hash tables mapping unqiue column keys to associated row values will be
// sufficient, where any duplication is not recorded because only one copy
// of a given key need be remembered. Implementors are not required to sort
// all rows by the specified column.
// } ----- end row methods -----
// { ----- begin table methods -----

Просмотреть файл

@ -310,6 +310,7 @@ orkinTable::GetOid(nsIMdbEnv* mev,
orkinTable::BecomeContent(nsIMdbEnv* mev,
const mdbOid* inOid) // exchange content
{
MORK_USED_1(inOid);
mdb_err outErr = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -458,7 +459,7 @@ orkinTable::GetTableRowCursor( // make a cursor, starting iteration at inRowPos
{
if ( ev->Good() )
{
cursor->mCursor_Seed = inRowPos;
cursor->mCursor_Seed = (mork_seed) inRowPos;
outCursor = cursor->AcquireTableRowCursorHandle(ev);
}
else
@ -483,7 +484,7 @@ orkinTable::PosToOid( // get row member for a table position
mdb_err outErr = 0;
mdbOid roid;
roid.mOid_Scope = 0;
roid.mOid_Id = -1;
roid.mOid_Id = (mork_id) -1;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -576,6 +577,7 @@ orkinTable::AddOid( // make sure the row with inOid is a table member
nsIMdbEnv* mev, // context
const mdbOid* inOid) // row to ensure membership in table
{
MORK_USED_1(inOid);
mdb_err outErr = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -736,6 +738,10 @@ orkinTable::SearchOneSortedColumn( // search only currently sorted col
const mdbYarn* inPrefix, // content to find as prefix in row's column cell
mdbRange* outRange) // range of matching rows
{
MORK_USED_1(inPrefix);
mdbRange range;
range.mRange_FirstPos = -1;
range.mRange_LastPos = -1;
mdb_err outErr = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -743,6 +749,8 @@ orkinTable::SearchOneSortedColumn( // search only currently sorted col
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outRange )
*outRange = range;
return outErr;
}
@ -757,13 +765,17 @@ orkinTable::SearchManyColumns( // search variable number of sorted cols
// is assumed referenced and used by the thumb; one should not inspect any
// output results in ioSearch until after the thumb is finished with it.
{
MORK_USED_2(inPrefix,ioSearch);
mdb_err outErr = 0;
nsIMdbThumb* outThumb = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( acqThumb )
*acqThumb = outThumb;
return outErr;
}
// } ----- end searching methods -----
@ -774,6 +786,7 @@ orkinTable::SearchColumnsHint( // advise re future expected search cols
nsIMdbEnv* mev, // context
const mdbColumnSet* inColumnSet) // columns likely to be searched
{
MORK_USED_1(inColumnSet);
mdb_err outErr = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -789,6 +802,7 @@ orkinTable::SortColumnsHint( // advise re future expected sort columns
nsIMdbEnv* mev, // context
const mdbColumnSet* inColumnSet) // columns for likely sort requests
{
MORK_USED_1(inColumnSet);
mdb_err outErr = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -807,6 +821,7 @@ orkinTable::StartBatchChangeHint( // advise before many adds and cuts
// the address of a local variable makes a good batch start label that
// can be used at batch end time, and such addresses remain unique.
{
MORK_USED_1(inLabel);
mdb_err outErr = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -831,6 +846,7 @@ orkinTable::EndBatchChangeHint( // advise before many adds and cuts
// a full sort of all rows at need when the batch changes end, or when
// a surprise request occurs for row position during batch changes.
{
MORK_USED_1(inLabel);
mdb_err outErr = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -852,6 +868,8 @@ orkinTable::CanSortColumn( // query which col is currently used for sorting
mdb_column inColumn, // column to query sorting potential
mdb_bool* outCanSort) // whether the column can be sorted
{
MORK_USED_1(inColumn);
mdb_bool canSort = morkBool_kFalse;
mdb_err outErr = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -861,6 +879,8 @@ orkinTable::CanSortColumn( // query which col is currently used for sorting
outErr = ev->AsErr();
}
if ( outCanSort )
*outCanSort = canSort;
return outErr;
}
@ -871,6 +891,8 @@ orkinTable::NewSortColumn( // change col used for sorting in the table
mdb_column* outActualColumn, // column actually used for sorting
nsIMdbThumb** acqThumb) // acquire thumb for incremental table resort
{
MORK_USED_1(inColumn);
mdb_column actualColumn = 0;
mdb_err outErr = 0;
nsIMdbThumb* outThumb = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
@ -879,6 +901,8 @@ orkinTable::NewSortColumn( // change col used for sorting in the table
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outActualColumn )
*outActualColumn = actualColumn;
if ( acqThumb )
*acqThumb = outThumb;
return outErr;
@ -894,6 +918,8 @@ orkinTable::NewSortColumnWithCompare( // change sort col w/ explicit compare
mdb_column* outActualColumn, // column actually used for sorting
nsIMdbThumb** acqThumb) // acquire thumb for incremental table resort
{
MORK_USED_2(inColumn,ioCompare);
mdb_column actualColumn = 0;
mdb_err outErr = 0;
nsIMdbThumb* outThumb = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
@ -902,6 +928,8 @@ orkinTable::NewSortColumnWithCompare( // change sort col w/ explicit compare
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outActualColumn )
*outActualColumn = actualColumn;
if ( acqThumb )
*acqThumb = outThumb;
return outErr;
@ -937,6 +965,7 @@ orkinTable::CloneSortColumn( // view same table with a different sort
mdb_column inColumn, // requested new column for sorting table
nsIMdbThumb** acqThumb) // acquire thumb for incremental table clone
{
MORK_USED_1(inColumn);
mdb_err outErr = 0;
nsIMdbThumb* outThumb = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
@ -958,6 +987,7 @@ orkinTable::ThumbToCloneSortTable( // redeem complete CloneSortColumn() thumb
nsIMdbThumb* ioThumb, // thumb from CloneSortColumn() with done status
nsIMdbTable** acqTable) // new table instance (or old if sort unchanged)
{
MORK_USED_1(ioThumb);
mdb_err outErr = 0;
nsIMdbTable* outTable = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
@ -983,13 +1013,17 @@ orkinTable::MoveOid( // change position of row in unsorted table
mdb_pos inToPos, // desired new position for row inRowId
mdb_pos* outActualPos) // actual new position of row in table
{
MORK_USED_3(inHintFromPos,inToPos,inOid);
mdb_err outErr = 0;
mdb_pos actualPos = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outActualPos )
*outActualPos = actualPos;
return outErr;
}
@ -1001,6 +1035,8 @@ orkinTable::MoveRow( // change position of row in unsorted table
mdb_pos inToPos, // desired new position for row inRowId
mdb_pos* outActualPos) // actual new position of row in table
{
MORK_USED_3(inHintFromPos,inToPos,ioRow);
mdb_pos actualPos = 0;
mdb_err outErr = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -1008,6 +1044,8 @@ orkinTable::MoveRow( // change position of row in unsorted table
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outActualPos )
*outActualPos = actualPos;
return outErr;
}
// } ----- end moving methods -----
@ -1021,6 +1059,8 @@ orkinTable::AddIndex( // create a sorting index for column if possible
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the index addition will be finished.
{
MORK_USED_1(inColumn);
nsIMdbThumb* outThumb = 0;
mdb_err outErr = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -1029,6 +1069,9 @@ orkinTable::AddIndex( // create a sorting index for column if possible
outErr = ev->AsErr();
}
if ( acqThumb )
*acqThumb = outThumb;
return outErr;
}
@ -1040,7 +1083,9 @@ orkinTable::CutIndex( // stop supporting a specific column index
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
// then the index removal will be finished.
{
MORK_USED_1(inColumn);
mdb_err outErr = 0;
nsIMdbThumb* outThumb = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
@ -1048,6 +1093,9 @@ orkinTable::CutIndex( // stop supporting a specific column index
outErr = ev->AsErr();
}
if ( acqThumb )
*acqThumb = outThumb;
return outErr;
}
@ -1057,15 +1105,17 @@ orkinTable::HasIndex( // query for current presence of a column index
mdb_column inColumn, // the column to investigate
mdb_bool* outHasIndex) // whether column has index for this column
{
MORK_USED_1(inColumn);
mdb_bool hasIndex = morkBool_kFalse;
mdb_err outErr = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
if ( outHasIndex )
*outHasIndex = morkBool_kFalse;
outErr = ev->AsErr();
}
if ( outHasIndex )
*outHasIndex = hasIndex;
return outErr;
}
@ -1074,6 +1124,7 @@ orkinTable::EnableIndexOnSort( // create an index for col on first sort
nsIMdbEnv* mev, // context
mdb_column inColumn) // the column to index if ever sorted
{
MORK_USED_1(inColumn);
mdb_err outErr = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -1090,15 +1141,17 @@ orkinTable::QueryIndexOnSort( // check whether index on sort is enabled
mdb_column inColumn, // the column to investigate
mdb_bool* outIndexOnSort) // whether column has index-on-sort enabled
{
MORK_USED_1(inColumn);
mdb_bool indexOnSort = morkBool_kFalse;
mdb_err outErr = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
{
if ( outIndexOnSort )
*outIndexOnSort = morkBool_kFalse;
outErr = ev->AsErr();
}
if ( outIndexOnSort )
*outIndexOnSort = indexOnSort;
return outErr;
}
@ -1107,6 +1160,7 @@ orkinTable::DisableIndexOnSort( // prevent future index creation on sort
nsIMdbEnv* mev, // context
mdb_column inColumn) // the column to index if ever sorted
{
MORK_USED_1(inColumn);
mdb_err outErr = 0;
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )

Просмотреть файл

@ -73,7 +73,7 @@ protected: // morkHandle memory management operators
{ return ioPool.NewHandle(ev, inSize); }
void* operator new(size_t inSize, morkHandleFace* ioFace)
{ return ioFace; }
{ MORK_USED_1(inSize); return ioFace; }
void operator delete(void* ioAddress)
{ morkNode::OnDeleteAssert(ioAddress); }

Просмотреть файл

@ -248,6 +248,7 @@ orkinTableRowCursor::GetCount(nsIMdbEnv* mev, mdb_count* outCount)
orkinTableRowCursor::GetSeed(nsIMdbEnv* mev, mdb_seed* outSeed)
{
mdb_err outErr = 0;
mdb_seed seed = 0;
morkEnv* ev =
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
if ( ev )
@ -255,6 +256,8 @@ orkinTableRowCursor::GetSeed(nsIMdbEnv* mev, mdb_seed* outSeed)
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outSeed )
*outSeed = seed;
return outErr;
}
@ -294,6 +297,7 @@ orkinTableRowCursor::GetPos(nsIMdbEnv* mev, mdb_pos* outPos)
/*virtual*/ mdb_err
orkinTableRowCursor::SetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool inFail)
{
MORK_USED_1(inFail);
mdb_err outErr = 0;
morkEnv* ev =
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
@ -308,6 +312,7 @@ orkinTableRowCursor::SetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool inFail)
/*virtual*/ mdb_err
orkinTableRowCursor::GetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool* outFail)
{
mdb_bool fail = morkBool_kFalse;
mdb_err outErr = 0;
morkEnv* ev =
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
@ -316,6 +321,8 @@ orkinTableRowCursor::GetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool* outFail)
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outFail )
*outFail = fail;
return outErr;
}
// } ----- end attribute methods -----
@ -329,6 +336,7 @@ orkinTableRowCursor::GetDoFailOnSeedOutOfSync(nsIMdbEnv* mev, mdb_bool* outFail)
/*virtual*/ mdb_err
orkinTableRowCursor::SetTable(nsIMdbEnv* mev, nsIMdbTable* ioTable)
{
MORK_USED_1(ioTable);
mdb_err outErr = 0;
morkEnv* ev =
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
@ -428,6 +436,11 @@ orkinTableRowCursor::NextRowCopy( // put row cells into sink only when already i
mdbOid* outOid, // out row oid
mdb_pos* outRowPos)
{
MORK_USED_1(ioSinkRow);
mdbOid oid;
oid.mOid_Scope = 0;
oid.mOid_Id = (mork_id) -1;
mdb_pos rowPos = -1;
mdb_err outErr = 0;
morkEnv* ev =
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
@ -441,6 +454,10 @@ orkinTableRowCursor::NextRowCopy( // put row cells into sink only when already i
ev->NilPointerError();
outErr = ev->AsErr();
}
if ( outRowPos )
*outRowPos = rowPos;
if ( outOid )
*outOid = oid;
return outErr;
}
@ -451,6 +468,11 @@ orkinTableRowCursor::NextRowCopyAll( // put all row cells into sink, adding to s
mdbOid* outOid, // out row oid
mdb_pos* outRowPos)
{
MORK_USED_1(ioSinkRow);
mdbOid oid;
oid.mOid_Scope = 0;
oid.mOid_Id = (mork_id) -1;
mdb_pos rowPos = -1;
mdb_err outErr = 0;
morkEnv* ev =
this->CanUseTableRowCursor(mev, /*inMutable*/ morkBool_kFalse, &outErr);
@ -459,6 +481,10 @@ orkinTableRowCursor::NextRowCopyAll( // put all row cells into sink, adding to s
ev->StubMethodOnlyError();
outErr = ev->AsErr();
}
if ( outRowPos )
*outRowPos = rowPos;
if ( outOid )
*outOid = oid;
return outErr;
} // nonzero if child, and a row child

Просмотреть файл

@ -75,7 +75,7 @@ protected: // morkHandle memory management operators
{ return ioPool.NewHandle(ev, inSize); }
void* operator new(size_t inSize, morkHandleFace* ioFace)
{ return ioFace; }
{ MORK_USED_1(inSize); return ioFace; }
void operator delete(void* ioAddress)
{ morkNode::OnDeleteAssert(ioAddress); }

Просмотреть файл

@ -73,7 +73,7 @@ protected: // morkHandle memory management operators
{ return ioPool.NewHandle(ev, inSize); }
void* operator new(size_t inSize, morkHandleFace* ioFace)
{ return ioFace; }
{ MORK_USED_1(inSize); return ioFace; }
void operator delete(void* ioAddress)
{ morkNode::OnDeleteAssert(ioAddress); }

Просмотреть файл

@ -939,16 +939,54 @@ public:
nsIMdbEnv* ev, // context
const mdbOid* inOid, // hypothetical row oid
mdb_bool* outHasRow) = 0; // whether GetRow() might succeed
virtual mdb_err GetRowRefCount( // get number of tables that contain a row
nsIMdbEnv* ev, // context
const mdbOid* inOid, // hypothetical row oid
mdb_count* outRefCount) = 0; // number of tables containing inRowKey
virtual mdb_err GetRow( // access one row with specific oid
nsIMdbEnv* ev, // context
const mdbOid* inOid, // hypothetical row oid
nsIMdbRow** acqRow) = 0; // acquire specific row (or null)
virtual mdb_err GetRowRefCount( // get number of tables that contain a row
nsIMdbEnv* ev, // context
const mdbOid* inOid, // hypothetical row oid
mdb_count* outRefCount) = 0; // number of tables containing inRowKey
virtual mdb_err FindRow(nsIMdbEnv* ev, // search for row with matching cell
mdb_scope inRowScope, // row scope for row ids
mdb_column inColumn, // the column to search (and maintain an index)
const mdbYarn* inTargetCellValue, // cell value for which to search
mdbOid* outRowOid, // out row oid on match (or {0,-1} for no match)
nsIMdbRow** acqRow) = 0; // acquire matching row (or nil for no match)
// FindRow() searches for one row that has a cell in column inColumn with
// a contained value with the same form (i.e. charset) and is byte-wise
// identical to the blob described by yarn inTargetCellValue. Both content
// and form of the yarn must be an exact match to find a matching row.
//
// (In other words, both a yarn's blob bytes and form are significant. The
// form is not expected to vary in columns used for identity anyway. This
// is intended to make the cost of FindRow() cheaper for MDB implementors,
// since any cell value atomization performed internally must necessarily
// make yarn form significant in order to avoid data loss in atomization.)
//
// FindRow() can lazily create an index on attribute inColumn for all rows
// with that attribute in row space scope inRowScope, so that subsequent
// calls to FindRow() will perform faster. Such an index might or might
// not be persistent (but this seems desirable if it is cheap to do so).
// Note that lazy index creation in readonly DBs is not very feasible.
//
// This FindRow() interface assumes that attribute inColumn is effectively
// an alternative means of unique identification for a row in a rowspace,
// so correct behavior is only guaranteed when no duplicates for this col
// appear in the given set of rows. (If more than one row has the same cell
// value in this column, no more than one will be found; and cutting one of
// two duplicate rows can cause the index to assume no other such row lives
// in the row space, so future calls return nil for negative search results
// even though some duplicate row might still live within the rowspace.)
//
// In other words, the FindRow() implementation is allowed to assume simple
// hash tables mapping unqiue column keys to associated row values will be
// sufficient, where any duplication is not recorded because only one copy
// of a given key need be remembered. Implementors are not required to sort
// all rows by the specified column.
// } ----- end row methods -----
// { ----- begin table methods -----
@ -1116,6 +1154,7 @@ public:
nsIMdbRow** acqRow) = 0; // create new row
// Note this row must be added to some table or cell child before the
// store is closed in order to make this row persist across sesssions.
// } ----- end row methods -----
// { ----- begin inport/export methods -----

Просмотреть файл

@ -1,310 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _MDB_
#include "mdb.h"
#endif
#ifndef _MORK_
#include "mork.h"
#endif
#ifndef _MORKNODE_
#include "morkNode.h"
#endif
#ifndef _MORKENV_
#include "morkEnv.h"
#endif
#ifndef _MORKARRAY_
#include "morkArray.h"
#endif
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
// ````` ````` ````` ````` `````
// { ===== begin morkNode interface =====
/*public virtual*/ void
morkArray::CloseMorkNode(morkEnv* ev) // CloseTable() only if open
{
if ( this->IsOpenNode() )
{
this->MarkClosing();
this->CloseArray(ev);
this->MarkShut();
}
}
/*public virtual*/
morkArray::~morkArray() // assert CloseTable() executed earlier
{
MORK_ASSERT(this->IsShutNode());
MORK_ASSERT(mArray_Slots==0);
}
/*public non-poly*/
morkArray::morkArray(morkEnv* ev, const morkUsage& inUsage,
nsIMdbHeap* ioHeap, mork_size inSize, nsIMdbHeap* ioSlotHeap)
: morkNode(ev, inUsage, ioHeap)
, mArray_Slots( 0 )
, mArray_Heap( 0 )
, mArray_Fill( 0 )
, mArray_Size( 0 )
, mArray_Seed( (mork_u4) this ) // "random" integer assignment
{
if ( ev->Good() )
{
if ( ioSlotHeap )
{
nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mArray_Heap);
if ( ev->Good() )
{
if ( inSize < 3 )
inSize = 3;
mdb_size byteSize = inSize * sizeof(void*);
void** block = 0;
ioSlotHeap->Alloc(ev->AsMdbEnv(), byteSize, (void**) &block);
if ( block && ev->Good() )
{
mArray_Slots = block;
mArray_Size = inSize;
MORK_MEMSET(mArray_Slots, 0, byteSize);
if ( ev->Good() )
mNode_Derived = morkDerived_kArray;
}
}
}
else
ev->NilPointerError();
}
}
/*public non-poly*/ void
morkArray::CloseArray(morkEnv* ev) // called by CloseMorkNode();
{
if ( this )
{
if ( this->IsNode() )
{
if ( mArray_Heap && mArray_Slots )
mArray_Heap->Free(ev->AsMdbEnv(), mArray_Slots);
mArray_Slots = 0;
mArray_Size = 0;
mArray_Fill = 0;
++mArray_Seed;
nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mArray_Heap);
this->MarkShut();
}
else
this->NonNodeError(ev);
}
else
ev->NilPointerError();
}
// } ===== end morkNode methods =====
// ````` ````` ````` ````` `````
/*static*/ void
morkArray::NonArrayTypeError(morkEnv* ev)
{
ev->NewError("non morkArray");
}
/*static*/ void
morkArray::IndexBeyondEndError(morkEnv* ev)
{
ev->NewError("array index beyond end");
}
/*static*/ void
morkArray::NilSlotsAddressError(morkEnv* ev)
{
ev->NewError("nil mArray_Slots");
}
/*static*/ void
morkArray::FillBeyondSizeError(morkEnv* ev)
{
ev->NewError("mArray_Fill > mArray_Size");
}
mork_bool
morkArray::Grow(morkEnv* ev, mork_size inNewSize)
// Grow() returns true if capacity becomes >= inNewSize and ev->Good()
{
if ( ev->Good() && inNewSize > mArray_Size ) // make array larger?
{
if ( mArray_Fill <= mArray_Size ) // fill and size fit the invariant?
{
if ( inNewSize - mArray_Size < 3 ) // actually want a few more slots?
inNewSize = mArray_Size + 3;
mdb_size newByteSize = inNewSize * sizeof(void*);
void** newBlock = 0;
mArray_Heap->Alloc(ev->AsMdbEnv(), newByteSize, (void**) &newBlock);
if ( newBlock && ev->Good() ) // okay new block?
{
void** oldSlots = mArray_Slots;
void** oldEnd = oldSlots + mArray_Fill;
void** newSlots = newBlock;
void** newEnd = newBlock + inNewSize;
while ( oldSlots < oldEnd )
*newSlots++ = *oldSlots++;
while ( newSlots < newEnd )
*newSlots++ = (void*) 0;
oldSlots = mArray_Slots;
mArray_Size = inNewSize;
mArray_Slots = newBlock;
mArray_Heap->Free(ev->AsMdbEnv(), oldSlots);
}
}
else
this->FillBeyondSizeError(ev);
}
++mArray_Seed; // always modify seed, since caller intends to add slots
return ( ev->Good() && mArray_Size >= inNewSize );
}
void*
morkArray::SafeAt(morkEnv* ev, mork_pos inPos)
{
if ( mArray_Slots )
{
if ( inPos >= 0 && inPos < (mork_pos) mArray_Fill )
return mArray_Slots[ inPos ];
else
this->IndexBeyondEndError(ev);
}
else
this->NilSlotsAddressError(ev);
return (void*) 0;
}
void
morkArray::SafeAtPut(morkEnv* ev, mork_pos inPos, void* ioSlot)
{
if ( mArray_Slots )
{
if ( inPos >= 0 && inPos < (mork_pos) mArray_Fill )
{
mArray_Slots[ inPos ] = ioSlot;
++mArray_Seed;
}
else
this->IndexBeyondEndError(ev);
}
else
this->NilSlotsAddressError(ev);
}
mork_pos
morkArray::AppendSlot(morkEnv* ev, void* ioSlot)
{
mork_pos outPos = -1;
if ( mArray_Slots )
{
mork_fill fill = mArray_Fill;
if ( this->Grow(ev, fill+1) )
{
outPos = fill;
mArray_Slots[ fill ] = ioSlot;
mArray_Fill = fill + 1;
// note Grow() increments mArray_Seed
}
}
else
this->NilSlotsAddressError(ev);
return outPos;
}
void
morkArray::AddSlot(morkEnv* ev, mork_pos inPos, void* ioSlot)
{
if ( mArray_Slots )
{
mork_fill fill = mArray_Fill;
if ( this->Grow(ev, fill+1) )
{
void** slot = mArray_Slots; // the slot vector
void** end = slot + fill; // one past the last used array slot
slot += inPos; // the slot to be added
while ( --end >= slot ) // another slot to move upward?
end[ 1 ] = *end;
*slot = ioSlot;
mArray_Fill = fill + 1;
// note Grow() increments mArray_Seed
}
}
else
this->NilSlotsAddressError(ev);
}
void
morkArray::CutSlot(morkEnv* ev, mork_pos inPos)
{
mork_fill fill = mArray_Fill;
if ( inPos >= 0 && inPos < (mork_pos) fill ) // cutting slot in used array portion?
{
void** slot = mArray_Slots; // the slot vector
void** end = slot + fill; // one past the last used array slot
slot += inPos; // the slot to be cut
while ( ++slot < end ) // another slot to move downward?
slot[ -1 ] = *slot;
slot[ -1 ] = 0; // clear the last used slot which is now unused
// note inPos<fill implies fill>0, so fill-1 must be nonnegative:
mArray_Fill = fill - 1;
++mArray_Seed;
}
}
void
morkArray::CutAllSlots(morkEnv* ev)
{
if ( mArray_Slots )
{
if ( mArray_Fill <= mArray_Size )
{
mdb_size oldByteSize = mArray_Fill * sizeof(void*);
MORK_MEMSET(mArray_Slots, 0, oldByteSize);
}
else
this->FillBeyondSizeError(ev);
}
else
this->NilSlotsAddressError(ev);
++mArray_Seed;
mArray_Fill = 0;
}
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

Просмотреть файл

@ -204,15 +204,40 @@ morkAtom::AliasYarn(mdbYarn* outYarn) const
return ( atom != 0 );
}
mork_aid
morkAtom::GetBookAtomAid() const // zero or book atom's ID
{
return ( this->IsBook() )? ((morkBookAtom*) this)->mBookAtom_Id : 0;
}
mork_scope
morkAtom::GetBookAtomSpaceScope(morkEnv* ev) const // zero or book's space's scope
{
mork_scope outScope = 0;
if ( this->IsBook() )
{
const morkBookAtom* bookAtom = (const morkBookAtom*) this;
morkAtomSpace* space = bookAtom->mBookAtom_Space;
if ( space->IsAtomSpace() )
outScope = space->mSpace_Scope;
else
space->NonAtomSpaceTypeError(ev);
}
return outScope;
}
void
morkAtom::MakeCellUseForever(morkEnv* ev)
{
MORK_USED_1(ev);
mAtom_CellUses = morkAtom_kForeverCellUses;
}
mork_u1
morkAtom::AddCellUse(morkEnv* ev)
{
MORK_USED_1(ev);
if ( mAtom_CellUses < morkAtom_kMaxCellUses ) // not already maxed out?
++mAtom_CellUses;
@ -260,6 +285,7 @@ morkAtom::AtomSizeOverflowError(morkEnv* ev)
void
morkOidAtom::InitRowOidAtom(morkEnv* ev, const mdbOid& inOid)
{
MORK_USED_1(ev);
mAtom_CellUses = 0;
mAtom_Kind = morkAtom_kKindRowOid;
mAtom_Change = morkChange_kNil;
@ -270,6 +296,7 @@ morkOidAtom::InitRowOidAtom(morkEnv* ev, const mdbOid& inOid)
void
morkOidAtom::InitTableOidAtom(morkEnv* ev, const mdbOid& inOid)
{
MORK_USED_1(ev);
mAtom_CellUses = 0;
mAtom_Kind = morkAtom_kKindTableOid;
mAtom_Change = morkChange_kNil;
@ -301,6 +328,7 @@ void
morkBigAnonAtom::InitBigAnonAtom(morkEnv* ev, const morkBuf& inBuf,
mork_cscode inForm)
{
MORK_USED_1(ev);
mAtom_CellUses = 0;
mAtom_Kind = morkAtom_kKindBigAnon;
mAtom_Change = morkChange_kNil;

Просмотреть файл

@ -60,6 +60,14 @@ public:
mork_bool IsBook() const { return this->IsWeeBook() || this->IsBigBook(); }
public: // atom space scope if IsBook() is true, or else zero:
mork_scope GetBookAtomSpaceScope(morkEnv* ev) const;
// zero or book's space's scope
mork_aid GetBookAtomAid() const;
// zero or book atom's ID
public: // empty construction does nothing
morkAtom() { }

Просмотреть файл

@ -1,263 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _MDB_
#include "mdb.h"
#endif
#ifndef _MORK_
#include "mork.h"
#endif
#ifndef _MORKNODE_
#include "morkNode.h"
#endif
#ifndef _MORKENV_
#include "morkEnv.h"
#endif
#ifndef _MORKMAP_
#include "morkMap.h"
#endif
#ifndef _MORKATOMMAP_
#include "morkAtomMap.h"
#endif
#ifndef _MORKATOM_
#include "morkAtom.h"
#endif
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
// ````` ````` ````` ````` `````
// { ===== begin morkNode interface =====
/*public virtual*/ void
morkAtomAidMap::CloseMorkNode(morkEnv* ev) // CloseAtomAidMap() only if open
{
if ( this->IsOpenNode() )
{
this->MarkClosing();
this->CloseAtomAidMap(ev);
this->MarkShut();
}
}
/*public virtual*/
morkAtomAidMap::~morkAtomAidMap() // assert CloseAtomAidMap() executed earlier
{
MORK_ASSERT(this->IsShutNode());
}
/*public non-poly*/
morkAtomAidMap::morkAtomAidMap(morkEnv* ev, const morkUsage& inUsage,
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
: morkMap(ev, inUsage, ioHeap,
/*inKeySize*/ sizeof(morkBookAtom*), /*inValSize*/ 0,
morkAtomAidMap_kStartSlotCount, ioSlotHeap,
/*inHoldChanges*/ morkBool_kFalse)
{
if ( ev->Good() )
mNode_Derived = morkDerived_kAtomAidMap;
}
/*public non-poly*/ void
morkAtomAidMap::CloseAtomAidMap(morkEnv* ev) // called by CloseMorkNode();
{
if ( this )
{
if ( this->IsNode() )
{
this->CloseMap(ev);
this->MarkShut();
}
else
this->NonNodeError(ev);
}
else
ev->NilPointerError();
}
// } ===== end morkNode methods =====
// ````` ````` ````` ````` `````
// { ===== begin morkMap poly interface =====
/*virtual*/ mork_bool //
morkAtomAidMap::Equal(morkEnv* ev, const void* inKeyA,
const void* inKeyB) const
{
return (*(const morkBookAtom**) inKeyA)->EqualAid(
*(const morkBookAtom**) inKeyB);
}
/*virtual*/ mork_u4 //
morkAtomAidMap::Hash(morkEnv* ev, const void* inKey) const
{
return (*(const morkBookAtom**) inKey)->HashAid();
}
// } ===== end morkMap poly interface =====
mork_bool
morkAtomAidMap::AddAtom(morkEnv* ev, morkBookAtom* ioAtom)
{
if ( ev->Good() )
{
this->Put(ev, &ioAtom, /*val*/ (void*) 0,
/*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0);
}
return ev->Good();
}
morkBookAtom*
morkAtomAidMap::CutAtom(morkEnv* ev, const morkBookAtom* inAtom)
{
morkBookAtom* oldKey = 0;
this->Cut(ev, &inAtom, &oldKey, /*val*/ (void*) 0,
(mork_change**) 0);
return oldKey;
}
morkBookAtom*
morkAtomAidMap::GetAtom(morkEnv* ev, const morkBookAtom* inAtom)
{
morkBookAtom* key = 0; // old val in the map
this->Get(ev, &inAtom, &key, /*val*/ (void*) 0, (mork_change**) 0);
return key;
}
morkBookAtom*
morkAtomAidMap::GetAid(morkEnv* ev, mork_aid inAid)
{
morkWeeBookAtom weeAtom(inAid);
morkBookAtom* key = &weeAtom; // we need a pointer
morkBookAtom* oldKey = 0; // old key in the map
this->Get(ev, &key, &oldKey, /*val*/ (void*) 0, (mork_change**) 0);
return oldKey;
}
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
// ````` ````` ````` ````` `````
// { ===== begin morkNode interface =====
/*public virtual*/ void
morkAtomBodyMap::CloseMorkNode(morkEnv* ev) // CloseAtomBodyMap() only if open
{
if ( this->IsOpenNode() )
{
this->MarkClosing();
this->CloseAtomBodyMap(ev);
this->MarkShut();
}
}
/*public virtual*/
morkAtomBodyMap::~morkAtomBodyMap() // assert CloseAtomBodyMap() executed earlier
{
MORK_ASSERT(this->IsShutNode());
}
/*public non-poly*/
morkAtomBodyMap::morkAtomBodyMap(morkEnv* ev, const morkUsage& inUsage,
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
: morkMap(ev, inUsage, ioHeap,
/*inKeySize*/ sizeof(morkBookAtom*), /*inValSize*/ 0,
morkAtomBodyMap_kStartSlotCount, ioSlotHeap,
/*inHoldChanges*/ morkBool_kFalse)
{
if ( ev->Good() )
mNode_Derived = morkDerived_kAtomBodyMap;
}
/*public non-poly*/ void
morkAtomBodyMap::CloseAtomBodyMap(morkEnv* ev) // called by CloseMorkNode();
{
if ( this )
{
if ( this->IsNode() )
{
this->CloseMap(ev);
this->MarkShut();
}
else
this->NonNodeError(ev);
}
else
ev->NilPointerError();
}
// } ===== end morkNode methods =====
// ````` ````` ````` ````` `````
// { ===== begin morkMap poly interface =====
/*virtual*/ mork_bool //
morkAtomBodyMap::Equal(morkEnv* ev, const void* inKeyA,
const void* inKeyB) const
{
return (*(const morkBookAtom**) inKeyA)->EqualFormAndBody(ev,
*(const morkBookAtom**) inKeyB);
}
/*virtual*/ mork_u4 //
morkAtomBodyMap::Hash(morkEnv* ev, const void* inKey) const
{
return (*(const morkBookAtom**) inKey)->HashFormAndBody(ev);
}
// } ===== end morkMap poly interface =====
mork_bool
morkAtomBodyMap::AddAtom(morkEnv* ev, morkBookAtom* ioAtom)
{
if ( ev->Good() )
{
this->Put(ev, &ioAtom, /*val*/ (void*) 0,
/*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0);
}
return ev->Good();
}
morkBookAtom*
morkAtomBodyMap::CutAtom(morkEnv* ev, const morkBookAtom* inAtom)
{
morkBookAtom* oldKey = 0;
this->Cut(ev, &inAtom, &oldKey, /*val*/ (void*) 0,
(mork_change**) 0);
return oldKey;
}
morkBookAtom*
morkAtomBodyMap::GetAtom(morkEnv* ev, const morkBookAtom* inAtom)
{
morkBookAtom* key = 0; // old val in the map
this->Get(ev, &inAtom, &key, /*val*/ (void*) 0, (mork_change**) 0);
return key;
}
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

Просмотреть файл

@ -1,187 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _MORKATOMMAP_
#define _MORKATOMMAP_ 1
#ifndef _MORK_
#include "mork.h"
#endif
#ifndef _MORKNODE_
#include "morkNode.h"
#endif
#ifndef _MORKMAP_
#include "morkMap.h"
#endif
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#define morkDerived_kAtomAidMap /*i*/ 0x6141 /* ascii 'aA' */
#define morkAtomAidMap_kStartSlotCount 512
/*| morkAtomAidMap: keys of morkBookAtom organized by atom ID
|*/
class morkAtomAidMap : public morkMap { // for mapping tokens to maps
// { ===== begin morkNode interface =====
public: // morkNode virtual methods
virtual void CloseMorkNode(morkEnv* ev); // CloseAtomAidMap() only if open
virtual ~morkAtomAidMap(); // assert that CloseAtomAidMap() executed earlier
public: // morkMap construction & destruction
morkAtomAidMap(morkEnv* ev, const morkUsage& inUsage,
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap);
void CloseAtomAidMap(morkEnv* ev); // called by CloseMorkNode();
public: // dynamic type identification
mork_bool IsAtomAidMap() const
{ return IsNode() && mNode_Derived == morkDerived_kAtomAidMap; }
// } ===== end morkNode methods =====
// { ===== begin morkMap poly interface =====
virtual mork_bool // note: equal(a,b) implies hash(a) == hash(b)
Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const;
// implemented using morkBookAtom::HashAid()
virtual mork_u4 // note: equal(a,b) implies hash(a) == hash(b)
Hash(morkEnv* ev, const void* inKey) const;
// implemented using morkBookAtom::EqualAid()
// } ===== end morkMap poly interface =====
public: // other map methods
mork_bool AddAtom(morkEnv* ev, morkBookAtom* ioAtom);
// AddAtom() returns ev->Good()
morkBookAtom* CutAtom(morkEnv* ev, const morkBookAtom* inAtom);
// CutAtom() returns the atom removed equal to inAtom, if there was one
morkBookAtom* GetAtom(morkEnv* ev, const morkBookAtom* inAtom);
// GetAtom() returns the atom equal to inAtom, or else nil
morkBookAtom* GetAid(morkEnv* ev, mork_aid inAid);
// GetAid() returns the atom equal to inAid, or else nil
// note the atoms are owned elsewhere, usuall by morkAtomSpace
};
class morkAtomAidMapIter: public morkMapIter{ // typesafe wrapper class
public:
morkAtomAidMapIter(morkEnv* ev, morkAtomAidMap* ioMap)
: morkMapIter(ev, ioMap) { }
morkAtomAidMapIter( ) : morkMapIter() { }
void InitAtomAidMapIter(morkEnv* ev, morkAtomAidMap* ioMap)
{ this->InitMapIter(ev, ioMap); }
mork_change* FirstAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
{ return this->First(ev, outAtomPtr, /*val*/ (void*) 0); }
mork_change* NextAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
{ return this->Next(ev, outAtomPtr, /*val*/ (void*) 0); }
mork_change* HereAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
{ return this->Here(ev, outAtomPtr, /*val*/ (void*) 0); }
mork_change* CutHereAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
{ return this->CutHere(ev, outAtomPtr, /*val*/ (void*) 0); }
};
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#define morkDerived_kAtomBodyMap /*i*/ 0x6142 /* ascii 'aB' */
#define morkAtomBodyMap_kStartSlotCount 512
/*| morkAtomBodyMap: keys of morkBookAtom organized by body bytes
|*/
class morkAtomBodyMap : public morkMap { // for mapping tokens to maps
// { ===== begin morkNode interface =====
public: // morkNode virtual methods
virtual void CloseMorkNode(morkEnv* ev); // CloseAtomBodyMap() only if open
virtual ~morkAtomBodyMap(); // assert CloseAtomBodyMap() executed earlier
public: // morkMap construction & destruction
morkAtomBodyMap(morkEnv* ev, const morkUsage& inUsage,
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap);
void CloseAtomBodyMap(morkEnv* ev); // called by CloseMorkNode();
public: // dynamic type identification
mork_bool IsAtomBodyMap() const
{ return IsNode() && mNode_Derived == morkDerived_kAtomBodyMap; }
// } ===== end morkNode methods =====
// { ===== begin morkMap poly interface =====
virtual mork_bool // note: equal(a,b) implies hash(a) == hash(b)
Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const;
// implemented using morkBookAtom::EqualFormAndBody()
virtual mork_u4 // note: equal(a,b) implies hash(a) == hash(b)
Hash(morkEnv* ev, const void* inKey) const;
// implemented using morkBookAtom::HashFormAndBody()
// } ===== end morkMap poly interface =====
public: // other map methods
mork_bool AddAtom(morkEnv* ev, morkBookAtom* ioAtom);
// AddAtom() returns ev->Good()
morkBookAtom* CutAtom(morkEnv* ev, const morkBookAtom* inAtom);
// CutAtom() returns the atom removed equal to inAtom, if there was one
morkBookAtom* GetAtom(morkEnv* ev, const morkBookAtom* inAtom);
// GetAtom() returns the atom equal to inAtom, or else nil
// note the atoms are owned elsewhere, usuall by morkAtomSpace
};
class morkAtomBodyMapIter: public morkMapIter{ // typesafe wrapper class
public:
morkAtomBodyMapIter(morkEnv* ev, morkAtomBodyMap* ioMap)
: morkMapIter(ev, ioMap) { }
morkAtomBodyMapIter( ) : morkMapIter() { }
void InitAtomBodyMapIter(morkEnv* ev, morkAtomBodyMap* ioMap)
{ this->InitMapIter(ev, ioMap); }
mork_change* FirstAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
{ return this->First(ev, outAtomPtr, /*val*/ (void*) 0); }
mork_change* NextAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
{ return this->Next(ev, outAtomPtr, /*val*/ (void*) 0); }
mork_change* HereAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
{ return this->Here(ev, outAtomPtr, /*val*/ (void*) 0); }
mork_change* CutHereAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
{ return this->CutHere(ev, outAtomPtr, /*val*/ (void*) 0); }
};
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#endif /* _MORKATOMMAP_ */

Просмотреть файл

@ -186,28 +186,28 @@ morkAtomSpace::MakeBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom)
morkBookAtom* outAtom = 0;
if ( ev->Good() )
{
if ( mSpace_Store->mStore_CanAutoAssignAtomIdentity )
{
morkPool* pool = this->GetSpaceStorePool();
morkBookAtom* atom = pool->NewBookAtomCopy(ev, inAtom);
if ( atom )
{
mork_aid id = this->MakeNewAtomId(ev, atom);
if ( id )
{
outAtom = atom;
atom->mBookAtom_Space = this;
mAtomSpace_AtomAids.AddAtom(ev, atom);
mAtomSpace_AtomBodies.AddAtom(ev, atom);
if ( mSpace_Scope == morkAtomSpace_kColumnScope )
outAtom->MakeCellUseForever(ev);
}
else
pool->ZapAtom(ev, atom);
}
}
else
mSpace_Store->CannotAutoAssignAtomIdentityError(ev);
if ( mSpace_Store->mStore_CanAutoAssignAtomIdentity )
{
morkPool* pool = this->GetSpaceStorePool();
morkBookAtom* atom = pool->NewBookAtomCopy(ev, inAtom);
if ( atom )
{
mork_aid id = this->MakeNewAtomId(ev, atom);
if ( id )
{
outAtom = atom;
atom->mBookAtom_Space = this;
mAtomSpace_AtomAids.AddAtom(ev, atom);
mAtomSpace_AtomBodies.AddAtom(ev, atom);
if ( mSpace_Scope == morkAtomSpace_kColumnScope )
outAtom->MakeCellUseForever(ev);
}
else
pool->ZapAtom(ev, atom);
}
}
else
mSpace_Store->CannotAutoAssignAtomIdentityError(ev);
}
return outAtom;
}

Просмотреть файл

@ -235,6 +235,7 @@ void
morkBuilder::LogGlitch(morkEnv* ev, const morkGlitch& inGlitch,
const char* inKind)
{
MORK_USED_2(inGlitch,inKind);
ev->NewWarning("parsing glitch");
}
@ -256,6 +257,7 @@ morkBuilder::OnNewPort(morkEnv* ev, const morkPlace& inPlace)
// mp:PortItem ::= mp:Content | mp:Group | OnPortGlitch
// mp:Content ::= mp:PortRow | mp:Dict | mp:Table | mp:Row
{
MORK_USED_2(ev,inPlace);
// mParser_InPort = morkBool_kTrue;
mBuilder_PortForm = 0;
mBuilder_PortRowScope = (mork_scope) 'r';
@ -272,6 +274,7 @@ morkBuilder::OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch)
morkBuilder::OnPortEnd(morkEnv* ev, const morkSpan& inSpan)
// mp:Start ::= OnNewPort mp:PortItem* OnPortEnd
{
MORK_USED_2(ev,inSpan);
// ev->StubMethodOnlyError();
// nothing to do?
// mParser_InPort = morkBool_kFalse;
@ -280,6 +283,7 @@ morkBuilder::OnPortEnd(morkEnv* ev, const morkSpan& inSpan)
/*virtual*/ void
morkBuilder::OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid)
{
MORK_USED_2(inPlace,inGid);
// mParser_InGroup = morkBool_kTrue;
ev->StubMethodOnlyError();
}
@ -293,6 +297,7 @@ morkBuilder::OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch)
/*virtual*/ void
morkBuilder::OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan)
{
MORK_USED_1(inSpan);
// mParser_InGroup = morkBool_kFalse;
ev->StubMethodOnlyError();
}
@ -300,6 +305,7 @@ morkBuilder::OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan)
/*virtual*/ void
morkBuilder::OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan)
{
MORK_USED_1(inSpan);
// mParser_InGroup = morkBool_kFalse;
ev->StubMethodOnlyError();
}
@ -308,6 +314,7 @@ morkBuilder::OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan)
morkBuilder::OnNewPortRow(morkEnv* ev, const morkPlace& inPlace,
const morkMid& inMid, mork_change inChange)
{
MORK_USED_3(inMid,inPlace,inChange);
// mParser_InPortRow = morkBool_kTrue;
ev->StubMethodOnlyError();
}
@ -321,6 +328,7 @@ morkBuilder::OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch)
/*virtual*/ void
morkBuilder::OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan)
{
MORK_USED_1(inSpan);
// mParser_InPortRow = morkBool_kFalse;
ev->StubMethodOnlyError();
}
@ -334,6 +342,7 @@ morkBuilder::OnNewTable(morkEnv* ev, const morkPlace& inPlace,
// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
// mp:MetaItem ::= mp:Cell | OnMetaGlitch
{
MORK_USED_2(inPlace,inChange);
// mParser_InTable = morkBool_kTrue;
mBuilder_TableForm = mBuilder_PortForm;
mBuilder_TableRowScope = mBuilder_PortRowScope;
@ -355,6 +364,7 @@ morkBuilder::OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch)
morkBuilder::OnTableEnd(morkEnv* ev, const morkSpan& inSpan)
// mp:Table ::= OnNewTable mp:TableItem* OnTableEnd
{
MORK_USED_1(inSpan);
// mParser_InTable = morkBool_kFalse;
if ( mBuilder_Table )
{
@ -381,6 +391,7 @@ morkBuilder::OnNewMeta(morkEnv* ev, const morkPlace& inPlace)
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
{
MORK_USED_2(ev,inPlace);
// mParser_InMeta = morkBool_kTrue;
}
@ -395,6 +406,7 @@ morkBuilder::OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch)
morkBuilder::OnMetaEnd(morkEnv* ev, const morkSpan& inSpan)
// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
{
MORK_USED_2(ev,inSpan);
// mParser_InMeta = morkBool_kFalse;
}
@ -410,6 +422,7 @@ morkBuilder::OnNewRow(morkEnv* ev, const morkPlace& inPlace,
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
{
MORK_USED_2(inPlace,inChange);
// mParser_InRow = morkBool_kTrue;
if ( mBuilder_Table )
{
@ -485,6 +498,7 @@ morkBuilder::FlushBuilderCells(morkEnv* ev)
morkBuilder::OnRowEnd(morkEnv* ev, const morkSpan& inSpan)
// mp:Row ::= OnNewRow mp:RowItem* OnRowEnd
{
MORK_USED_1(inSpan);
// mParser_InRow = morkBool_kFalse;
if ( mBuilder_Row )
{
@ -502,6 +516,7 @@ morkBuilder::OnNewDict(morkEnv* ev, const morkPlace& inPlace)
// mp:Dict ::= OnNewDict mp:DictItem* OnDictEnd
// mp:DictItem ::= OnAlias | OnAliasGlitch | mp:Meta | OnDictGlitch
{
MORK_USED_2(ev,inPlace);
// mParser_InDict = morkBool_kTrue;
mBuilder_CellForm = mBuilder_DictForm = mBuilder_PortForm;
@ -518,6 +533,7 @@ morkBuilder::OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch)
morkBuilder::OnDictEnd(morkEnv* ev, const morkSpan& inSpan)
// mp:Dict ::= OnNewDict mp:DictItem* OnDictEnd
{
MORK_USED_2(ev,inSpan);
// mParser_InDict = morkBool_kFalse;
mBuilder_DictForm = 0;
@ -528,6 +544,7 @@ morkBuilder::OnDictEnd(morkEnv* ev, const morkSpan& inSpan)
morkBuilder::OnAlias(morkEnv* ev, const morkSpan& inSpan,
const morkMid& inMid)
{
MORK_USED_1(inSpan);
if ( mParser_InDict )
{
morkMid mid = inMid; // local copy for modification
@ -583,6 +600,7 @@ morkBuilder::OnNewCell(morkEnv* ev, const morkPlace& inPlace,
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
{
MORK_USED_1(inPlace);
// mParser_InCell = morkBool_kTrue;
mBuilder_CellAtomScope = mBuilder_RowAtomScope;
@ -699,6 +717,7 @@ morkBuilder::OnCellForm(morkEnv* ev, mork_cscode inCharsetFormat)
morkBuilder::OnCellEnd(morkEnv* ev, const morkSpan& inSpan)
// mp:Cell ::= OnNewCell mp:CellItem? OnCellEnd
{
MORK_USED_2(ev,inSpan);
// mParser_InCell = morkBool_kFalse;
mBuilder_MetaTokenSlot = 0;
@ -711,6 +730,7 @@ morkBuilder::OnValue(morkEnv* ev, const morkSpan& inSpan,
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
{
MORK_USED_1(inSpan);
morkStore* store = mBuilder_Store;
morkCell* cell = mBuilder_Cell;
if ( cell )
@ -751,6 +771,7 @@ morkBuilder::OnValueMid(morkEnv* ev, const morkSpan& inSpan,
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
{
MORK_USED_1(inSpan);
morkStore* store = mBuilder_Store;
morkCell* cell = mBuilder_Cell;
@ -779,7 +800,7 @@ morkBuilder::OnValueMid(morkEnv* ev, const morkSpan& inSpan,
mork_token* metaSlot = mBuilder_MetaTokenSlot;
if ( metaSlot )
{
mork_scope valScope = valOid->mOid_Scope;
mork_scope valScope = valOid->mOid_Scope;
if ( !valScope || valScope == morkStore_kColumnSpaceScope )
{
if ( ev->Good() && valMid.HasSomeId() )
@ -810,6 +831,7 @@ morkBuilder::OnRowMid(morkEnv* ev, const morkSpan& inSpan,
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
{
MORK_USED_1(inSpan);
morkStore* store = mBuilder_Store;
morkCell* cell = mBuilder_Cell;
if ( cell )
@ -846,6 +868,7 @@ morkBuilder::OnTableMid(morkEnv* ev, const morkSpan& inSpan,
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
// mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
{
MORK_USED_1(inSpan);
morkStore* store = mBuilder_Store;
morkCell* cell = mBuilder_Cell;
if ( cell )

Просмотреть файл

@ -57,12 +57,14 @@ morkCell::SetYarn(morkEnv* ev, const mdbYarn* inYarn, morkStore* ioStore)
void
morkCell::GetYarn(morkEnv* ev, mdbYarn* outYarn) const
{
MORK_USED_1(ev);
mCell_Atom->GetYarn(outYarn);
}
void
morkCell::AliasYarn(morkEnv* ev, mdbYarn* outYarn) const
{
MORK_USED_1(ev);
mCell_Atom->AliasYarn(outYarn);
}

Просмотреть файл

@ -1,236 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _MDB_
#include "mdb.h"
#endif
#ifndef _MORK_
#include "mork.h"
#endif
#ifndef _MORKNODE_
#include "morkNode.h"
#endif
#ifndef _MORKOBJECT_
#include "morkObject.h"
#endif
#ifndef _MORKENV_
#include "morkEnv.h"
#endif
#ifndef _MORKCELLOBJECT_
#include "morkCellObject.h"
#endif
#ifndef _MORKROWOBJECT_
#include "morkRowObject.h"
#endif
#ifndef _MORKROW_
#include "morkRow.h"
#endif
#ifndef _MORKCELL_
#include "morkCell.h"
#endif
#ifndef _ORKINCELL_
#include "orkinCell.h"
#endif
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
// ````` ````` ````` ````` `````
// { ===== begin morkNode interface =====
/*public virtual*/ void
morkCellObject::CloseMorkNode(morkEnv* ev) // CloseCellObject() only if open
{
if ( this->IsOpenNode() )
{
this->MarkClosing();
this->CloseCellObject(ev);
this->MarkShut();
}
}
/*public virtual*/
morkCellObject::~morkCellObject() // assert CloseCellObject() executed earlier
{
MORK_ASSERT(mCellObject_Row==0);
}
/*public non-poly*/
morkCellObject::morkCellObject(morkEnv* ev, const morkUsage& inUsage,
nsIMdbHeap* ioHeap, morkRow* ioRow, morkCell* ioCell,
mork_column inCol, mork_pos inPos)
: morkObject(ev, inUsage, ioHeap, (morkHandle*) 0)
, mCellObject_RowObject( 0 )
, mCellObject_Row( 0 )
, mCellObject_Cell( 0 )
, mCellObject_Col( inCol )
, mCellObject_RowSeed( 0 )
, mCellObject_Pos( (mork_u2) inPos )
{
if ( ev->Good() )
{
if ( ioRow && ioCell )
{
if ( ioRow->IsRow() )
{
morkStore* store = ioRow->GetRowSpaceStore(ev);
if ( store )
{
morkRowObject* rowObj = ioRow->AcquireRowObject(ev, store);
if ( rowObj )
{
mCellObject_Row = ioRow;
mCellObject_Cell = ioCell;
mCellObject_RowSeed = ioRow->mRow_Seed;
// morkRowObject::SlotStrongRowObject(rowObj, ev,
// &mCellObject_RowObject);
mCellObject_RowObject = rowObj; // assume control of strong ref
}
if ( ev->Good() )
mNode_Derived = morkDerived_kCellObject;
}
}
else
ioRow->NonRowTypeError(ev);
}
else
ev->NilPointerError();
}
}
/*public non-poly*/ void
morkCellObject::CloseCellObject(morkEnv* ev) // called by CloseMorkNode();
{
if ( this )
{
if ( this->IsNode() )
{
morkRowObject::SlotStrongRowObject((morkRowObject*) 0, ev,
&mCellObject_RowObject);
mCellObject_Row = 0;
mCellObject_Cell = 0;
mCellObject_RowSeed = 0;
this->CloseObject(ev);
this->MarkShut();
}
else
this->NonNodeError(ev);
}
else
ev->NilPointerError();
}
// } ===== end morkNode methods =====
// ````` ````` ````` ````` `````
mork_bool
morkCellObject::ResyncWithRow(morkEnv* ev)
{
morkRow* row = mCellObject_Row;
mork_pos pos = 0;
morkCell* cell = row->GetCell(ev, mCellObject_Col, &pos);
if ( cell )
{
mCellObject_Pos = pos;
mCellObject_Cell = cell;
mCellObject_RowSeed = row->mRow_Seed;
}
else
{
mCellObject_Cell = 0;
this->MissingRowColumnError(ev);
}
return ev->Good();
}
morkAtom*
morkCellObject::GetCellAtom(morkEnv* ev) const
{
morkCell* cell = mCellObject_Cell;
if ( cell )
return cell->GetAtom();
else
this->NilCellError(ev);
return (morkAtom*) 0;
}
/*static*/ void
morkCellObject::WrongRowObjectRowError(morkEnv* ev)
{
ev->NewError("mCellObject_Row != mCellObject_RowObject->mRowObject_Row");
}
/*static*/ void
morkCellObject::NilRowError(morkEnv* ev)
{
ev->NewError("nil mCellObject_Row");
}
/*static*/ void
morkCellObject::NilRowObjectError(morkEnv* ev)
{
ev->NewError("nil mCellObject_RowObject");
}
/*static*/ void
morkCellObject::NilCellError(morkEnv* ev)
{
ev->NewError("nil mCellObject_Cell");
}
/*static*/ void
morkCellObject::NonCellObjectTypeError(morkEnv* ev)
{
ev->NewError("non morkCellObject");
}
/*static*/ void
morkCellObject::MissingRowColumnError(morkEnv* ev)
{
ev->NewError("mCellObject_Col not in mCellObject_Row");
}
nsIMdbCell*
morkCellObject::AcquireCellHandle(morkEnv* ev)
{
nsIMdbCell* outCell = 0;
orkinCell* c = (orkinCell*) mObject_Handle;
if ( c ) // have an old handle?
c->AddStrongRef(ev->AsMdbEnv());
else // need new handle?
{
c = orkinCell::MakeCell(ev, this);
mObject_Handle = c;
}
if ( c )
outCell = c;
return outCell;
}
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

Просмотреть файл

@ -1,250 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _MDB_
#include "mdb.h"
#endif
#ifndef _MORK_
#include "mork.h"
#endif
#ifndef _MORKCONFIG_
#include "morkConfig.h"
#endif
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
/* ----- ----- ----- ----- MORK_OBSOLETE ----- ----- ----- ----- */
#ifdef MORK_OBSOLETE
#include <Types.h>
#include "plstr.h"
static void // copied almost verbatim from the IronDoc debugger sources:
mork_mac_break_string(register const char* inMessage) /*i*/
{
Str255 pascalStr; // to hold Pascal string version of inMessage
mork_u4 length = PL_strlen(inMessage);
// if longer than maximum 255 bytes, just copy 255 bytes worth
pascalStr[ 0 ] = (length > 255)? 255 : length;
if ( length ) // anything to copy? */
{
register mork_u1* p = ((mork_u1*) &pascalStr) + 1; // after length byte
register mork_u1* end = p + length; // one past last byte to copy
while ( p < end ) // more bytes to copy?
{
register int c = (mork_u1) *inMessage++;
if ( c == ';' ) // c is the MacsBug ';' metacharacter?
c = ':'; // change to ':', rendering harmless in a MacsBug context
*p++ = (mork_u1) c;
}
}
DebugStr(pascalStr); /* call Mac debugger entry point */
}
#endif /*MORK_OBSOLETE*/
/* ----- ----- ----- ----- MORK_OBSOLETE ----- ----- ----- ----- */
void mork_assertion_signal(const char* inMessage)
{
#ifdef MORK_OBSOLETE
mork_mac_break_string(inMessage);
#endif /*MORK_OBSOLETE*/
#if defined(MORK_WIN) || defined(MORK_MAC)
// asm { int 3 }
NS_ASSERTION(0, inMessage);
#endif /*MORK_WIN*/
}
#ifdef MORK_PROVIDE_STDLIB
MORK_LIB_IMPL(mork_i4)
mork_memcmp(const void* inOne, const void* inTwo, mork_size inSize)
{
register const mork_u1* t = (const mork_u1*) inTwo;
register const mork_u1* s = (const mork_u1*) inOne;
const mork_u1* end = s + inSize;
register mork_i4 delta;
while ( s < end )
{
delta = ((mork_i4) *s) - ((mork_i4) *t);
if ( delta )
return delta;
else
{
++t;
++s;
}
}
return 0;
}
MORK_LIB_IMPL(void)
mork_memcpy(void* outDst, const void* inSrc, mork_size inSize)
{
register mork_u1* d = (mork_u1*) outDst;
mork_u1* end = d + inSize;
register const mork_u1* s = ((const mork_u1*) inSrc);
while ( inSize >= 8 )
{
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
inSize -= 8;
}
while ( d < end )
*d++ = *s++;
}
MORK_LIB_IMPL(void)
mork_memmove(void* outDst, const void* inSrc, mork_size inSize)
{
register mork_u1* d = (mork_u1*) outDst;
register const mork_u1* s = (const mork_u1*) inSrc;
if ( d != s && inSize ) // copy is necessary?
{
const mork_u1* srcEnd = s + inSize; // one past last source byte
if ( d > s && d < srcEnd ) // overlap? need to copy backwards?
{
s = srcEnd; // start one past last source byte
d += inSize; // start one past last dest byte
mork_u1* dstBegin = d; // last byte to write is first in dest range
while ( d - dstBegin >= 8 )
{
*--d = *--s;
*--d = *--s;
*--d = *--s;
*--d = *--s;
*--d = *--s;
*--d = *--s;
*--d = *--s;
*--d = *--s;
}
while ( d > dstBegin )
*--d = *--s;
}
else // can copy forwards without any overlap
{
mork_u1* dstEnd = d + inSize;
while ( dstEnd - d >= 8 )
{
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
while ( d < dstEnd )
*d++ = *s++;
}
}
}
MORK_LIB_IMPL(void)
mork_memset(void* outDst, int inByte, mork_size inSize)
{
register mork_u1* d = (mork_u1*) outDst;
mork_u1* end = d + inSize;
while ( d < end )
*d++ = (mork_u1) inByte;
}
MORK_LIB_IMPL(void)
mork_strcpy(void* outDst, const void* inSrc)
{
// back up one first to support preincrement
register mork_u1* d = ((mork_u1*) outDst) - 1;
register const mork_u1* s = ((const mork_u1*) inSrc) - 1;
while ( ( *++d = *++s ) != 0 )
/* empty */;
}
MORK_LIB_IMPL(mork_i4)
mork_strcmp(const void* inOne, const void* inTwo)
{
register const mork_u1* t = (const mork_u1*) inTwo;
register const mork_u1* s = ((const mork_u1*) inOne);
register mork_i4 a;
register mork_i4 b;
register mork_i4 delta;
do
{
a = (mork_i4) *s++;
b = (mork_i4) *t++;
delta = a - b;
}
while ( !delta && a && b );
return delta;
}
MORK_LIB_IMPL(mork_i4)
mork_strncmp(const void* inOne, const void* inTwo, mork_size inSize)
{
register const mork_u1* t = (const mork_u1*) inTwo;
register const mork_u1* s = (const mork_u1*) inOne;
const mork_u1* end = s + inSize;
register mork_i4 delta;
register mork_i4 a;
register mork_i4 b;
while ( s < end )
{
a = (mork_i4) *s++;
b = (mork_i4) *t++;
delta = a - b;
if ( delta || !a || !b )
return delta;
}
return 0;
}
MORK_LIB_IMPL(mork_size)
mork_strlen(const void* inString)
{
// back up one first to support preincrement
register const mork_u1* s = ((const mork_u1*) inString) - 1;
while ( *++s ) // preincrement is cheapest
/* empty */;
return s - ((const mork_u1*) inString); // distance from original address
}
#endif /*MORK_PROVIDE_STDLIB*/
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

Просмотреть файл

@ -30,6 +30,10 @@
#endif
// { %%%%% begin platform defs peculiar to Mork %%%%%
//#define XP_MAC 1
//#define MORK_ALONE 1
#ifdef XP_MAC
#define MORK_MAC 1
#endif
@ -59,7 +63,10 @@
#include "errno.h"
#include "string.h"
#include "memory.h"
#ifndef MORK_ALONE
#include "nsDebug.h"
#endif /*MORK_ALONE*/
#define MORK_ISPRINT(c) isprint(c)

Просмотреть файл

@ -92,7 +92,7 @@ morkDeque::IndexOf(const morkLink* member) const /*i*/
{
++count;
if ( member == link )
return count;
return (mork_pos) count;
}
return 0;
}

Просмотреть файл

@ -185,15 +185,15 @@ morkEnv::OidAsHex(void* outBuf, const mdbOid& inOid)
mork_scope scope = inOid.mOid_Scope;
if ( scope < 0x80 && morkCh_IsName((mork_ch) scope) )
{
*p++ = (mork_u1) scope;
*p = 0; // null termination
outSize += 2;
*p++ = (mork_u1) scope;
*p = 0; // null termination
outSize += 2;
}
else
{
*p++ = '^';
mork_size scopeSize = this->TokenAsHex(p, scope);
outSize += scopeSize + 2;
*p++ = '^';
mork_size scopeSize = this->TokenAsHex(p, scope);
outSize += scopeSize + 2;
}
return outSize;
}
@ -205,20 +205,20 @@ morkEnv::HexToByte(mork_ch inFirstHex, mork_ch inSecondHex)
mork_u1 hi = 0; // high four hex bits
mork_flags f = morkCh_GetFlags(inFirstHex);
if ( morkFlags_IsDigit(f) )
hi = inFirstHex - '0';
hi = (mork_u1) (inFirstHex - (mork_ch) '0');
else if ( morkFlags_IsUpper(f) )
hi = (inFirstHex - 'A') + 10;
hi = (mork_u1) ((inFirstHex - (mork_ch) 'A') + 10);
else if ( morkFlags_IsLower(f) )
hi = (inFirstHex - 'a') + 10;
hi = (mork_u1) ((inFirstHex - (mork_ch) 'a') + 10);
mork_u1 lo = 0; // low four hex bits
f = morkCh_GetFlags(inSecondHex);
if ( morkFlags_IsDigit(f) )
lo = inSecondHex - '0';
lo = (mork_u1) (inSecondHex - (mork_ch) '0');
else if ( morkFlags_IsUpper(f) )
lo = (inSecondHex - 'A') + 10;
lo = (mork_u1) ((inSecondHex - (mork_ch) 'A') + 10);
else if ( morkFlags_IsLower(f) )
lo = (inSecondHex - 'a') + 10;
lo = (mork_u1) ((inSecondHex - (mork_ch) 'a') + 10);
return (mork_u1) ((hi << 4) | lo);
}
@ -240,7 +240,7 @@ morkEnv::TokenAsHex(void* outBuf, mork_token inToken)
}
*p = 0; // end the string with a null byte
char* s = (char*) outBuf; // first byte in string
mork_size size = p - s; // distance from start
mork_size size = (mork_size) (p - s); // distance from start
// now reverse the string in place:
// note that p starts on the null byte, so we need predecrement:
@ -311,7 +311,7 @@ morkEnv::NewErrorAndCode(const char* inString, mork_u2 inCode)
MORK_ASSERT(morkBool_kFalse); // get developer's attention
++mEnv_ErrorCount;
mEnv_ErrorCode = (inCode)? inCode: morkEnv_kGenericError;
mEnv_ErrorCode = (mork_u4) ((inCode)? inCode: morkEnv_kGenericError);
if ( mEnv_ErrorHook )
mEnv_ErrorHook->OnErrorString(this->AsMdbEnv(), inString);

Просмотреть файл

@ -373,6 +373,7 @@ morkStdioFile::AcquireBud(morkEnv* ev, nsIMdbHeap* ioHeap)
// behavior is exhibited by the file, so crashes protect old files.
// Note that AcquireBud() is an illegal operation on readonly files.
{
MORK_USED_1(ioHeap);
morkFile* outFile = 0;
if ( this->IsOpenAndActiveFile() )
{
@ -491,7 +492,7 @@ morkStdioFile::Read(morkEnv* ev, void* outBuf, mork_size inSize)
FILE* file = (FILE*) mStdioFile_File;
if ( file )
{
long count = MORK_FILEREAD(outBuf, inSize, file);
long count = (long) MORK_FILEREAD(outBuf, inSize, file);
if ( count >= 0 )
{
outCount = (mork_num) count;

Просмотреть файл

@ -132,10 +132,10 @@ public: // non-poly morkFile methods
mork_bool FileIoOpen() const { return mFile_IoOpen == 'O'; }
mork_bool FileActive() const { return mFile_Active == 'A'; }
void SetFileFrozen(mork_bool b) { mFile_Frozen = (b)? 'F' : 0; }
void SetFileDoTrace(mork_bool b) { mFile_DoTrace = (b)? 'T' : 0; }
void SetFileIoOpen(mork_bool b) { mFile_IoOpen = (b)? 'O' : 0; }
void SetFileActive(mork_bool b) { mFile_Active = (b)? 'A' : 0; }
void SetFileFrozen(mork_bool b) { mFile_Frozen = (mork_u1) ((b)? 'F' : 0); }
void SetFileDoTrace(mork_bool b) { mFile_DoTrace = (mork_u1) ((b)? 'T' : 0); }
void SetFileIoOpen(mork_bool b) { mFile_IoOpen = (mork_u1) ((b)? 'O' : 0); }
void SetFileActive(mork_bool b) { mFile_Active = (mork_u1) ((b)? 'A' : 0); }
mork_bool IsOpenActiveAndMutableFile() const

Просмотреть файл

@ -147,6 +147,7 @@ void morkHandle::NonOpenObjectError(morkEnv* ev) const
void morkHandle::NewBadMagicHandleError(morkEnv* ev, mork_magic inMagic) const
{
MORK_USED_1(inMagic);
ev->NewError("wrong mHandle_Magic");
}
@ -393,6 +394,7 @@ morkHandle::Handle_CloseMdbObject(nsIMdbEnv* mev)
/*virtual*/ mdb_err
morkHandle::Handle_IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen)
{
MORK_USED_1(mev);
mdb_err outErr = 0;
MORK_ASSERT(outOpen);

Просмотреть файл

@ -100,7 +100,7 @@ public: // morkHandle memory management operators
{ return ioPool.NewHandle(ev, inSize); }
void* operator new(size_t inSize, morkHandleFace* ioFace)
{ return ioFace; }
{ MORK_USED_1(inSize); return ioFace; }
void operator delete(void* ioAddress)
{ morkNode::OnDeleteAssert(ioAddress); }

Просмотреть файл

@ -1,148 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _MDB_
#include "mdb.h"
#endif
#ifndef _MORK_
#include "mork.h"
#endif
#ifndef _MORKNODE_
#include "morkNode.h"
#endif
#ifndef _MORKENV_
#include "morkEnv.h"
#endif
#ifndef _MORKMAP_
#include "morkMap.h"
#endif
#ifndef _MORKINTMAP_
#include "morkIntMap.h"
#endif
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
// ````` ````` ````` ````` `````
// { ===== begin morkNode interface =====
/*public virtual*/ void
morkIntMap::CloseMorkNode(morkEnv* ev) // CloseIntMap() only if open
{
if ( this->IsOpenNode() )
{
this->MarkClosing();
this->CloseIntMap(ev);
this->MarkShut();
}
}
/*public virtual*/
morkIntMap::~morkIntMap() // assert CloseIntMap() executed earlier
{
MORK_ASSERT(this->IsShutNode());
}
/*public non-poly*/
morkIntMap::morkIntMap(morkEnv* ev,
const morkUsage& inUsage, mork_size inValSize,
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_bool inHoldChanges)
: morkMap(ev, inUsage, ioHeap, sizeof(mork_u4), inValSize,
morkIntMap_kStartSlotCount, ioSlotHeap, inHoldChanges)
{
if ( ev->Good() )
mNode_Derived = morkDerived_kIntMap;
}
/*public non-poly*/ void
morkIntMap::CloseIntMap(morkEnv* ev) // called by CloseMorkNode();
{
if ( this )
{
if ( this->IsNode() )
{
this->CloseMap(ev);
this->MarkShut();
}
else
this->NonNodeError(ev);
}
else
ev->NilPointerError();
}
// } ===== end morkNode methods =====
// ````` ````` ````` ````` `````
// { ===== begin morkMap poly interface =====
/*virtual*/ mork_bool // *((mork_u4*) inKeyA) == *((mork_u4*) inKeyB)
morkIntMap::Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const
{
return *((const mork_u4*) inKeyA) == *((const mork_u4*) inKeyB);
}
/*virtual*/ mork_u4 // some integer function of *((mork_u4*) inKey)
morkIntMap::Hash(morkEnv* ev, const void* inKey) const
{
return *((const mork_u4*) inKey);
}
// } ===== end morkMap poly interface =====
mork_bool
morkIntMap::AddInt(morkEnv* ev, mork_u4 inKey, void* ioAddress)
// the AddInt() method return value equals ev->Good().
{
if ( ev->Good() )
{
this->Put(ev, &inKey, &ioAddress,
/*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0);
}
return ev->Good();
}
mork_bool
morkIntMap::CutInt(morkEnv* ev, mork_u4 inKey)
{
return this->Cut(ev, &inKey, /*key*/ (void*) 0, /*val*/ (void*) 0,
(mork_change**) 0);
}
void*
morkIntMap::GetInt(morkEnv* ev, mork_u4 inKey)
// Note the returned val does NOT have an increase in refcount for this.
{
void* val = 0; // old val in the map
this->Get(ev, &inKey, /*key*/ (void*) 0, &val, (mork_change**) 0);
return val;
}
mork_bool
morkIntMap::HasInt(morkEnv* ev, mork_u4 inKey)
// Note the returned val does NOT have an increase in refcount for this.
{
return this->Get(ev, &inKey, /*key*/ (void*) 0, /*val*/ (void*) 0,
(mork_change**) 0);
}
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

Просмотреть файл

@ -1,87 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _MORKINTMAP_
#define _MORKINTMAP_ 1
#ifndef _MORK_
#include "mork.h"
#endif
#ifndef _MORKNODE_
#include "morkNode.h"
#endif
#ifndef _MORKMAP_
#include "morkMap.h"
#endif
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#define morkDerived_kIntMap /*i*/ 0x694D /* ascii 'iM' */
#define morkIntMap_kStartSlotCount 512
/*| morkIntMap: maps mork_token -> morkNode
|*/
class morkIntMap : public morkMap { // for mapping tokens to maps
// { ===== begin morkNode interface =====
public: // morkNode virtual methods
virtual void CloseMorkNode(morkEnv* ev); // CloseIntMap() only if open
virtual ~morkIntMap(); // assert that CloseIntMap() executed earlier
public: // morkMap construction & destruction
// keySize for morkIntMap equals sizeof(mork_u4)
morkIntMap(morkEnv* ev, const morkUsage& inUsage, mork_size inValSize,
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_bool inHoldChanges);
void CloseIntMap(morkEnv* ev); // called by CloseMorkNode();
public: // dynamic type identification
mork_bool IsIntMap() const
{ return IsNode() && mNode_Derived == morkDerived_kIntMap; }
// } ===== end morkNode methods =====
// { ===== begin morkMap poly interface =====
virtual mork_bool // *((mork_u4*) inKeyA) == *((mork_u4*) inKeyB)
Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const;
virtual mork_u4 // some integer function of *((mork_u4*) inKey)
Hash(morkEnv* ev, const void* inKey) const;
// } ===== end morkMap poly interface =====
public: // other map methods
mork_bool AddInt(morkEnv* ev, mork_u4 inKey, void* ioAddress);
// the AddInt() boolean return equals ev->Good().
mork_bool CutInt(morkEnv* ev, mork_token inKey);
// The CutInt() boolean return indicates whether removal happened.
void* GetInt(morkEnv* ev, mork_token inKey);
// Note the returned node does NOT have an increase in refcount for this.
mork_bool HasInt(morkEnv* ev, mork_u4 inKey);
// Note the returned node does NOT have an increase in refcount for this.
};
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#endif /* _MORKINTMAP_ */

Просмотреть файл

@ -1,937 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
// This code is mostly a port to C++ from public domain IronDoc C sources.
// Note many code comments here come verbatim from cut-and-pasted IronDoc.
#ifndef _MDB_
#include "mdb.h"
#endif
#ifndef _MORK_
#include "mork.h"
#endif
#ifndef _MORKNODE_
#include "morkNode.h"
#endif
#ifndef _MORKMAP_
#include "morkMap.h"
#endif
#ifndef _MORKENV_
#include "morkEnv.h"
#endif
class morkHashArrays {
public:
nsIMdbHeap* mHashArrays_Heap; // copy of mMap_Heap
mork_count mHashArrays_Slots; // copy of mMap_Slots
mork_u1* mHashArrays_Keys; // copy of mMap_Keys
mork_u1* mHashArrays_Vals; // copy of mMap_Vals
morkAssoc* mHashArrays_Assocs; // copy of mMap_Assocs
mork_change* mHashArrays_Changes; // copy of mMap_Changes
morkAssoc** mHashArrays_Buckets; // copy of mMap_Buckets
morkAssoc* mHashArrays_FreeList; // copy of mMap_FreeList
public:
void finalize(morkEnv* ev);
};
void morkHashArrays::finalize(morkEnv* ev)
{
nsIMdbEnv* menv = ev->AsMdbEnv();
nsIMdbHeap* heap = mHashArrays_Heap;
if ( heap )
{
if ( mHashArrays_Keys )
heap->Free(menv, mHashArrays_Keys);
if ( mHashArrays_Vals )
heap->Free(menv, mHashArrays_Vals);
if ( mHashArrays_Assocs )
heap->Free(menv, mHashArrays_Assocs);
if ( mHashArrays_Changes )
heap->Free(menv, mHashArrays_Changes);
if ( mHashArrays_Buckets )
heap->Free(menv, mHashArrays_Buckets);
}
}
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
// ````` ````` ````` ````` `````
// { ===== begin morkNode interface =====
/*public virtual*/ void
morkMap::CloseMorkNode(morkEnv* ev) // CloseMap() only if open
{
if ( this->IsOpenNode() )
{
this->MarkClosing();
this->CloseMap(ev);
this->MarkShut();
}
}
/*public virtual*/
morkMap::~morkMap() // assert CloseMap() executed earlier
{
MORK_ASSERT(mMap_FreeList==0);
MORK_ASSERT(mMap_Buckets==0);
MORK_ASSERT(mMap_Keys==0);
MORK_ASSERT(mMap_Vals==0);
MORK_ASSERT(mMap_Changes==0);
MORK_ASSERT(mMap_Assocs==0);
}
/*public non-poly*/ void
morkMap::CloseMap(morkEnv* ev) // called by CloseMorkNode();
{
if ( this )
{
if ( this->IsNode() )
{
nsIMdbHeap* heap = mMap_Heap;
if ( heap ) /* need to free the arrays? */
{
nsIMdbEnv* menv = ev->AsMdbEnv();
if ( mMap_Keys )
heap->Free(menv, mMap_Keys);
if ( mMap_Vals )
heap->Free(menv, mMap_Vals);
if ( mMap_Assocs )
heap->Free(menv, mMap_Assocs);
if ( mMap_Buckets )
heap->Free(menv, mMap_Buckets);
if ( mMap_Changes )
heap->Free(menv, mMap_Changes);
}
mMap_Keys = 0;
mMap_Vals = 0;
mMap_Buckets = 0;
mMap_Assocs = 0;
mMap_Changes = 0;
mMap_FreeList = 0;
MORK_MEMSET(&mMap_Form, 0, sizeof(morkMapForm));
this->MarkShut();
}
else
this->NonNodeError(ev);
}
else
ev->NilPointerError();
}
// } ===== end morkNode methods =====
// ````` ````` ````` ````` `````
void
morkMap::clear_map(morkEnv* ev, nsIMdbHeap* ioSlotHeap)
{
mMap_Tag = 0;
mMap_Seed = 0;
mMap_Slots = 0;
mMap_Fill = 0;
mMap_Keys = 0;
mMap_Vals = 0;
mMap_Assocs = 0;
mMap_Changes = 0;
mMap_Buckets = 0;
mMap_FreeList = 0;
MORK_MEMSET(&mMap_Form, 0, sizeof(morkMapForm));
mMap_Heap = 0;
if ( ioSlotHeap )
{
nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mMap_Heap);
}
else
ev->NilPointerError();
}
morkMap::morkMap(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
mork_size inKeySize, mork_size inValSize,
mork_size inSlots, nsIMdbHeap* ioSlotHeap, mork_bool inHoldChanges)
: morkNode(ev, inUsage, ioHeap)
, mMap_Heap( 0 )
{
if ( ev->Good() )
{
this->clear_map(ev, ioSlotHeap);
if ( ev->Good() )
{
mMap_Form.mMapForm_HoldChanges = inHoldChanges;
mMap_Form.mMapForm_KeySize = inKeySize;
mMap_Form.mMapForm_ValSize = inValSize;
mMap_Form.mMapForm_KeyIsIP = ( inKeySize == sizeof(mork_ip) );
mMap_Form.mMapForm_ValIsIP = ( inValSize == sizeof(mork_ip) );
this->InitMap(ev, inSlots);
if ( ev->Good() )
mNode_Derived = morkDerived_kMap;
}
}
}
void
morkMap::NewIterOutOfSyncError(morkEnv* ev)
{
ev->NewError("map iter out of sync");
}
void morkMap::NewBadMapError(morkEnv* ev)
{
ev->NewError("bad morkMap tag");
if ( !this )
ev->NewError("nil morkMap instance");
}
void morkMap::NewSlotsUnderflowWarning(morkEnv* ev)
{
ev->NewWarning("member count underflow");
}
void morkMap::InitMap(morkEnv* ev, mork_size inSlots)
{
if ( ev->Good() )
{
morkHashArrays old;
// MORK_MEMCPY(&mMap_Form, &inForm, sizeof(morkMapForm));
if ( inSlots < 3 ) /* requested capacity absurdly small? */
inSlots = 3; /* bump it up to a minimum practical level */
else if ( inSlots > (128 * 1024) ) /* requested slots absurdly big? */
inSlots = (128 * 1024); /* decrease it to a maximum practical level */
if ( this->new_arrays(ev, &old, inSlots) )
mMap_Tag = morkMap_kTag;
MORK_MEMSET(&old, 0, sizeof(morkHashArrays)); // do NOT finalize
}
}
morkAssoc**
morkMap::find(morkEnv* ev, const void* inKey, mork_u4 inHash) const
{
mork_u1* keys = mMap_Keys;
mork_num keySize = this->FormKeySize();
// morkMap_mEqual equal = this->FormEqual();
morkAssoc** ref = mMap_Buckets + (inHash % mMap_Slots);
morkAssoc* assoc = *ref;
while ( assoc ) /* look at another assoc in the bucket? */
{
mork_pos i = assoc - mMap_Assocs; /* index of this assoc */
if ( this->Equal(ev, keys + (i * keySize), inKey) ) /* found? */
return ref;
ref = &assoc->mAssoc_Next; /* consider next assoc slot in bucket */
assoc = *ref; /* if this is null, then we are done */
}
return 0;
}
/*| get_assoc: read the key and/or value at index inPos
|*/
void
morkMap::get_assoc(void* outKey, void* outVal, mork_pos inPos) const
{
mork_num valSize = this->FormValSize();
if ( valSize && outVal ) /* map holds values? caller wants the value? */
{
const mork_u1* value = mMap_Vals + (valSize * inPos);
if ( valSize == sizeof(mork_ip) && this->FormValIsIP() ) /* ip case? */
*((mork_ip*) outVal) = *((const mork_ip*) value);
else
MORK_MEMCPY(outVal, value, valSize);
}
if ( outKey ) /* caller wants the key? */
{
mork_num keySize = this->FormKeySize();
const mork_u1* key = mMap_Keys + (keySize * inPos);
if ( keySize == sizeof(mork_ip) && this->FormKeyIsIP() ) /* ip case? */
*((mork_ip*) outKey) = *((const mork_ip*) key);
else
MORK_MEMCPY(outKey, key, keySize);
}
}
/*| put_assoc: write the key and/or value at index inPos
|*/
void
morkMap::put_assoc(const void* inKey, const void* inVal, mork_pos inPos) const
{
mork_num valSize = this->FormValSize();
if ( valSize && inVal ) /* map holds values? caller sends a value? */
{
mork_u1* value = mMap_Vals + (valSize * inPos);
if ( valSize == sizeof(mork_ip) && this->FormValIsIP() ) /* ip case? */
*((mork_ip*) value) = *((const mork_ip*) inVal);
else
MORK_MEMCPY(value, inVal, valSize);
}
if ( inKey ) /* caller sends a key? */
{
mork_num keySize = this->FormKeySize();
mork_u1* key = mMap_Keys + (keySize * inPos);
if ( keySize == sizeof(mork_ip) && this->FormKeyIsIP() ) /* ip case? */
*((mork_ip*) key) = *((const mork_ip*) inKey);
else
MORK_MEMCPY(key, inKey, keySize);
}
}
void*
morkMap::clear_alloc(morkEnv* ev, mork_size inSize)
{
void* p = 0;
nsIMdbHeap* heap = mMap_Heap;
if ( heap )
{
if ( heap->Alloc(ev->AsMdbEnv(), inSize, (void**) &p) == 0 && p )
{
MORK_MEMSET(p, 0, inSize);
return p;
}
}
else
ev->NilPointerError();
return (void*) 0;
}
void*
morkMap::alloc(morkEnv* ev, mork_size inSize)
{
void* p = 0;
nsIMdbHeap* heap = mMap_Heap;
if ( heap )
{
if ( heap->Alloc(ev->AsMdbEnv(), inSize, (void**) &p) == 0 && p )
return p;
}
else
ev->NilPointerError();
return (void*) 0;
}
/*| new_keys: allocate an array of inSlots new keys filled with zero.
|*/
mork_u1*
morkMap::new_keys(morkEnv* ev, mork_num inSlots)
{
mork_num size = inSlots * this->FormKeySize();
return (mork_u1*) this->clear_alloc(ev, size);
}
/*| new_values: allocate an array of inSlots new values filled with zero.
**| When values are zero sized, we just return a null pointer.
|*/
mork_u1*
morkMap::new_values(morkEnv* ev, mork_num inSlots)
{
mork_u1* values = 0;
mork_num size = inSlots * this->FormValSize();
if ( size )
values = (mork_u1*) this->clear_alloc(ev, size);
return values;
}
mork_change*
morkMap::new_changes(morkEnv* ev, mork_num inSlots)
{
mork_change* changes = 0;
mork_num size = inSlots * sizeof(mork_change);
if ( size && mMap_Form.mMapForm_HoldChanges )
changes = (mork_change*) this->clear_alloc(ev, size);
return changes;
}
/*| new_buckets: allocate an array of inSlots new buckets filled with zero.
|*/
morkAssoc**
morkMap::new_buckets(morkEnv* ev, mork_num inSlots)
{
mork_num size = inSlots * sizeof(morkAssoc*);
return (morkAssoc**) this->clear_alloc(ev, size);
}
/*| new_assocs: allocate an array of inSlots new assocs, with each assoc
**| linked together in a list with the first array element at the list head
**| and the last element at the list tail. (morkMap::grow() needs this.)
|*/
morkAssoc*
morkMap::new_assocs(morkEnv* ev, mork_num inSlots)
{
mork_num size = inSlots * sizeof(morkAssoc);
morkAssoc* assocs = (morkAssoc*) this->alloc(ev, size);
if ( assocs ) /* able to allocate the array? */
{
morkAssoc* a = assocs + (inSlots - 1); /* the last array element */
a->mAssoc_Next = 0; /* terminate tail element of the list with null */
while ( --a >= assocs ) /* another assoc to link into the list? */
a->mAssoc_Next = a + 1; /* each points to the following assoc */
}
return assocs;
}
mork_bool
morkMap::new_arrays(morkEnv* ev, morkHashArrays* old, mork_num inSlots)
{
mork_bool outNew = morkBool_kFalse;
/* see if we can allocate all the new arrays before we go any further: */
morkAssoc** newBuckets = this->new_buckets(ev, inSlots);
morkAssoc* newAssocs = this->new_assocs(ev, inSlots);
mork_u1* newKeys = this->new_keys(ev, inSlots);
mork_u1* newValues = this->new_values(ev, inSlots);
mork_change* newChanges = this->new_changes(ev, inSlots);
/* it is okay for newChanges to be null when changes are not held: */
mork_bool okayChanges = ( newChanges || !this->FormHoldChanges() );
/* it is okay for newValues to be null when values are zero sized: */
mork_bool okayValues = ( newValues || !this->FormValSize() );
if ( newBuckets && newAssocs && newKeys && okayChanges && okayValues )
{
outNew = morkBool_kTrue; /* yes, we created all the arrays we need */
/* init the old hashArrays with slots from this hash table: */
old->mHashArrays_Heap = mMap_Heap;
old->mHashArrays_Slots = mMap_Slots;
old->mHashArrays_Keys = mMap_Keys;
old->mHashArrays_Vals = mMap_Vals;
old->mHashArrays_Assocs = mMap_Assocs;
old->mHashArrays_Buckets = mMap_Buckets;
old->mHashArrays_Changes = mMap_Changes;
/* now replace all our array slots with the new structures: */
++mMap_Seed; /* note the map is now changed */
mMap_Keys = newKeys;
mMap_Vals = newValues;
mMap_Buckets = newBuckets;
mMap_Assocs = newAssocs;
mMap_FreeList = newAssocs; /* all are free to start with */
mMap_Changes = newChanges;
mMap_Slots = inSlots;
}
else /* free the partial set of arrays that were actually allocated */
{
nsIMdbEnv* menv = ev->AsMdbEnv();
nsIMdbHeap* heap = mMap_Heap;
if ( newBuckets )
heap->Free(menv, newBuckets);
if ( newAssocs )
heap->Free(menv, newAssocs);
if ( newKeys )
heap->Free(menv, newKeys);
if ( newValues )
heap->Free(menv, newValues);
if ( newChanges )
heap->Free(menv, newChanges);
MORK_MEMSET(old, 0, sizeof(morkHashArrays));
}
return outNew;
}
/*| grow: make the map arrays bigger by 33%. The old map is completely
**| full, or else we would not have called grow() to get more space. This
**| means the free list is empty, and also means every old key and value is in
**| use in the old arrays. So every key and value must be copied to the new
**| arrays, and since they are contiguous in the old arrays, we can efficiently
**| bitwise copy them in bulk from the old arrays to the new arrays, without
**| paying any attention to the structure of the old arrays.
**|
**|| The content of the old bucket and assoc arrays need not be copied because
**| this information is going to be completely rebuilt by rehashing all the
**| keys into their new buckets, given the new larger map capacity. The new
**| bucket array from new_arrays() is assumed to contain all zeroes, which is
**| necessary to ensure the lists in each bucket stay null terminated as we
**| build the new linked lists. (Note no old bucket ordering is preserved.)
**|
**|| If the old capacity is N, then in the new arrays the assocs with indexes
**| from zero to N-1 are still allocated and must be rehashed into the map.
**| The new free list contains all the following assocs, starting with the new
**| assoc link at index N. (We call the links in the link array "assocs"
**| because allocating a link is the same as allocating the key/value pair
**| with the same index as the link.)
**|
**|| The new free list is initialized simply by pointing at the first new link
**| in the assoc array after the size of the old assoc array. This assumes
**| that FeHashTable_new_arrays() has already linked all the new assocs into a
**| list with the first at the head of the list and the last at the tail of the
**| list. So by making the free list point to the first of the new uncopied
**| assocs, the list is already well-formed.
|*/
mork_bool morkMap::grow(morkEnv* ev)
{
if ( mMap_Heap ) /* can we grow the map? */
{
mork_num newSlots = ((mMap_Slots * 4) / 3) + 1; /* +33% */
morkHashArrays old; /* a place to temporarily hold all the old arrays */
if ( this->new_arrays(ev, &old, newSlots) ) /* have more? */
{
// morkMap_mHash hash = this->FormHash(); /* for terse loop use */
/* figure out the bulk volume sizes of old keys and values to move: */
mork_num oldSlots = old.mHashArrays_Slots; /* number of old assocs */
mork_num keyBulk = oldSlots * this->FormKeySize(); /* key volume */
mork_num valBulk = oldSlots * this->FormValSize(); /* values */
/* convenient variables for new arrays that need to be rehashed: */
morkAssoc** newBuckets = mMap_Buckets; /* new all zeroes */
morkAssoc* newAssocs = mMap_Assocs; /* hash into buckets */
morkAssoc* newFreeList = newAssocs + oldSlots; /* new room is free */
mork_u1* key = mMap_Keys; /* the first key to rehash */
--newAssocs; /* back up one before preincrement used in while loop */
/* move all old keys and values to the new arrays: */
MORK_MEMCPY(mMap_Keys, old.mHashArrays_Keys, keyBulk);
if ( valBulk ) /* are values nonzero sized? */
MORK_MEMCPY(mMap_Vals, old.mHashArrays_Vals, valBulk);
mMap_FreeList = newFreeList; /* remaining assocs are free */
while ( ++newAssocs < newFreeList ) /* rehash another old assoc? */
{
morkAssoc** top = newBuckets + (this->Hash(ev, key) % newSlots);
key += this->FormKeySize(); /* the next key to rehash */
newAssocs->mAssoc_Next = *top; /* link to prev bucket top */
*top = newAssocs; /* push assoc on top of bucket */
}
++mMap_Seed; /* note the map has changed */
old.finalize(ev); /* remember to free the old arrays */
}
}
else ev->OutOfMemoryError();
return ev->Good();
}
mork_bool
morkMap::Put(morkEnv* ev, const void* inKey, const void* inVal,
void* outKey, void* outVal, mork_change** outChange)
{
mork_bool outPut = morkBool_kFalse;
if ( this->GoodMap() ) /* looks good? */
{
mork_u4 hash = this->Hash(ev, inKey);
morkAssoc** ref = this->find(ev, inKey, hash);
if ( ref ) /* assoc was found? reuse an existing assoc slot? */
{
outPut = morkBool_kTrue; /* inKey was indeed already inside the map */
}
else /* assoc not found -- need to allocate a new assoc slot */
{
morkAssoc* assoc = this->pop_free_assoc();
if ( !assoc ) /* no slots remaining in free list? must grow map? */
{
if ( this->grow(ev) ) /* successfully made map larger? */
assoc = this->pop_free_assoc();
}
if ( assoc ) /* allocated new assoc without error? */
{
ref = mMap_Buckets + (hash % mMap_Slots);
assoc->mAssoc_Next = *ref; /* link to prev bucket top */
*ref = assoc; /* push assoc on top of bucket */
++mMap_Fill; /* one more member in the collection */
++mMap_Seed; /* note the map has changed */
}
}
if ( ref ) /* did not have an error during possible growth? */
{
mork_pos i = (*ref) - mMap_Assocs; /* index of assoc */
if ( outPut && (outKey || outVal) ) /* copy old before cobbering? */
this->get_assoc(outKey, outVal, i);
this->put_assoc(inKey, inVal, i);
++mMap_Seed; /* note the map has changed */
if ( outChange )
{
if ( mMap_Changes )
*outChange = mMap_Changes + i;
else
*outChange = this->FormDummyChange();
}
}
}
else this->NewBadMapError(ev);
return outPut;
}
mork_num
morkMap::CutAll(morkEnv* ev)
{
mork_num outCutAll = 0;
if ( this->GoodMap() ) /* map looks good? */
{
mork_num slots = mMap_Slots;
morkAssoc* before = mMap_Assocs - 1; /* before first member */
morkAssoc* assoc = before + slots; /* the very last member */
++mMap_Seed; /* note the map is changed */
/* make the assoc array a linked list headed by first & tailed by last: */
assoc->mAssoc_Next = 0; /* null terminate the new free list */
while ( --assoc > before ) /* another assoc to link into the list? */
assoc->mAssoc_Next = assoc + 1;
mMap_FreeList = mMap_Assocs; /* all are free */
outCutAll = mMap_Fill; /* we'll cut all of them of course */
mMap_Fill = 0; /* the map is completely empty */
}
else this->NewBadMapError(ev);
return outCutAll;
}
mork_bool
morkMap::Cut(morkEnv* ev, const void* inKey,
void* outKey, void* outVal, mork_change** outChange)
{
mork_bool outCut = morkBool_kFalse;
if ( this->GoodMap() ) /* looks good? */
{
mork_u4 hash = this->Hash(ev, inKey);
morkAssoc** ref = this->find(ev, inKey, hash);
if ( ref ) /* found an assoc for key? */
{
outCut = morkBool_kTrue;
morkAssoc* assoc = *ref;
mork_pos i = assoc - mMap_Assocs; /* index of assoc */
*ref = assoc->mAssoc_Next; /* unlink the found assoc */
this->push_free_assoc(assoc); /* and put it in free list */
if ( outChange )
{
if ( mMap_Changes )
*outChange = mMap_Changes + i;
else
*outChange = this->FormDummyChange();
}
++mMap_Seed; /* note the map has changed */
if ( mMap_Fill ) /* the count shows nonzero members? */
--mMap_Fill; /* one less member in the collection */
else
this->NewSlotsUnderflowWarning(ev);
}
}
else this->NewBadMapError(ev);
return outCut;
}
mork_bool
morkMap::Get(morkEnv* ev, const void* inKey,
void* outKey, void* outVal, mork_change** outChange)
{
mork_bool outGet = morkBool_kFalse;
if ( this->GoodMap() ) /* looks good? */
{
mork_u4 hash = this->Hash(ev, inKey);
morkAssoc** ref = this->find(ev, inKey, hash);
if ( ref ) /* found an assoc for inKey? */
{
mork_pos i = (*ref) - mMap_Assocs; /* index of assoc */
outGet = morkBool_kTrue;
this->get_assoc(outKey, outVal, i);
if ( outChange )
{
if ( mMap_Changes )
*outChange = mMap_Changes + i;
else
*outChange = this->FormDummyChange();
}
}
}
else this->NewBadMapError(ev);
return outGet;
}
morkMapIter::morkMapIter( )
: mMapIter_Map( 0 )
, mMapIter_Seed( 0 )
, mMapIter_Bucket( 0 )
, mMapIter_AssocRef( 0 )
, mMapIter_Assoc( 0 )
, mMapIter_Next( 0 )
{
}
void
morkMapIter::InitMapIter(morkEnv* ev, morkMap* ioMap)
{
mMapIter_Map = 0;
mMapIter_Seed = 0;
mMapIter_Bucket = 0;
mMapIter_AssocRef = 0;
mMapIter_Assoc = 0;
mMapIter_Next = 0;
if ( ioMap )
{
if ( ioMap->GoodMap() )
{
mMapIter_Map = ioMap;
mMapIter_Seed = ioMap->mMap_Seed;
}
else ioMap->NewBadMapError(ev);
}
else ev->NilPointerError();
}
morkMapIter::morkMapIter(morkEnv* ev, morkMap* ioMap)
: mMapIter_Map( 0 )
, mMapIter_Seed( 0 )
, mMapIter_Bucket( 0 )
, mMapIter_AssocRef( 0 )
, mMapIter_Assoc( 0 )
, mMapIter_Next( 0 )
{
if ( ioMap )
{
if ( ioMap->GoodMap() )
{
mMapIter_Map = ioMap;
mMapIter_Seed = ioMap->mMap_Seed;
}
else ioMap->NewBadMapError(ev);
}
else ev->NilPointerError();
}
void
morkMapIter::CloseMapIter(morkEnv* ev)
{
mMapIter_Map = 0;
mMapIter_Seed = 0;
mMapIter_Bucket = 0;
mMapIter_AssocRef = 0;
mMapIter_Assoc = 0;
mMapIter_Next = 0;
}
mork_change*
morkMapIter::First(morkEnv* ev, void* outKey, void* outVal)
{
mork_change* outFirst = 0;
morkMap* map = mMapIter_Map;
if ( map && map->GoodMap() ) /* map looks good? */
{
morkAssoc** bucket = map->mMap_Buckets;
morkAssoc** end = bucket + map->mMap_Slots; /* one past last */
mMapIter_Seed = map->mMap_Seed; /* sync the seeds */
while ( bucket < end ) /* another bucket in which to look for assocs? */
{
morkAssoc* assoc = *bucket++;
if ( assoc ) /* found the first map assoc in use? */
{
mork_pos i = assoc - map->mMap_Assocs;
mork_change* c = map->mMap_Changes;
outFirst = ( c )? (c + i) : map->FormDummyChange();
mMapIter_Assoc = assoc; /* current assoc in iteration */
mMapIter_Next = assoc->mAssoc_Next; /* more in bucket */
mMapIter_Bucket = --bucket; /* bucket for this assoc */
mMapIter_AssocRef = bucket; /* slot referencing assoc */
map->get_assoc(outKey, outVal, i);
break; /* end while loop */
}
}
}
else map->NewBadMapError(ev);
return outFirst;
}
mork_change*
morkMapIter::Next(morkEnv* ev, void* outKey, void* outVal)
{
mork_change* outNext = 0;
morkMap* map = mMapIter_Map;
if ( map && map->GoodMap() ) /* map looks good? */
{
if ( mMapIter_Seed == map->mMap_Seed ) /* in sync? */
{
morkAssoc* here = mMapIter_Assoc; /* current assoc */
if ( here ) /* iteration is not yet concluded? */
{
morkAssoc* next = mMapIter_Next;
morkAssoc* assoc = next; /* default new mMapIter_Assoc */
if ( next ) /* there are more assocs in the same bucket after Here? */
{
morkAssoc** ref = mMapIter_AssocRef;
/* (*HereRef) equals Here, except when Here has been cut, after
** which (*HereRef) always equals Next. So if (*HereRef) is not
** equal to Next, then HereRef still needs to be updated to point
** somewhere else other than Here. Otherwise it is fine.
*/
if ( *ref != next ) /* Here was not cut? must update HereRef? */
mMapIter_AssocRef = &here->mAssoc_Next;
mMapIter_Next = next->mAssoc_Next;
}
else /* look for the next assoc in the next nonempty bucket */
{
morkAssoc** bucket = map->mMap_Buckets;
morkAssoc** end = bucket + map->mMap_Slots; /* beyond */
mMapIter_Assoc = 0; /* default to no more assocs */
bucket = mMapIter_Bucket; /* last exhausted bucket */
mMapIter_Assoc = 0; /* default to iteration ended */
while ( ++bucket < end ) /* another bucket to search for assocs? */
{
assoc = *bucket;
if ( assoc ) /* found another map assoc in use? */
{
mMapIter_Bucket = bucket;
mMapIter_AssocRef = bucket; /* ref to assoc */
mMapIter_Next = assoc->mAssoc_Next; /* more */
break; /* end while loop */
}
}
}
if ( assoc ) /* did we find another assoc in the iteration? */
{
mMapIter_Assoc = assoc; /* current assoc */
mork_pos i = assoc - map->mMap_Assocs;
mork_change* c = map->mMap_Changes;
outNext = ( c )? (c + i) : map->FormDummyChange();
map->get_assoc( outKey, outVal, i);
}
}
}
else map->NewIterOutOfSyncError(ev);
}
else map->NewBadMapError(ev);
return outNext;
}
mork_change*
morkMapIter::Here(morkEnv* ev, void* outKey, void* outVal)
{
mork_change* outHere = 0;
morkMap* map = mMapIter_Map;
if ( map && map->GoodMap() ) /* map looks good? */
{
if ( mMapIter_Seed == map->mMap_Seed ) /* in sync? */
{
morkAssoc* here = mMapIter_Assoc; /* current assoc */
if ( here ) /* iteration is not yet concluded? */
{
mork_pos i = here - map->mMap_Assocs;
mork_change* c = map->mMap_Changes;
outHere = ( c )? (c + i) : map->FormDummyChange();
map->get_assoc(outKey, outVal, i);
}
}
else map->NewIterOutOfSyncError(ev);
}
else map->NewBadMapError(ev);
return outHere;
}
mork_change*
morkMapIter::CutHere(morkEnv* ev, void* outKey, void* outVal)
{
mork_change* outCutHere = 0;
morkMap* map = mMapIter_Map;
if ( map && map->GoodMap() ) /* map looks good? */
{
if ( mMapIter_Seed == map->mMap_Seed ) /* in sync? */
{
morkAssoc* here = mMapIter_Assoc; /* current assoc */
if ( here ) /* iteration is not yet concluded? */
{
morkAssoc** ref = mMapIter_AssocRef;
if ( *ref != mMapIter_Next ) /* not already cut? */
{
mork_pos i = here - map->mMap_Assocs;
mork_change* c = map->mMap_Changes;
outCutHere = ( c )? (c + i) : map->FormDummyChange();
if ( outKey || outVal )
map->get_assoc(outKey, outVal, i);
map->push_free_assoc(here); /* add to free list */
*ref = mMapIter_Next; /* unlink here from bucket list */
/* note the map has changed, but we are still in sync: */
mMapIter_Seed = ++map->mMap_Seed; /* sync */
if ( map->mMap_Fill ) /* still has nonzero value? */
--map->mMap_Fill; /* one less member in the collection */
else
map->NewSlotsUnderflowWarning(ev);
}
}
}
else map->NewIterOutOfSyncError(ev);
}
else map->NewBadMapError(ev);
return outCutHere;
}
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

Просмотреть файл

@ -368,13 +368,16 @@ morkNode::SlotStrongNode(morkNode* me, morkEnv* ev, morkNode** ioSlot)
// expression 'morkNode::SlotStrongNode((morkNode*) 0, ev, &slot)'.
{
morkNode* node = *ioSlot;
if ( node )
if ( me != node )
{
*ioSlot = 0;
node->CutStrongRef(ev);
if ( node )
{
*ioSlot = 0;
node->CutStrongRef(ev);
}
if ( me && me->AddStrongRef(ev) )
*ioSlot = me;
}
if ( me && me->AddStrongRef(ev) )
*ioSlot = me;
}
/*public static*/ void
@ -386,13 +389,16 @@ morkNode::SlotWeakNode(morkNode* me, morkEnv* ev, morkNode** ioSlot)
// expression 'morkNode::SlotWeakNode((morkNode*) 0, ev, &slot)'.
{
morkNode* node = *ioSlot;
if ( node )
if ( me != node )
{
*ioSlot = 0;
node->CutWeakRef(ev);
if ( node )
{
*ioSlot = 0;
node->CutWeakRef(ev);
}
if ( me && me->AddWeakRef(ev) )
*ioSlot = me;
}
if ( me && me->AddWeakRef(ev) )
*ioSlot = me;
}
/*public non-poly*/ mork_uses

Просмотреть файл

@ -198,7 +198,7 @@ public: // other morkNode methods
mork_bool BadRefs() const { return mNode_Refs < mNode_Uses; }
mork_uses StrongRefsOnly() const { return mNode_Uses; }
mork_refs WeakRefsOnly() const { return ( mNode_Refs - mNode_Uses ); }
mork_refs WeakRefsOnly() const { return (mork_refs) ( mNode_Refs - mNode_Uses ); }
// (this refcounting derives from public domain IronDoc node refcounts)
mork_refs AddStrongRef(morkEnv* ev);

Просмотреть файл

@ -211,6 +211,7 @@ morkParser::NonUsableParserError(morkEnv* ev) //
/*protected non-poly*/ void
morkParser::StartParse(morkEnv* ev)
{
MORK_USED_1(ev);
mParser_InCell = morkBool_kFalse;
mParser_InMeta = morkBool_kFalse;
mParser_InDict = morkBool_kFalse;
@ -792,6 +793,7 @@ morkParser::EofInsteadOfHexError(morkEnv* ev)
/*static*/ void
morkParser::ExpectedHexDigitError(morkEnv* ev, int c)
{
MORK_USED_1(c);
ev->NewWarning("expected hex digit");
}
@ -969,6 +971,45 @@ morkParser::NonParserTypeError(morkEnv* ev)
ev->NewError("non morkParser");
}
mork_bool morkParser::MatchPattern(morkEnv* ev, const char* inPattern)
{
// if an error occurs, we want original inPattern in the debugger:
const char* pattern = inPattern; // mutable copy
morkStream* s = mParser_Stream;
register int c;
while ( *inPattern && ev->Good() )
{
char byte = *pattern++;
if ( (c = s->Getc(ev)) != byte )
{
ev->NewError("byte not in expected pattern");
}
}
return ev->Good();
}
void morkParser::ReadGroup(morkEnv* ev)
/* groups must be ignored until properly terminated */
// zm:Group ::= zm:GroupStart zm:Content zm:GroupEnd /* transaction */
// zm:GroupStart ::= zm:S? '@$${' zm:Id '{@' /* transaction id has own space */
// zm:GroupEnd ::= zm:GroupCommit | zm:GroupAbort
// zm:GroupCommit ::= zm:S? '@$$}' zm:Id '}@' /* id matches start id */
// zm:GroupAbort ::= zm:S? '@$$}~~' zm:Id '}@' /* id matches start id */
/* We must allow started transactions to be aborted in summary files. */
/* Note '$$' will never occur unescaped in values we will see in Mork. */
{
if ( this->MatchPattern(ev, "$${") )
{
//morkMid cellMid = &mParser_CellMid;
//if ( this->ReadMid(ev, cellMid) )
//{
// if ( this->MatchPattern(ev, "}@") )
// {
// }
//}
}
}
void morkParser::ReadDict(morkEnv* ev)
// zm:Dict ::= zm:S? '<' zm:DictItem* zm:S? '>'
// zm:DictItem ::= zm:MetaDict | zm:Alias
@ -1060,6 +1101,10 @@ morkParser::OnPortState(morkEnv* ev)
this->ReadDict(ev);
break;
case '@': // group
this->ReadGroup(ev);
break;
case '+': // plus
mParser_Change = morkChange_kAdd;
break;
@ -1181,7 +1226,7 @@ morkParser::ParseMore( // return count of bytes consumed now
*outPos = endPos;
if ( endPos > startPos )
outCount = endPos - startPos;
outCount = (mdb_count) (endPos - startPos);
}
else
{

Просмотреть файл

@ -476,6 +476,7 @@ protected: // protected parser helper methods
void ReadTable(morkEnv* ev);
void ReadTableMeta(morkEnv* ev);
void ReadDict(morkEnv* ev);
void ReadGroup(morkEnv* ev);
void ReadMeta(morkEnv* ev, int inEndMeta);
void ReadAlias(morkEnv* ev);
mork_id ReadHex(morkEnv* ev, int* outNextChar);
@ -483,6 +484,8 @@ protected: // protected parser helper methods
morkBuf* ReadName(morkEnv* ev, int c);
mork_bool ReadMid(morkEnv* ev, morkMid* outMid);
mork_bool MatchPattern(morkEnv* ev, const char* inPattern);
void EndSpanOnThisByte(morkEnv* ev, morkSpan* ioSpan);
void StartSpanOnLastByte(morkEnv* ev, morkSpan* ioSpan);

Просмотреть файл

@ -1,381 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _MDB_
#include "mdb.h"
#endif
#ifndef _MORK_
#include "mork.h"
#endif
#ifndef _MORKNODE_
#include "morkNode.h"
#endif
#ifndef _MORKENV_
#include "morkEnv.h"
#endif
#ifndef _MORKPOOL_
#include "morkPool.h"
#endif
#ifndef _MORKATOM_
#include "morkAtom.h"
#endif
#ifndef _MORKHANDLE_
#include "morkHandle.h"
#endif
#ifndef _MORKCELL_
#include "morkCell.h"
#endif
#ifndef _MORKROW_
#include "morkRow.h"
#endif
#ifndef _MORKBLOB_
#include "morkBlob.h"
#endif
#ifndef _MORKDEQUE_
#include "morkDeque.h"
#endif
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
// ````` ````` ````` ````` `````
// { ===== begin morkNode interface =====
/*public virtual*/ void
morkPool::CloseMorkNode(morkEnv* ev) // ClosePool() only if open
{
if ( this->IsOpenNode() )
{
this->MarkClosing();
this->ClosePool(ev);
this->MarkShut();
}
}
/*public virtual*/
morkPool::~morkPool() // assert ClosePool() executed earlier
{
MORK_ASSERT(this->IsShutNode());
}
/*public non-poly*/
morkPool::morkPool(const morkUsage& inUsage, nsIMdbHeap* ioHeap,
nsIMdbHeap* ioSlotHeap)
: morkNode(inUsage, ioHeap)
, mPool_Heap( ioSlotHeap )
{
// mPool_Heap is NOT refcounted
MORK_ASSERT(ioSlotHeap);
if ( ioSlotHeap )
mNode_Derived = morkDerived_kPool;
}
/*public non-poly*/
morkPool::morkPool(morkEnv* ev,
const morkUsage& inUsage, nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
: morkNode(ev, inUsage, ioHeap)
, mPool_Heap( ioSlotHeap )
{
if ( ioSlotHeap )
{
// mPool_Heap is NOT refcounted:
// nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mPool_Heap);
if ( ev->Good() )
mNode_Derived = morkDerived_kPool;
}
else
ev->NilPointerError();
}
/*public non-poly*/ void
morkPool::ClosePool(morkEnv* ev) // called by CloseMorkNode();
{
if ( this )
{
if ( this->IsNode() )
{
// mPool_Heap is NOT refcounted:
// nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mPool_Heap);
this->MarkShut();
}
else
this->NonNodeError(ev);
}
else
ev->NilPointerError();
}
// } ===== end morkNode methods =====
// ````` ````` ````` ````` `````
// alloc and free individual instances of handles (inside hand frames):
morkHandleFace*
morkPool::NewHandle(morkEnv* ev, mork_size inSize)
{
void* newBlock = 0;
mPool_Heap->Alloc(ev->AsMdbEnv(), inSize, (void**) &newBlock);
return (morkHandleFace*) newBlock;
}
void
morkPool::ZapHandle(morkEnv* ev, morkHandleFace* ioHandle)
{
if ( ioHandle )
mPool_Heap->Free(ev->AsMdbEnv(), ioHandle);
}
// alloc and free individual instances of rows:
morkRow*
morkPool::NewRow(morkEnv* ev) // allocate a new row instance
{
morkRow* newRow = 0;
mPool_Heap->Alloc(ev->AsMdbEnv(), sizeof(morkRow), (void**) &newRow);
if ( newRow )
MORK_MEMSET(newRow, 0, sizeof(morkRow));
if ( newRow )
{
}
return newRow;
}
void
morkPool::ZapRow(morkEnv* ev, morkRow* ioRow) // free old row instance
{
if ( ioRow )
mPool_Heap->Free(ev->AsMdbEnv(), ioRow);
}
// alloc and free entire vectors of cells (not just one cell at a time)
morkCell*
morkPool::NewCells(morkEnv* ev, mork_size inSize)
{
morkCell* newCells = 0;
mork_size size = inSize * sizeof(morkCell);
if ( size )
mPool_Heap->Alloc(ev->AsMdbEnv(), size, (void**) &newCells);
// note morkAtom depends on having nil stored in all new mCell_Atom slots:
if ( newCells )
MORK_MEMSET(newCells, 0, size);
return newCells;
}
void
morkPool::ZapCells(morkEnv* ev, morkCell* ioVector, mork_size inSize)
{
if ( ioVector )
mPool_Heap->Free(ev->AsMdbEnv(), ioVector);
}
// resize (grow or trim) cell vectors inside a containing row instance
mork_bool
morkPool::AddRowCells(morkEnv* ev, morkRow* ioRow, mork_size inNewSize)
{
// note strong implementation similarity to morkArray::Grow()
mork_fill fill = ioRow->mRow_Length;
if ( ev->Good() && fill < inNewSize ) // need more cells?
{
morkCell* newCells = this->NewCells(ev, inNewSize);
if ( newCells )
{
morkCell* c = newCells; // for iterating during copy
morkCell* oldCells = ioRow->mRow_Cells;
morkCell* end = oldCells + fill; // copy all the old cells
while ( oldCells < end )
{
*c++ = *oldCells++; // bitwise copy each old cell struct
}
oldCells = ioRow->mRow_Cells;
ioRow->mRow_Cells = newCells;
ioRow->mRow_Length = inNewSize;
++ioRow->mRow_Seed;
if ( oldCells )
this->ZapCells(ev, oldCells, fill);
}
}
return ( ev->Good() && ioRow->mRow_Length >= inNewSize );
}
mork_bool
morkPool::CutRowCells(morkEnv* ev, morkRow* ioRow,
mork_size inNewSize)
{
mork_fill fill = ioRow->mRow_Length;
if ( ev->Good() && fill > inNewSize ) // need fewer cells?
{
if ( inNewSize ) // want any row cells at all?
{
morkCell* newCells = this->NewCells(ev, inNewSize);
if ( newCells )
{
morkCell* oldCells = ioRow->mRow_Cells;
morkCell* oldEnd = oldCells + fill; // one past all old cells
morkCell* newEnd = oldCells + inNewSize; // copy only kept old cells
while ( oldCells < newEnd )
{
*newCells++ = *oldCells++; // bitwise copy each old cell struct
}
while ( oldCells < oldEnd )
{
if ( oldCells->mCell_Atom ) // need to unref old cell atom?
oldCells->SetAtom(ev, (morkAtom*) 0, this); // unref cell atom
++oldCells;
}
oldCells = ioRow->mRow_Cells;
ioRow->mRow_Cells = newCells;
ioRow->mRow_Length = inNewSize;
++ioRow->mRow_Seed;
if ( oldCells )
this->ZapCells(ev, oldCells, fill);
}
}
else // get rid of all row cells
{
morkCell* oldCells = ioRow->mRow_Cells;
ioRow->mRow_Cells = 0;
ioRow->mRow_Length = 0;
++ioRow->mRow_Seed;
if ( oldCells )
this->ZapCells(ev, oldCells, fill);
}
}
return ( ev->Good() && ioRow->mRow_Length <= inNewSize );
}
// alloc & free individual instances of atoms (lots of atom subclasses):
void
morkPool::ZapAtom(morkEnv* ev, morkAtom* ioAtom) // any subclass (by kind)
{
if ( ioAtom )
mPool_Heap->Free(ev->AsMdbEnv(), ioAtom);
}
morkOidAtom*
morkPool::NewRowOidAtom(morkEnv* ev, const mdbOid& inOid)
{
morkOidAtom* newAtom = 0;
mPool_Heap->Alloc(ev->AsMdbEnv(), sizeof(morkOidAtom),(void**) &newAtom);
if ( newAtom )
newAtom->InitRowOidAtom(ev, inOid);
return newAtom;
}
morkOidAtom*
morkPool::NewTableOidAtom(morkEnv* ev, const mdbOid& inOid)
{
morkOidAtom* newAtom = 0;
mPool_Heap->Alloc(ev->AsMdbEnv(), sizeof(morkOidAtom), (void**) &newAtom);
if ( newAtom )
newAtom->InitTableOidAtom(ev, inOid);
return newAtom;
}
morkAtom*
morkPool::NewAnonAtom(morkEnv* ev, const morkBuf& inBuf,
mork_cscode inForm)
// if inForm is zero, and inBuf.mBuf_Fill is less than 256, then a 'wee'
// anon atom will be created, and otherwise a 'big' anon atom.
{
morkAtom* newAtom = 0;
mork_bool needBig = ( inForm || inBuf.mBuf_Fill > 255 );
mork_size size = ( needBig )?
morkBigAnonAtom::SizeForFill(inBuf.mBuf_Fill) :
morkWeeAnonAtom::SizeForFill(inBuf.mBuf_Fill);
mPool_Heap->Alloc(ev->AsMdbEnv(), size, (void**) &newAtom);
if ( newAtom )
{
if ( needBig )
((morkBigAnonAtom*) newAtom)->InitBigAnonAtom(ev, inBuf, inForm);
else
((morkWeeAnonAtom*) newAtom)->InitWeeAnonAtom(ev, inBuf);
}
return newAtom;
}
morkBookAtom*
morkPool::NewBookAtom(morkEnv* ev, const morkBuf& inBuf,
mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid)
// if inForm is zero, and inBuf.mBuf_Fill is less than 256, then a 'wee'
// book atom will be created, and otherwise a 'big' book atom.
{
morkBookAtom* newAtom = 0;
mork_bool needBig = ( inForm || inBuf.mBuf_Fill > 255 );
mork_size size = ( needBig )?
morkBigBookAtom::SizeForFill(inBuf.mBuf_Fill) :
morkWeeBookAtom::SizeForFill(inBuf.mBuf_Fill);
mPool_Heap->Alloc(ev->AsMdbEnv(), size, (void**) &newAtom);
if ( newAtom )
{
if ( needBig )
((morkBigBookAtom*) newAtom)->InitBigBookAtom(ev,
inBuf, inForm, ioSpace, inAid);
else
((morkWeeBookAtom*) newAtom)->InitWeeBookAtom(ev,
inBuf, ioSpace, inAid);
}
return newAtom;
}
morkBookAtom*
morkPool::NewBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom)
// make the smallest kind of book atom that can hold content in inAtom.
// The inAtom parameter is often expected to be a staged book atom in
// the store, which was used to search an atom space for existing atoms.
{
morkBookAtom* newAtom = 0;
mork_cscode form = inAtom.mBigBookAtom_Form;
mork_fill fill = inAtom.mBigBookAtom_Size;
mork_bool needBig = ( form || fill > 255 );
mork_size size = ( needBig )?
morkBigBookAtom::SizeForFill(fill) :
morkWeeBookAtom::SizeForFill(fill);
mPool_Heap->Alloc(ev->AsMdbEnv(), size, (void**) &newAtom);
if ( newAtom )
{
morkBuf buf(inAtom.mBigBookAtom_Body, fill);
if ( needBig )
((morkBigBookAtom*) newAtom)->InitBigBookAtom(ev,
buf, form, inAtom.mBookAtom_Space, inAtom.mBookAtom_Id);
else
((morkWeeBookAtom*) newAtom)->InitWeeBookAtom(ev,
buf, inAtom.mBookAtom_Space, inAtom.mBookAtom_Id);
}
return newAtom;
}
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

Просмотреть файл

@ -1,317 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _MDB_
#include "mdb.h"
#endif
#ifndef _MORK_
#include "mork.h"
#endif
#ifndef _MORKNODE_
#include "morkNode.h"
#endif
#ifndef _MORKENV_
#include "morkEnv.h"
#endif
#ifndef _MORKCURSOR_
#include "morkCursor.h"
#endif
#ifndef _MORKPORTTABLECURSOR_
#include "morkPortTableCursor.h"
#endif
#ifndef _ORKINPORTTABLECURSOR_
#include "orkinPortTableCursor.h"
#endif
#ifndef _MORKSTORE_
#include "morkStore.h"
#endif
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
// ````` ````` ````` ````` `````
// { ===== begin morkNode interface =====
/*public virtual*/ void
morkPortTableCursor::CloseMorkNode(morkEnv* ev) // ClosePortTableCursor() only if open
{
if ( this->IsOpenNode() )
{
this->MarkClosing();
this->ClosePortTableCursor(ev);
this->MarkShut();
}
}
/*public virtual*/
morkPortTableCursor::~morkPortTableCursor() // ClosePortTableCursor() executed earlier
{
MORK_ASSERT(this->IsShutNode());
}
/*public non-poly*/
morkPortTableCursor::morkPortTableCursor(morkEnv* ev,
const morkUsage& inUsage,
nsIMdbHeap* ioHeap, morkStore* ioStore, mdb_scope inRowScope,
mdb_kind inTableKind, nsIMdbHeap* ioSlotHeap)
: morkCursor(ev, inUsage, ioHeap)
, mPortTableCursor_Store( 0 )
, mPortTableCursor_RowScope( (mdb_scope) -1 ) // we want != inRowScope
, mPortTableCursor_TableKind( (mdb_kind) -1 ) // we want != inTableKind
, mPortTableCursor_LastTable ( 0 ) // not refcounted
, mPortTableCursor_RowSpace( 0 ) // strong ref to row space
, mPortTableCursor_TablesDidEnd( morkBool_kFalse )
, mPortTableCursor_SpacesDidEnd( morkBool_kFalse )
{
if ( ev->Good() )
{
if ( ioStore )
{
mCursor_Pos = -1;
mCursor_Seed = 0; // let the iterator do it's own seed handling
morkStore::SlotWeakStore(ioStore, ev, &mPortTableCursor_Store);
if ( this->SetRowScope(ev, inRowScope) )
this->SetTableKind(ev, inTableKind);
if ( ev->Good() )
mNode_Derived = morkDerived_kPortTableCursor;
}
else
ev->NilPointerError();
}
}
/*public non-poly*/ void
morkPortTableCursor::ClosePortTableCursor(morkEnv* ev)
{
if ( this )
{
if ( this->IsNode() )
{
mCursor_Pos = -1;
mCursor_Seed = 0;
mPortTableCursor_LastTable = 0;
morkStore::SlotWeakStore((morkStore*) 0, ev, &mPortTableCursor_Store);
morkRowSpace::SlotStrongRowSpace((morkRowSpace*) 0, ev,
&mPortTableCursor_RowSpace);
this->CloseCursor(ev);
this->MarkShut();
}
else
this->NonNodeError(ev);
}
else
ev->NilPointerError();
}
// } ===== end morkNode methods =====
// ````` ````` ````` ````` `````
/*static*/ void
morkPortTableCursor::NilCursorStoreError(morkEnv* ev)
{
ev->NewError("nil mPortTableCursor_Store");
}
/*static*/ void
morkPortTableCursor::NonPortTableCursorTypeError(morkEnv* ev)
{
ev->NewError("non morkPortTableCursor");
}
orkinPortTableCursor*
morkPortTableCursor::AcquirePortTableCursorHandle(morkEnv* ev)
{
orkinPortTableCursor* outCursor = 0;
orkinPortTableCursor* c = (orkinPortTableCursor*) mObject_Handle;
if ( c ) // have an old handle?
c->AddStrongRef(ev->AsMdbEnv());
else // need new handle?
{
c = orkinPortTableCursor::MakePortTableCursor(ev, this);
mObject_Handle = c;
}
if ( c )
outCursor = c;
return outCursor;
}
mork_bool
morkPortTableCursor::SetRowScope(morkEnv* ev, mork_scope inRowScope)
{
mPortTableCursor_RowScope = inRowScope;
mPortTableCursor_LastTable = 0; // restart iteration of space
mPortTableCursor_TableIter.CloseMapIter(ev);
mPortTableCursor_TablesDidEnd = morkBool_kTrue;
mPortTableCursor_SpacesDidEnd = morkBool_kTrue;
morkStore* store = mPortTableCursor_Store;
if ( store )
{
morkRowSpace* space = mPortTableCursor_RowSpace;
if ( inRowScope ) // intend to cover a specific scope only?
{
space = store->LazyGetRowSpace(ev, inRowScope);
morkRowSpace::SlotStrongRowSpace(space, ev,
&mPortTableCursor_RowSpace);
// We want mPortTableCursor_SpacesDidEnd == morkBool_kTrue
// to show this is the only space to be covered.
}
else // prepare space map iter to cover all space scopes
{
morkRowSpaceMapIter* rsi = &mPortTableCursor_SpaceIter;
rsi->InitRowSpaceMapIter(ev, &store->mStore_RowSpaces);
space = 0;
(void) rsi->FirstRowSpace(ev, (mork_scope*) 0, &space);
morkRowSpace::SlotStrongRowSpace(space, ev,
&mPortTableCursor_RowSpace);
if ( space ) // found first space in store
mPortTableCursor_SpacesDidEnd = morkBool_kFalse;
}
this->init_space_tables_map(ev);
}
else
this->NilCursorStoreError(ev);
return ev->Good();
}
void
morkPortTableCursor::init_space_tables_map(morkEnv* ev)
{
morkRowSpace* space = mPortTableCursor_RowSpace;
if ( space && ev->Good() )
{
morkTableMapIter* ti = &mPortTableCursor_TableIter;
ti->InitTableMapIter(ev, &space->mRowSpace_Tables);
if ( ev->Good() )
mPortTableCursor_TablesDidEnd = morkBool_kFalse;
}
}
mork_bool
morkPortTableCursor::SetTableKind(morkEnv* ev, mork_kind inTableKind)
{
mPortTableCursor_TableKind = inTableKind;
mPortTableCursor_LastTable = 0; // restart iteration of space
mPortTableCursor_TablesDidEnd = morkBool_kTrue;
morkRowSpace* space = mPortTableCursor_RowSpace;
if ( !space && mPortTableCursor_RowScope == 0 )
{
this->SetRowScope(ev, 0);
space = mPortTableCursor_RowSpace;
}
this->init_space_tables_map(ev);
return ev->Good();
}
morkRowSpace*
morkPortTableCursor::NextSpace(morkEnv* ev)
{
morkRowSpace* outSpace = 0;
mPortTableCursor_LastTable = 0;
mPortTableCursor_SpacesDidEnd = morkBool_kTrue;
mPortTableCursor_TablesDidEnd = morkBool_kTrue;
if ( !mPortTableCursor_RowScope ) // not just one scope?
{
morkStore* store = mPortTableCursor_Store;
if ( store )
{
morkRowSpaceMapIter* rsi = &mPortTableCursor_SpaceIter;
(void) rsi->NextRowSpace(ev, (mork_scope*) 0, &outSpace);
morkRowSpace::SlotStrongRowSpace(outSpace, ev,
&mPortTableCursor_RowSpace);
if ( outSpace ) // found next space in store
{
mPortTableCursor_SpacesDidEnd = morkBool_kFalse;
this->init_space_tables_map(ev);
if ( ev->Bad() )
outSpace = 0;
}
}
else
this->NilCursorStoreError(ev);
}
return outSpace;
}
morkTable *
morkPortTableCursor::NextTable(morkEnv* ev)
{
mork_kind kind = mPortTableCursor_TableKind;
do // until spaces end, or until we find a table in a space
{
morkRowSpace* space = mPortTableCursor_RowSpace;
if ( mPortTableCursor_TablesDidEnd ) // current space exhausted?
space = this->NextSpace(ev); // go on to the next space
if ( space ) // have a space remaining that might hold tables?
{
mork_tid* key = 0; // ignore keys in table map
morkTable* table = 0; // old value table in the map
morkTableMapIter* ti = &mPortTableCursor_TableIter;
mork_change* c = ( mPortTableCursor_LastTable )?
ti->NextTable(ev, key, &table) : ti->FirstTable(ev, key, &table);
for ( ; c && ev->Good(); c = ti->NextTable(ev, key, &table) )
{
if ( table && table->IsTable() )
{
if ( !kind || kind == table->mTable_Kind )
{
mPortTableCursor_LastTable = table; // ti->NextTable() hence
return table;
}
}
else
table->NonTableTypeWarning(ev);
}
mPortTableCursor_TablesDidEnd = morkBool_kTrue; // space is done
mPortTableCursor_LastTable = 0; // make sure next space starts fresh
}
} while ( ev->Good() && !mPortTableCursor_SpacesDidEnd );
return (morkTable*) 0;
}
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

Просмотреть файл

@ -69,8 +69,13 @@
mork_u2
morkRow::AddTableUse(morkEnv* ev)
{
if ( mRow_TableUses < morkRow_kMaxTableUses ) // not already maxed out?
++mRow_TableUses;
if ( this->IsRow() )
{
if ( mRow_TableUses < morkRow_kMaxTableUses ) // not already maxed out?
++mRow_TableUses;
}
else
this->NonRowTypeError(ev);
return mRow_TableUses;
}
@ -78,13 +83,18 @@ morkRow::AddTableUse(morkEnv* ev)
mork_u2
morkRow::CutTableUse(morkEnv* ev)
{
if ( mRow_TableUses ) // any outstanding uses to cut?
if ( this->IsRow() )
{
if ( mRow_TableUses < morkRow_kMaxTableUses ) // not frozen at max?
--mRow_TableUses;
if ( mRow_TableUses ) // any outstanding uses to cut?
{
if ( mRow_TableUses < morkRow_kMaxTableUses ) // not frozen at max?
--mRow_TableUses;
}
else
this->TableUsesUnderflowWarning(ev);
}
else
this->TableUsesUnderflowWarning(ev);
this->NonRowTypeError(ev);
return mRow_TableUses;
}
@ -142,7 +152,7 @@ morkRow::InitRow(morkEnv* ev, const mdbOid* inOid, morkRowSpace* ioSpace,
mRow_Cells = 0;
mRow_Oid = *inOid;
mRow_Length = inLength;
mRow_Length = (mork_u2) inLength;
mRow_Seed = (mork_u2) this; // "random" assignment
mRow_TableUses = 0;
@ -300,7 +310,7 @@ morkRow::TakeCells(morkEnv* ev, morkCell* ioVector, mork_fill inVecLength,
if ( ioVector && inVecLength && ev->Good() )
{
++mRow_Seed; // intend to change structure of mRow_Cells
mork_pos length = (mork_pos) mRow_Length;
mork_size length = (mork_size) mRow_Length;
mork_count overlap = this->CountOverlap(ev, ioVector, inVecLength);
@ -328,8 +338,8 @@ morkRow::NewCell(morkEnv* ev, mdb_column inColumn,
mork_pos* outPos, morkStore* ioStore)
{
++mRow_Seed; // intend to change structure of mRow_Cells
mork_pos length = (mork_pos) mRow_Length;
*outPos = length;
mork_size length = (mork_size) mRow_Length;
*outPos = (mork_pos) length;
morkPool* pool = ioStore->StorePool();
if ( pool->AddRowCells(ev, this, length + 1) )
{
@ -344,6 +354,7 @@ morkRow::NewCell(morkEnv* ev, mdb_column inColumn,
morkCell*
morkRow::CellAt(morkEnv* ev, mork_pos inPos) const
{
MORK_USED_1(ev);
morkCell* cells = mRow_Cells;
if ( cells && inPos < mRow_Length && inPos >= 0 )
{
@ -355,6 +366,7 @@ morkRow::CellAt(morkEnv* ev, mork_pos inPos) const
morkCell*
morkRow::GetCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos) const
{
MORK_USED_1(ev);
morkCell* cells = mRow_Cells;
if ( cells )
{
@ -375,6 +387,42 @@ morkRow::GetCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos) const
return (morkCell*) 0;
}
mork_aid
morkRow::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.
{
if ( this && this->IsRow() )
{
morkCell* cells = mRow_Cells;
if ( cells )
{
morkCell* end = cells + mRow_Length;
while ( cells < end )
{
mork_column col = cells->GetColumn();
if ( col == inColumn ) // found desired column?
{
morkAtom* atom = cells->mCell_Atom;
if ( atom && atom->IsBook() )
return ((morkBookAtom*) atom)->mBookAtom_Id;
else
return 0;
}
else
++cells;
}
}
}
else
this->NonRowTypeError(ev);
return 0;
}
void
morkRow::EmptyAllCells(morkEnv* ev)
{
@ -396,12 +444,46 @@ morkRow::EmptyAllCells(morkEnv* ev)
}
}
void
morkRow::cut_all_index_entries(morkEnv* ev)
{
morkRowSpace* rowSpace = mRow_Space;
if ( rowSpace->mRowSpace_IndexCount ) // any indexes?
{
morkCell* cells = mRow_Cells;
if ( cells )
{
morkCell* end = cells + mRow_Length;
--cells; // prepare for preincrement:
while ( ++cells < end )
{
morkAtom* atom = cells->mCell_Atom;
if ( atom )
{
mork_aid atomAid = atom->GetBookAtomAid();
if ( atomAid )
{
mork_column col = cells->GetColumn();
morkAtomRowMap* map = rowSpace->FindMap(ev, col);
if ( map ) // cut row from index for this column?
map->CutAid(ev, atomAid);
}
}
}
}
}
}
void
morkRow::CutAllColumns(morkEnv* ev)
{
morkStore* store = this->GetRowSpaceStore(ev);
if ( store )
{
morkRowSpace* rowSpace = mRow_Space;
if ( rowSpace->mRowSpace_IndexCount ) // any indexes?
this->cut_all_index_entries(ev);
morkPool* pool = store->StorePool();
pool->CutRowCells(ev, this, /*newSize*/ 0);
}
@ -415,6 +497,9 @@ morkRow::SetRow(morkEnv* ev, const morkRow* inSourceRow)
morkStore* srcStore = inSourceRow->GetRowSpaceStore(ev);
if ( store && srcStore )
{
morkRowSpace* rowSpace = mRow_Space;
mork_count indexes = rowSpace->mRowSpace_IndexCount; // any indexes?
mork_bool sameStore = ( store == srcStore ); // identical stores?
morkPool* pool = store->StorePool();
if ( pool->CutRowCells(ev, this, /*newSize*/ 0) )
@ -432,17 +517,17 @@ morkRow::SetRow(morkEnv* ev, const morkRow* inSourceRow)
while ( ++dst < dstEnd && ++src < srcEnd && ev->Good() )
{
morkAtom* atom = src->mCell_Atom;
mork_column col = src->GetColumn();
mork_column dstCol = src->GetColumn();
if ( sameStore ) // source and dest in same store?
{
dst->SetColumnAndChange(col, morkChange_kAdd);
dst->SetColumnAndChange(dstCol, morkChange_kAdd);
dst->mCell_Atom = atom;
if ( atom ) // another ref to non-nil atom?
atom->AddCellUse(ev);
}
else // need to dup items from src store in a dest store
{
mork_column dstCol = store->CopyToken(ev, col, srcStore);
dstCol = store->CopyToken(ev, dstCol, srcStore);
if ( dstCol )
{
dst->SetColumnAndChange(dstCol, morkChange_kAdd);
@ -452,6 +537,16 @@ morkRow::SetRow(morkEnv* ev, const morkRow* inSourceRow)
atom->AddCellUse(ev);
}
}
if ( indexes && atom )
{
mork_aid atomAid = atom->GetBookAtomAid();
if ( atomAid )
{
morkAtomRowMap* map = rowSpace->FindMap(ev, dstCol);
if ( map )
map->AddAid(ev, atomAid, this);
}
}
}
}
}
@ -473,12 +568,14 @@ void
morkRow::OnZeroTableUse(morkEnv* ev)
// OnZeroTableUse() is called when CutTableUse() returns zero.
{
MORK_USED_1(ev);
// ev->NewWarning("need to implement OnZeroTableUse");
}
void
morkRow::DirtyAllRowContent(morkEnv* ev)
{
MORK_USED_1(ev);
this->SetRowDirty();
morkCell* cells = mRow_Cells;
@ -527,6 +624,20 @@ void morkRow::CutColumn(morkEnv* ev, mdb_column inColumn)
morkStore* store = this->GetRowSpaceStore(ev);
if ( store )
{
morkRowSpace* rowSpace = mRow_Space;
morkAtomRowMap* map = ( rowSpace->mRowSpace_IndexCount )?
rowSpace->FindMap(ev, inColumn) : (morkAtomRowMap*) 0;
if ( map ) // this row attribute is indexed by row space?
{
morkAtom* oldAtom = cell->mCell_Atom;
if ( oldAtom ) // need to cut an entry from the index?
{
mork_aid oldAid = oldAtom->GetBookAtomAid();
if ( oldAid ) // cut old row attribute from row index in space?
map->CutAid(ev, oldAid);
}
}
morkPool* pool = store->StorePool();
cell->SetAtom(ev, (morkAtom*) 0, pool);
@ -553,6 +664,25 @@ void morkRow::CutColumn(morkEnv* ev, mdb_column inColumn)
}
}
// void morkRow::cut_cell_from_space_index(morkEnv* ev, morkCell* ioCell)
// {
// morkAtom* oldAtom = ioCell->mCell_Atom;
// if ( oldAtom )
// {
// mork_column col = ioCell->GetColumn();
// morkRowSpace* rowSpace = mRow_Space;
// morkAtomRowMap* map = ( rowSpace->mRowSpace_IndexCount )?
// rowSpace->FindMap(ev, col) : (morkAtomRowMap*) 0;
//
// if ( map ) // col is indexed by row space?
// {
// mork_aid oldAid = oldAtom->GetBookAtomAid();
// if ( oldAid ) // cut old row attribute from row index in space?
// map->CutAid(ev, oldAid);
// }
// }
// }
void morkRow::AddColumn(morkEnv* ev, mdb_column inColumn,
const mdbYarn* inYarn, morkStore* ioStore)
{
@ -570,7 +700,31 @@ void morkRow::AddColumn(morkEnv* ev, mdb_column inColumn,
// cell->SetYarn(ev, inYarn, ioStore);
morkAtom* atom = ioStore->YarnToAtom(ev, inYarn);
if ( atom )
{
morkRowSpace* rowSpace = mRow_Space;
morkAtomRowMap* map = ( rowSpace->mRowSpace_IndexCount )?
rowSpace->FindMap(ev, inColumn) : (morkAtomRowMap*) 0;
if ( map ) // inColumn is indexed by row space?
{
morkAtom* oldAtom = cell->mCell_Atom;
if ( oldAtom && oldAtom != atom ) // cut old cell from index?
{
mork_aid oldAid = oldAtom->GetBookAtomAid();
if ( oldAid ) // cut old row attribute from row index in space?
map->CutAid(ev, oldAid);
}
}
cell->SetAtom(ev, atom, ioStore->StorePool()); // refcounts atom
if ( map ) // inColumn is indexed by row space?
{
mork_aid newAid = atom->GetBookAtomAid();
if ( newAid ) // add new row attribute to row index in space?
map->AddAid(ev, newAid, this);
}
}
}
}
}

Просмотреть файл

@ -74,6 +74,10 @@ public: // other row methods
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
@ -100,6 +104,13 @@ public: // internal row methods
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);
@ -132,7 +143,7 @@ public: // hash and equal
return (mRow_Oid.mOid_Scope << 16) ^ mRow_Oid.mOid_Id;
}
mork_u4 EqualRow(const morkRow* ioRow) const
mork_bool EqualRow(const morkRow* ioRow) const
{
return
(
@ -141,7 +152,7 @@ public: // hash and equal
);
}
mork_u4 EqualOid(const mdbOid* ioOid) const
mork_bool EqualOid(const mdbOid* ioOid) const
{
return
(

Просмотреть файл

@ -1,171 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _MDB_
#include "mdb.h"
#endif
#ifndef _MORK_
#include "mork.h"
#endif
#ifndef _MORKNODE_
#include "morkNode.h"
#endif
#ifndef _MORKENV_
#include "morkEnv.h"
#endif
#ifndef _MORKMAP_
#include "morkMap.h"
#endif
#ifndef _MORKROWMAP_
#include "morkRowMap.h"
#endif
#ifndef _MORKROW_
#include "morkRow.h"
#endif
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
// ````` ````` ````` ````` `````
// { ===== begin morkNode interface =====
/*public virtual*/ void
morkRowMap::CloseMorkNode(morkEnv* ev) // CloseRowMap() only if open
{
if ( this->IsOpenNode() )
{
this->MarkClosing();
this->CloseRowMap(ev);
this->MarkShut();
}
}
/*public virtual*/
morkRowMap::~morkRowMap() // assert CloseRowMap() executed earlier
{
MORK_ASSERT(this->IsShutNode());
}
/*public non-poly*/
morkRowMap::morkRowMap(morkEnv* ev, const morkUsage& inUsage,
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_size inSlots)
: morkMap(ev, inUsage, ioHeap,
/*inKeySize*/ sizeof(morkRow*), /*inValSize*/ 0,
inSlots, ioSlotHeap, /*inHoldChanges*/ morkBool_kFalse)
{
if ( ev->Good() )
mNode_Derived = morkDerived_kRowMap;
}
/*public non-poly*/ void
morkRowMap::CloseRowMap(morkEnv* ev) // called by CloseMorkNode();
{
if ( this )
{
if ( this->IsNode() )
{
this->CloseMap(ev);
this->MarkShut();
}
else
this->NonNodeError(ev);
}
else
ev->NilPointerError();
}
// } ===== end morkNode methods =====
// ````` ````` ````` ````` `````
// { ===== begin morkMap poly interface =====
/*virtual*/ mork_bool //
morkRowMap::Equal(morkEnv* ev, const void* inKeyA,
const void* inKeyB) const
{
return (*(const morkRow**) inKeyA)->EqualRow(*(const morkRow**) inKeyB);
}
/*virtual*/ mork_u4 //
morkRowMap::Hash(morkEnv* ev, const void* inKey) const
{
return (*(const morkRow**) inKey)->HashRow();
}
// } ===== end morkMap poly interface =====
mork_bool
morkRowMap::AddRow(morkEnv* ev, morkRow* ioRow)
{
if ( ev->Good() )
{
this->Put(ev, &ioRow, /*val*/ (void*) 0,
/*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0);
}
return ev->Good();
}
morkRow*
morkRowMap::CutOid(morkEnv* ev, const mdbOid* inOid)
{
morkRow row(inOid);
morkRow* key = &row;
morkRow* oldKey = 0;
this->Cut(ev, &key, &oldKey, /*val*/ (void*) 0,
(mork_change**) 0);
return oldKey;
}
morkRow*
morkRowMap::CutRow(morkEnv* ev, const morkRow* ioRow)
{
morkRow* oldKey = 0;
this->Cut(ev, &ioRow, &oldKey, /*val*/ (void*) 0,
(mork_change**) 0);
return oldKey;
}
morkRow*
morkRowMap::GetOid(morkEnv* ev, const mdbOid* inOid)
{
morkRow row(inOid);
morkRow* key = &row;
morkRow* oldKey = 0;
this->Get(ev, &key, &oldKey, /*val*/ (void*) 0, (mork_change**) 0);
return oldKey;
}
morkRow*
morkRowMap::GetRow(morkEnv* ev, const morkRow* ioRow)
{
morkRow* oldKey = 0;
this->Get(ev, &ioRow, &oldKey, /*val*/ (void*) 0, (mork_change**) 0);
return oldKey;
}
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

Просмотреть файл

@ -68,6 +68,10 @@
#include "morkRow.h"
#endif
#ifndef _MORKATOMMAP_
#include "morkAtomMap.h"
#endif
#ifndef _MORKROWOBJECT_
#include "morkRowObject.h"
#endif
@ -99,14 +103,29 @@ morkRowSpace::morkRowSpace(morkEnv* ev,
const morkUsage& inUsage, mork_scope inScope, morkStore* ioStore,
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
: morkSpace(ev, inUsage, inScope, ioStore, ioHeap, ioSlotHeap)
, mRowSpace_SlotHeap( ioSlotHeap )
, mRowSpace_Rows(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap,
morkRowSpace_kStartRowMapSlotCount)
, mRowSpace_Tables(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap)
, mRowSpace_NextTableId( 1 )
, mRowSpace_NextRowId( 1 )
, mRowSpace_IndexCount( 0 )
{
morkAtomRowMap** cache = mRowSpace_IndexCache;
morkAtomRowMap** cacheEnd = cache + morkRowSpace_kPrimeCacheSize;
while ( cache < cacheEnd )
*cache++ = 0; // put nil into every slot of cache table
if ( ev->Good() )
mNode_Derived = morkDerived_kRowSpace;
{
if ( ioSlotHeap )
{
mNode_Derived = morkDerived_kRowSpace;
}
else
ev->NilPointerError();
}
}
/*public non-poly*/ void
@ -116,11 +135,20 @@ morkRowSpace::CloseRowSpace(morkEnv* ev) // called by CloseMorkNode();
{
if ( this->IsNode() )
{
morkAtomRowMap** cache = mRowSpace_IndexCache;
morkAtomRowMap** cacheEnd = cache + morkRowSpace_kPrimeCacheSize;
--cache; // prepare for preincrement:
while ( ++cache < cacheEnd )
{
if ( *cache )
morkAtomRowMap::SlotStrongAtomRowMap(0, ev, cache);
}
mRowSpace_Tables.CloseMorkNode(ev);
morkStore* store = mSpace_Store;
if ( store )
this->CutAllRows(ev, &store->mStore_Pool);
this->CutAllRows(ev, &store->mStore_Pool);
mRowSpace_Rows.CloseMorkNode(ev);
this->CloseSpace(ev);
@ -187,18 +215,22 @@ morkRowSpace::CutAllRows(morkEnv* ev, morkPool* ioPool)
for ( c = i.FirstRow(ev, &r); c && ev->Good();
c = i.NextRow(ev, &r) )
{
if ( r->IsRow() )
if ( r )
{
if ( r->mRow_Object )
if ( r->IsRow() )
{
morkRowObject::SlotWeakRowObject((morkRowObject*) 0, ev,
&r->mRow_Object);
}
if ( r )
if ( r->mRow_Object )
{
morkRowObject::SlotWeakRowObject((morkRowObject*) 0, ev,
&r->mRow_Object);
}
ioPool->ZapRow(ev, r);
}
else
r->NonRowTypeWarning(ev);
}
else
r->NonRowTypeWarning(ev);
ev->NilPointerError();
i.CutHereRow(ev, /*key*/ (morkRow**) 0);
}
@ -346,6 +378,136 @@ morkRowSpace::MakeNewRowId(morkEnv* ev)
return outRid;
}
morkAtomRowMap*
morkRowSpace::make_index(morkEnv* ev, mork_column inCol)
{
morkAtomRowMap* outMap = 0;
nsIMdbHeap* heap = mRowSpace_SlotHeap;
if ( heap ) // have expected heap for allocations?
{
morkAtomRowMap* map = new(*heap, ev)
morkAtomRowMap(ev, morkUsage::kHeap, heap, heap, inCol);
if ( map ) // able to create new map index?
{
if ( ev->Good() ) // no errors during construction?
{
morkRowMapIter i(ev, &mRowSpace_Rows);
mork_change* c = 0;
morkRow* row = 0;
mork_aid aidKey = 0;
for ( c = i.FirstRow(ev, &row); c && ev->Good();
c = i.NextRow(ev, &row) ) // another row in space?
{
aidKey = row->GetCellAtomAid(ev, inCol);
if ( aidKey ) // row has indexed attribute?
map->AddAid(ev, aidKey, row); // include in map
}
}
if ( ev->Good() ) // no errors constructing index?
outMap = map; // return from function
else
map->CutStrongRef(ev); // discard map on error
}
}
else
ev->NilPointerError();
return outMap;
}
morkAtomRowMap*
morkRowSpace::ForceMap(morkEnv* ev, mork_column inCol)
{
morkAtomRowMap* outMap = this->FindMap(ev, inCol);
if ( !outMap && ev->Good() ) // no such existing index?
{
if ( mRowSpace_IndexCount < morkRowSpace_kMaxIndexCount )
{
morkAtomRowMap* map = this->make_index(ev, inCol);
if ( map ) // created a new index for col?
{
mork_count wrap = 0; // count times wrap-around occurs
morkAtomRowMap** slot = mRowSpace_IndexCache; // table
morkAtomRowMap** end = slot + morkRowSpace_kPrimeCacheSize;
slot += ( inCol % morkRowSpace_kPrimeCacheSize ); // hash
while ( *slot ) // empty slot not yet found?
{
if ( ++slot >= end ) // wrap around?
{
slot = mRowSpace_IndexCache; // back to table start
if ( ++wrap > 1 ) // wrapped more than once?
{
ev->NewError("no free cache slots"); // disaster
break; // end while loop
}
}
}
if ( ev->Good() ) // everything went just fine?
{
++mRowSpace_IndexCount; // note another new map
*slot = map; // install map in the hash table
outMap = map; // return the new map from function
}
else
map->CutStrongRef(ev); // discard map on error
}
}
else
ev->NewError("too many indexes"); // why so many indexes?
}
return outMap;
}
morkAtomRowMap*
morkRowSpace::FindMap(morkEnv* ev, mork_column inCol)
{
if ( mRowSpace_IndexCount && ev->Good() )
{
mork_count wrap = 0; // count times wrap-around occurs
morkAtomRowMap** slot = mRowSpace_IndexCache; // table
morkAtomRowMap** end = slot + morkRowSpace_kPrimeCacheSize;
slot += ( inCol % morkRowSpace_kPrimeCacheSize ); // hash
morkAtomRowMap* map = *slot;
while ( map ) // another used slot to examine?
{
if ( inCol == map->mAtomRowMap_IndexColumn ) // found col?
return map;
if ( ++slot >= end ) // wrap around?
{
slot = mRowSpace_IndexCache;
if ( ++wrap > 1 ) // wrapped more than once?
return (morkAtomRowMap*) 0; // stop searching
}
map = *slot;
}
}
return (morkAtomRowMap*) 0;
}
morkRow*
morkRowSpace::FindRow(morkEnv* ev, mork_column inCol, const mdbYarn* inYarn)
{
morkRow* outRow = 0;
morkAtom* atom = mSpace_Store->YarnToAtom(ev, inYarn);
if ( atom ) // have or created an atom corresponding to input yarn?
{
mork_aid atomAid = atom->GetBookAtomAid();
if ( atomAid ) // atom has an identity for use in hash table?
{
morkAtomRowMap* map = this->ForceMap(ev, inCol);
if ( map ) // able to find or create index for col?
{
outRow = map->GetAid(ev, atomAid); // search for row
}
}
}
return outRow;
}
morkRow*
morkRowSpace::NewRowWithOid(morkEnv* ev, const mdbOid* inOid)

Просмотреть файл

@ -43,12 +43,21 @@
#include "morkTable.h"
#endif
#ifndef _MORKARRAY_
#include "morkArray.h"
#endif
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#define morkDerived_kRowSpace /*i*/ 0x7253 /* ascii 'rS' */
#define morkRowSpace_kStartRowMapSlotCount 512
#define morkRowSpace_kMaxIndexCount 8 /* no more indexes than this */
#define morkRowSpace_kPrimeCacheSize 17 /* should be prime number */
class morkAtomRowMap;
/*| morkRowSpace:
|*/
class morkRowSpace : public morkSpace { //
@ -76,11 +85,18 @@ class morkRowSpace : public morkSpace { //
public: // state is public because the entire Mork system is private
nsIMdbHeap* mRowSpace_SlotHeap;
morkRowMap mRowSpace_Rows; // hash table of morkRow instances
morkTableMap mRowSpace_Tables; // all the tables in this row scope
mork_tid mRowSpace_NextTableId; // for auto-assigning table IDs
mork_rid mRowSpace_NextRowId; // for auto-assigning row IDs
mork_tid mRowSpace_NextTableId; // for auto-assigning table IDs
mork_rid mRowSpace_NextRowId; // for auto-assigning row IDs
mork_count mRowSpace_IndexCount; // if nonzero, row indexes exist
// every nonzero slot in IndexCache is a strong ref to a morkAtomRowMap:
morkAtomRowMap* mRowSpace_IndexCache[ morkRowSpace_kPrimeCacheSize ];
// { ===== begin morkNode interface =====
public: // morkNode virtual methods
@ -131,6 +147,14 @@ public: // other space methods
morkRow* NewRowWithOid(morkEnv* ev, const mdbOid* inOid);
morkRow* NewRow(morkEnv* ev);
morkRow* FindRow(morkEnv* ev, mork_column inColumn, const mdbYarn* inYarn);
morkAtomRowMap* ForceMap(morkEnv* ev, mork_column inColumn);
morkAtomRowMap* FindMap(morkEnv* ev, mork_column inColumn);
protected: // internal utilities
morkAtomRowMap* make_index(morkEnv* ev, mork_column inColumn);
public: // typesafe refcounting inlines calling inherited morkNode methods
static void SlotWeakRowSpace(morkRowSpace* me,
morkEnv* ev, morkRowSpace** ioSlot)

Просмотреть файл

@ -1,305 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _MDB_
#include "mdb.h"
#endif
#ifndef _MORK_
#include "mork.h"
#endif
#ifndef _MORKSINK_
#include "morkSink.h"
#endif
#ifndef _MORKENV_
#include "morkEnv.h"
#endif
#ifndef _MORKBLOB_
#include "morkBlob.h"
#endif
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
/*virtual*/ morkSink::~morkSink()
{
mSink_At = 0;
mSink_End = 0;
}
/*virtual*/ void
morkSpool::FlushSink(morkEnv* ev) // sync mSpool_Coil->mBuf_Fill
{
morkCoil* coil = mSpool_Coil;
if ( coil )
{
mork_u1* body = (mork_u1*) coil->mBuf_Body;
if ( body )
{
mork_u1* at = mSink_At;
mork_u1* end = mSink_End;
if ( at >= body && at <= end ) // expected cursor order?
{
mork_fill fill = at - body; // current content size
if ( fill <= coil->mBlob_Size )
coil->mBuf_Fill = fill;
else
{
coil->BlobFillOverSizeError(ev);
coil->mBuf_Fill = coil->mBlob_Size; // make it safe
}
}
else
this->BadSpoolCursorOrderError(ev);
}
else
coil->NilBufBodyError(ev);
}
else
this->NilSpoolCoilError(ev);
}
/*virtual*/ void
morkSpool::SpillPutc(morkEnv* ev, int c) // grow coil and write byte
{
morkCoil* coil = mSpool_Coil;
if ( coil )
{
mork_u1* body = (mork_u1*) coil->mBuf_Body;
if ( body )
{
mork_u1* at = mSink_At;
mork_u1* end = mSink_End;
if ( at >= body && at <= end ) // expected cursor order?
{
mork_size size = coil->mBlob_Size;
mork_fill fill = at - body; // current content size
if ( fill <= size ) // less content than medium size?
{
coil->mBuf_Fill = fill;
if ( at >= end ) // need to grow the coil?
{
if ( size > 2048 ) // grow slower over 2K?
size += 512;
else
{
mork_size growth = ( size * 4 ) / 3; // grow by 33%
if ( growth < 64 ) // grow faster under (64 * 3)?
growth = 64;
size += growth;
}
if ( coil->GrowCoil(ev, size) ) // made coil bigger?
{
body = (mork_u1*) coil->mBuf_Body;
if ( body ) // have a coil body?
{
mSink_At = at = body + fill;
mSink_End = end = body + coil->mBlob_Size;
}
else
coil->NilBufBodyError(ev);
}
}
if ( ev->Good() ) // seem ready to write byte c?
{
if ( at < end ) // morkSink::Putc() would succeed?
{
*at++ = c;
mSink_At = at;
coil->mBuf_Fill = fill + 1;
}
else
this->BadSpoolCursorOrderError(ev);
}
}
else // fill exceeds size
{
coil->BlobFillOverSizeError(ev);
coil->mBuf_Fill = coil->mBlob_Size; // make it safe
}
}
else
this->BadSpoolCursorOrderError(ev);
}
else
coil->NilBufBodyError(ev);
}
else
this->NilSpoolCoilError(ev);
}
// ````` ````` ````` ````` ````` ````` ````` `````
// public: // public non-poly morkSink methods
/*virtual*/
morkSpool::~morkSpool()
// Zero all slots to show this sink is disabled, but destroy no memory.
// Note it is typically unnecessary to flush this coil sink, since all
// content is written directly to the coil without any buffering.
{
mSink_At = 0;
mSink_End = 0;
mSpool_Coil = 0;
}
morkSpool::morkSpool(morkEnv* ev, morkCoil* ioCoil)
// After installing the coil, calls Seek(ev, 0) to prepare for writing.
: morkSink()
, mSpool_Coil( 0 )
{
mSink_At = 0; // set correctly later in Seek()
mSink_End = 0; // set correctly later in Seek()
if ( ev->Good() )
{
if ( ioCoil )
{
mSpool_Coil = ioCoil;
this->Seek(ev, /*pos*/ 0);
}
else
ev->NilPointerError();
}
}
// ----- All boolean return values below are equal to ev->Good(): -----
/*static*/ void
morkSpool::BadSpoolCursorOrderError(morkEnv* ev)
{
ev->NewError("bad morkSpool cursor order");
}
/*static*/ void
morkSpool::NilSpoolCoilError(morkEnv* ev)
{
ev->NewError("nil mSpool_Coil");
}
mork_bool
morkSpool::Seek(morkEnv* ev, mork_pos inPos)
// Changed the current write position in coil's buffer to inPos.
// For example, to start writing the coil from scratch, use inPos==0.
{
morkCoil* coil = mSpool_Coil;
if ( coil )
{
mork_size minSize = inPos + 64;
if ( coil->mBlob_Size < minSize )
coil->GrowCoil(ev, minSize);
if ( ev->Good() )
{
coil->mBuf_Fill = inPos;
mork_u1* body = (mork_u1*) coil->mBuf_Body;
if ( body )
{
mSink_At = body + inPos;
mSink_End = body + coil->mBlob_Size;
}
else
coil->NilBufBodyError(ev);
}
}
else
this->NilSpoolCoilError(ev);
return ev->Good();
}
mork_bool
morkSpool::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
// write inSize bytes of inBuf to current position inside coil's buffer
{
// This method is conceptually very similar to morkStream::Write(),
// and this code was written while looking at that method for clues.
morkCoil* coil = mSpool_Coil;
if ( coil )
{
mork_u1* body = (mork_u1*) coil->mBuf_Body;
if ( body )
{
if ( inBuf && inSize ) // anything to write?
{
mork_u1* at = mSink_At;
mork_u1* end = mSink_End;
if ( at >= body && at <= end ) // expected cursor order?
{
// note coil->mBuf_Fill can be stale after morkSink::Putc():
mork_pos fill = at - body; // current content size
mork_num space = end - at; // space left in body
if ( space < inSize ) // not enough to hold write?
{
mork_size minGrowth = space + 16;
mork_size minSize = coil->mBlob_Size + minGrowth;
if ( coil->GrowCoil(ev, minSize) )
{
body = (mork_u1*) coil->mBuf_Body;
if ( body )
{
mSink_At = at = body + fill;
mSink_End = end = body + coil->mBlob_Size;
space = end - at; // space left in body
}
else
coil->NilBufBodyError(ev);
}
}
if ( ev->Good() )
{
if ( space >= inSize ) // enough room to hold write?
{
MORK_MEMCPY(at, inBuf, inSize); // into body
mSink_At = at + inSize; // advance past written bytes
coil->mBuf_Fill = fill + inSize; // "flush" to fix fill
}
else
ev->NewError("insufficient morkSpool space");
}
}
else
this->BadSpoolCursorOrderError(ev);
}
}
else
coil->NilBufBodyError(ev);
}
else
this->NilSpoolCoilError(ev);
return ev->Good();
}
mork_bool
morkSpool::PutString(morkEnv* ev, const char* inString)
// call Write() with inBuf=inString and inSize=strlen(inString),
// unless inString is null, in which case we then do nothing at all.
{
if ( inString )
{
mork_size size = MORK_STRLEN(inString);
this->Write(ev, inString, size);
}
return ev->Good();
}
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

Просмотреть файл

@ -94,7 +94,7 @@ morkSpace::morkSpace(morkEnv* ev,
{
if ( ev->Good() )
{
if ( ioStore )
if ( ioStore && ioSlotHeap )
{
morkStore::SlotWeakStore(ioStore, ev, &mSpace_Store);
if ( ev->Good() )

Просмотреть файл

@ -274,6 +274,7 @@ morkStore::CloseStore(morkEnv* ev) // called by CloseMorkNode();
void
morkStore::RenumberAllCollectableContent(morkEnv* ev)
{
MORK_USED_1(ev);
// do nothing currently
}
@ -367,6 +368,7 @@ morkStore::StageStringAsBookAtom(morkEnv* ev, const char* inString,
morkAtomSpace* morkStore::LazyGetOidAtomSpace(morkEnv* ev)
{
MORK_USED_1(ev);
if ( !mStore_OidAtomSpace )
{
}
@ -551,6 +553,7 @@ mork_bool
morkStore::OpenStoreFile(morkEnv* ev, mork_bool inFrozen,
const char* inFilePath, const mdbOpenPolicy* inOpenPolicy)
{
MORK_USED_1(inOpenPolicy);
morkFile::SlotStrongFile((morkFile*) 0, ev, &mStore_File);
if ( ev->Good() )
{
@ -571,6 +574,7 @@ mork_bool
morkStore::CreateStoreFile(morkEnv* ev,
const char* inFilePath, const mdbOpenPolicy* inOpenPolicy)
{
MORK_USED_1(inOpenPolicy);
morkFile::SlotStrongFile((morkFile*) 0, ev, &mStore_File);
if ( ev->Good() )
{
@ -736,6 +740,7 @@ morkStore::MidToAtom(morkEnv* ev, const morkMid& inMid)
morkStore::SmallTokenToOneByteYarn(morkEnv* ev, mdb_token inToken,
mdbYarn* outYarn)
{
MORK_USED_1(ev);
if ( outYarn->mYarn_Buf && outYarn->mYarn_Size ) // any space in yarn at all?
{
mork_u1* buf = (mork_u1*) outYarn->mYarn_Buf; // for byte arithmetic
@ -1028,10 +1033,14 @@ mork_bool
morkStore::HasTableKind(morkEnv* ev, mdb_scope inRowScope,
mdb_kind inTableKind, mdb_count* outTableCount)
{
MORK_USED_2(inRowScope,inTableKind);
mork_bool outBool = morkBool_kFalse;
mdb_count tableCount = 0;
ev->StubMethodOnlyError();
if ( outTableCount )
*outTableCount = tableCount;
return outBool;
}
@ -1059,6 +1068,22 @@ morkStore::GetTableKind(morkEnv* ev, mdb_scope inRowScope,
return outTable;
}
morkRow*
morkStore::FindRow(morkEnv* ev, mdb_scope inScope, mdb_column inColumn,
const mdbYarn* inYarn)
{
morkRow* outRow = 0;
if ( ev->Good() )
{
morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inScope);
if ( rowSpace )
{
outRow = rowSpace->FindRow(ev, inColumn, inYarn);
}
}
return outRow;
}
morkRow*
morkStore::GetRow(morkEnv* ev, const mdbOid* inOid)
{

Просмотреть файл

@ -294,6 +294,9 @@ public: // other store methods
morkTable* GetTableKind(morkEnv* ev, mdb_scope inRowScope,
mdb_kind inTableKind, mdb_count* outTableCount,
mdb_bool* outMustBeUnique);
morkRow* FindRow(morkEnv* ev, mdb_scope inScope, mdb_column inColumn,
const mdbYarn* inTargetCellValue);
morkRow* GetRow(morkEnv* ev, const mdbOid* inOid);
morkTable* GetTable(morkEnv* ev, const mdbOid* inOid);

Просмотреть файл

@ -381,6 +381,7 @@ morkStream::AcquireBud(morkEnv* ev, nsIMdbHeap* ioHeap)
// behavior is exhibited by the file, so crashes protect old files.
// Note that AcquireBud() is an illegal operation on readonly files.
{
MORK_USED_1(ioHeap);
morkFile* outFile = 0;
morkFile* file = mStream_ContentFile;
if ( this->IsOpenAndActiveFile() && file )
@ -508,7 +509,7 @@ morkStream::Read(morkEnv* ev, void* outBuf, mork_size inSize)
mork_u1* buf = mStream_Buf;
if ( at >= buf && at <= end ) // expected cursor order?
{
mork_num remaining = end - at; // bytes left in buffer
mork_num remaining = (mork_num) (end - at); // bytes left in buffer
mork_num quantum = inSize; // number of bytes to copy
if ( quantum > remaining ) // more than buffer content?
@ -534,7 +535,7 @@ morkStream::Read(morkEnv* ev, void* outBuf, mork_size inSize)
// exhausted the local buffer, so we need to show
// it is now empty, and adjust the current buf pos.
mork_num posDelta = (at - buf); // old buf content
mork_num posDelta = (mork_num) (at - buf); // old buf content
mStream_BufPos += posDelta; // past now empty buf
mStream_At = mStream_ReadEnd = buf; // empty buffer
@ -569,7 +570,7 @@ morkStream::Read(morkEnv* ev, void* outBuf, mork_size inSize)
if ( ev->Bad() )
outActual = 0;
return outActual;
return (mork_size) outActual;
}
/*public virtual*/ mork_pos
@ -658,7 +659,7 @@ morkStream::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
mork_u1* buf = mStream_Buf;
if ( at >= buf && at <= end ) // expected cursor order?
{
mork_num space = end - at; // space left in buffer
mork_num space = (mork_num) (end - at); // space left in buffer
mork_num quantum = inSize; // number of bytes to write
if ( quantum > space ) // more than buffer size?
@ -695,7 +696,7 @@ morkStream::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
if ( ev->Good() ) // no errors?
{
space = end - at; // space left in buffer
space = (mork_num) (end - at); // space left in buffer
if ( space > inSize ) // write to buffer?
{
mStream_Dirty = morkBool_kTrue; // ensure flush
@ -817,7 +818,7 @@ morkStream::spill_buf(morkEnv* ev) // spill/flush from buffer to file
mork_u1* at = mStream_At;
if ( at >= buf && at <= mStream_WriteEnd ) // order?
{
mork_num count = at - buf; // the number of bytes buffered
mork_num count = (mork_num) (at - buf); // bytes buffered
if ( count ) // anything to write to the string?
{
if ( count > mStream_BufSize ) // no more than max?

Просмотреть файл

@ -210,7 +210,7 @@ public: // public non-poly morkStream methods
{ this->PutString(ev, inString); }
void Ungetc(int c) /*i*/
{ if ( mStream_At > mStream_Buf && c > 0 ) *--mStream_At = c; }
{ if ( mStream_At > mStream_Buf && c > 0 ) *--mStream_At = (mork_u1) c; }
// Note Getc() returns EOF consistently after any fill_getc() error occurs.
int Getc(morkEnv* ev) /*i*/
@ -220,7 +220,7 @@ public: // public non-poly morkStream methods
{
mStream_Dirty = morkBool_kTrue;
if ( mStream_At < mStream_WriteEnd )
*mStream_At++ = c;
*mStream_At++ = (mork_u1) c;
else
spill_putc(ev, c);
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше