mork performance improvements by davidmc, r=bienvenu

This commit is contained in:
bienvenu%netscape.com 2000-04-01 17:07:38 +00:00
Родитель 4e09e35e37
Коммит 13937da825
19 изменённых файлов: 598 добавлений и 85 удалений

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

@ -2141,6 +2141,49 @@ public:
nsIMdbRow* ioSourceRow) = 0; // row to duplicate
// } ----- end row methods -----
// { ----- begin blob methods -----
virtual mdb_err SetCellYarn(nsIMdbEnv* ev, // synonym for AddColumn()
mdb_column inColumn, // column to write
const mdbYarn* inYarn) = 0; // reads from yarn slots
// make this text object contain content from the yarn's buffer
virtual mdb_err GetCellYarn(nsIMdbEnv* ev,
mdb_column inColumn, // column to read
mdbYarn* outYarn) = 0; // writes some yarn slots
// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
virtual mdb_err AliasCellYarn(nsIMdbEnv* ev,
mdb_column inColumn, // column to alias
mdbYarn* outYarn) = 0; // writes ALL yarn slots
virtual mdb_err NextCellYarn(nsIMdbEnv* ev, // iterative version of GetCellYarn()
mdb_column* ioColumn, // next column to read
mdbYarn* outYarn) = 0; // writes some yarn slots
// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
//
// The ioColumn argument is an inout parameter which initially contains the
// last column accessed and returns the next column corresponding to the
// content read into the yarn. Callers should start with a zero column
// value to say 'no previous column', which causes the first column to be
// read. Then the value returned in ioColumn is perfect for the next call
// to NextCellYarn(), since it will then be the previous column accessed.
// Callers need only examine the column token returned to see which cell
// in the row is being read into the yarn. When no more columns remain,
// and the iteration has ended, ioColumn will return a zero token again.
// So iterating over cells starts and ends with a zero column token.
virtual mdb_err SeekCellYarn( // resembles nsIMdbRowCellCursor::SeekCell()
nsIMdbEnv* ev, // context
mdb_pos inPos, // position of cell in row sequence
mdb_column* outColumn, // column for this particular cell
mdbYarn* outYarn) = 0; // writes some yarn slots
// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
// Callers can pass nil for outYarn to indicate no interest in content, so
// only the outColumn value is returned. NOTE to subclasses: you must be
// able to ignore outYarn when the pointer is nil; please do not crash.
// } ----- end blob methods -----
// } ===== end nsIMdbRow methods =====
};
@ -2361,3 +2404,4 @@ public:
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#endif /* _MDB_ */

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

@ -373,6 +373,11 @@ morkBookAtom::HashFormAndBody(morkEnv* ev) const
size = ((const morkBigBookAtom*) this)->mBigBookAtom_Size;
body = ((const morkBigBookAtom*) this)->mBigBookAtom_Body;
}
else if ( this->IsFarBook() )
{
size = ((const morkFarBookAtom*) this)->mFarBookAtom_Size;
body = ((const morkFarBookAtom*) this)->mFarBookAtom_Body;
}
else
this->NonBookAtomTypeError(ev);
@ -414,6 +419,12 @@ morkBookAtom::EqualFormAndBody(morkEnv* ev, const morkBookAtom* inAtom) const
body = ((const morkBigBookAtom*) inAtom)->mBigBookAtom_Body;
form = ((const morkBigBookAtom*) inAtom)->mBigBookAtom_Form;
}
else if ( inAtom->IsFarBook() )
{
size = ((const morkFarBookAtom*) inAtom)->mFarBookAtom_Size;
body = ((const morkFarBookAtom*) inAtom)->mFarBookAtom_Body;
form = ((const morkFarBookAtom*) inAtom)->mFarBookAtom_Form;
}
else
inAtom->NonBookAtomTypeError(ev);
@ -433,6 +444,12 @@ morkBookAtom::EqualFormAndBody(morkEnv* ev, const morkBookAtom* inAtom) const
thisBody = ((const morkBigBookAtom*) this)->mBigBookAtom_Body;
thisForm = ((const morkBigBookAtom*) this)->mBigBookAtom_Form;
}
else if ( this->IsFarBook() )
{
thisSize = ((const morkFarBookAtom*) this)->mFarBookAtom_Size;
thisBody = ((const morkFarBookAtom*) this)->mFarBookAtom_Body;
thisForm = ((const morkFarBookAtom*) this)->mFarBookAtom_Form;
}
else
this->NonBookAtomTypeError(ev);
@ -533,4 +550,30 @@ morkBigBookAtom::InitBigBookAtom(morkEnv* ev, const morkBuf& inBuf,
ev->NilPointerError();
}
void morkFarBookAtom::InitFarBookAtom(morkEnv* ev, const morkBuf& inBuf,
mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid)
{
mAtom_Kind = 0;
mAtom_Change = morkChange_kNil;
if ( ioSpace )
{
if ( inAid )
{
mAtom_CellUses = 0;
mAtom_Kind = morkAtom_kKindFarBook;
mAtom_Size = 0;
mBookAtom_Space = ioSpace;
mBookAtom_Id = inAid;
mFarBookAtom_Form = inForm;
mFarBookAtom_Size = inBuf.mBuf_Fill;
mFarBookAtom_Body = (mork_u1*) inBuf.mBuf_Body;
}
else
this->ZeroAidError(ev);
}
else
ev->NilPointerError();
}
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

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

@ -38,6 +38,7 @@
#define morkAtom_kKindBigAnon 'A' /* means morkBigAnonAtom subclass */
#define morkAtom_kKindWeeBook 'b' /* means morkWeeBookAtom subclass */
#define morkAtom_kKindBigBook 'B' /* means morkBigBookAtom subclass */
#define morkAtom_kKindFarBook 'f' /* means morkFarBookAtom subclass */
#define morkAtom_kKindRowOid 'r' /* means morkOidAtom subclass */
#define morkAtom_kKindTableOid 't' /* means morkOidAtom subclass */
@ -59,6 +60,7 @@ public:
mork_bool IsBigAnon() const { return mAtom_Kind == morkAtom_kKindBigAnon; }
mork_bool IsWeeBook() const { return mAtom_Kind == morkAtom_kKindWeeBook; }
mork_bool IsBigBook() const { return mAtom_Kind == morkAtom_kKindBigBook; }
mork_bool IsFarBook() const { return mAtom_Kind == morkAtom_kKindFarBook; }
mork_bool IsRowOid() const { return mAtom_Kind == morkAtom_kKindRowOid; }
mork_bool IsTableOid() const { return mAtom_Kind == morkAtom_kKindTableOid; }
@ -233,9 +235,11 @@ public: // Hash() and Equal() for atom ID maps are same for all subclasses:
public: // Hash() and Equal() for atom body maps know about subclasses:
// YOU CANNOT SUBCLASS morkBookAtom WITHOUT FIXING Hash and Equal METHODS:
mork_u4 HashFormAndBody(morkEnv* ev) const;
mork_bool EqualFormAndBody(morkEnv* ev, const morkBookAtom* inAtom) const;
public: // separation from containing space
void CutBookAtomFromSpace(morkEnv* ev);
@ -245,6 +249,43 @@ private: // copying is not allowed
morkBookAtom& operator=(const morkBookAtom& other);
};
/*| FarBookAtom: this alternative format for book atoms was introduced
**| in May 2000 in order to support finding atoms in hash tables without
**| first copying the strings from original parsing buffers into a new
**| atom format. This was consuming too much time. However, we can
**| use morkFarBookAtom to stage a hash table query, as long as we then
**| fix HashFormAndBody() and EqualFormAndBody() to use morkFarBookAtom
**| correctly.
**|
**|| Note we do NOT intend that instances of morkFarBookAtom will ever
**| be installed in hash tables, because this is not space efficient.
**| We only expect to create temp instances for table lookups.
|*/
class morkFarBookAtom : public morkBookAtom { //
// mork_u1 mAtom_Kind; // identifies a specific atom subclass
// mork_u1 mAtom_CellUses; // number of persistent uses in a cell
// mork_change mAtom_Change; // how has this atom been changed?
// mork_u1 mAtom_Size; // NOT USED IN "BIG" format atoms
// morkAtomSpace* mBookAtom_Space; // mBookAtom_Space->SpaceScope() is scope
// mork_aid mBookAtom_Id; // identity token for this shared atom
public:
mork_cscode mFarBookAtom_Form; // charset format encoding
mork_size mFarBookAtom_Size; // size of content vector
mork_u1* mFarBookAtom_Body; // bytes are elsewere, out of line
public: // empty construction does nothing
morkFarBookAtom() { }
void InitFarBookAtom(morkEnv* ev, const morkBuf& inBuf,
mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid);
private: // copying is not allowed
morkFarBookAtom(const morkFarBookAtom& other);
morkFarBookAtom& operator=(const morkFarBookAtom& other);
};
/*| WeeBookAtom: .
|*/
class morkWeeBookAtom : public morkBookAtom { //
@ -339,3 +380,4 @@ private: // copying is not allowed
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#endif /* _MORKATOM_ */

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

@ -174,7 +174,7 @@ morkAtomSpace::CutAllAtoms(morkEnv* ev, morkPool* ioPool)
morkBookAtom*
morkAtomSpace::MakeBookAtomCopyWithAid(morkEnv* ev,
const morkBigBookAtom& inAtom, mork_aid inAid)
const morkFarBookAtom& inAtom, mork_aid inAid)
// Make copy of inAtom and put it in both maps, using specified ID.
{
morkBookAtom* outAtom = 0;
@ -182,7 +182,7 @@ morkAtomSpace::MakeBookAtomCopyWithAid(morkEnv* ev,
if ( ev->Good() && store )
{
morkPool* pool = this->GetSpaceStorePool();
outAtom = pool->NewBookAtomCopy(ev, inAtom, &store->mStore_Zone);
outAtom = pool->NewFarBookAtomCopy(ev, inAtom, &store->mStore_Zone);
if ( outAtom )
{
if ( store->mStore_CanDirty )
@ -207,7 +207,7 @@ morkAtomSpace::MakeBookAtomCopyWithAid(morkEnv* ev,
}
morkBookAtom*
morkAtomSpace::MakeBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom)
morkAtomSpace::MakeBookAtomCopy(morkEnv* ev, const morkFarBookAtom& inAtom)
// make copy of inAtom and put it in both maps, using a new ID as needed.
{
morkBookAtom* outAtom = 0;
@ -217,7 +217,7 @@ morkAtomSpace::MakeBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom)
if ( store->mStore_CanAutoAssignAtomIdentity )
{
morkPool* pool = this->GetSpaceStorePool();
morkBookAtom* atom = pool->NewBookAtomCopy(ev, inAtom, &mSpace_Store->mStore_Zone);
morkBookAtom* atom = pool->NewFarBookAtomCopy(ev, inAtom, &mSpace_Store->mStore_Zone);
if ( atom )
{
mork_aid id = this->MakeNewAtomId(ev, atom);
@ -289,3 +289,4 @@ morkAtomSpaceMap::morkAtomSpaceMap(morkEnv* ev, const morkUsage& inUsage,
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

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

@ -151,10 +151,10 @@ public: // other space methods
// CutAllAtoms() puts all the atoms back in the pool.
morkBookAtom* MakeBookAtomCopyWithAid(morkEnv* ev,
const morkBigBookAtom& inAtom, mork_aid inAid);
const morkFarBookAtom& inAtom, mork_aid inAid);
// Make copy of inAtom and put it in both maps, using specified ID.
morkBookAtom* MakeBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom);
morkBookAtom* MakeBookAtomCopy(morkEnv* ev, const morkFarBookAtom& inAtom);
// Make copy of inAtom and put it in both maps, using a new ID as needed.
mork_aid MakeNewAtomId(morkEnv* ev, morkBookAtom* ioAtom);
@ -233,3 +233,4 @@ public:
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#endif /* _MORKATOMSPACE_ */

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

@ -104,11 +104,11 @@
/* ===== separating switchable features ===== */
//define MORK_ENABLE_ZONE_ARENAS 1 /* using morkZone for pooling */
#define MORK_ENABLE_ZONE_ARENAS 1 /* using morkZone for pooling */
//define MORK_ENABLE_PROBE_MAPS 1 /* use smaller hash tables */
#define MORK_ENABLE_PROBE_MAPS 1 /* use smaller hash tables */
//define MORK_BEAD_OVER_NODE_MAPS 1 /* use bead not node maps */
#define MORK_BEAD_OVER_NODE_MAPS 1 /* use bead not node maps */
/* ===== pooling ===== */
@ -209,3 +209,4 @@ MORK_LIB(mork_size) mork_strlen(const void* inString);
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#endif /* _MORKCONFIG_ */

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

@ -525,7 +525,7 @@ void
morkParser::ReadCell(morkEnv* ev)
{
mParser_CellMid.ClearMid();
this->StartSpanOnLastByte(ev, &mParser_CellSpan);
// this->StartSpanOnLastByte(ev, &mParser_CellSpan);
morkMid* cellMid = 0; // if mid syntax is used for column
morkBuf* cellBuf = 0; // if naked string is used for column
@ -533,7 +533,7 @@ morkParser::ReadCell(morkEnv* ev)
register int c;
if ( (c = s->Getc(ev)) != EOF && ev->Good() )
{
this->StartSpanOnLastByte(ev, &mParser_ColumnSpan);
// this->StartSpanOnLastByte(ev, &mParser_ColumnSpan);
if ( c == '^' )
{
cellMid = &mParser_CellMid;
@ -547,7 +547,7 @@ morkParser::ReadCell(morkEnv* ev)
}
if ( ev->Good() )
{
this->EndSpanOnThisByte(ev, &mParser_ColumnSpan);
// this->EndSpanOnThisByte(ev, &mParser_ColumnSpan);
mParser_InCell = morkBool_kTrue;
this->OnNewCell(ev, *mParser_CellSpan.AsPlace(),
@ -556,13 +556,13 @@ morkParser::ReadCell(morkEnv* ev)
mParser_CellChange = morkChange_kNil;
if ( (c = this->NextChar(ev)) != EOF && ev->Good() )
{
this->StartSpanOnLastByte(ev, &mParser_SlotSpan);
// this->StartSpanOnLastByte(ev, &mParser_SlotSpan);
if ( c == '=' )
{
morkBuf* buf = this->ReadValue(ev);
if ( buf )
{
this->EndSpanOnThisByte(ev, &mParser_SlotSpan);
// this->EndSpanOnThisByte(ev, &mParser_SlotSpan);
this->OnValue(ev, mParser_SlotSpan, *buf);
}
}
@ -570,7 +570,7 @@ morkParser::ReadCell(morkEnv* ev)
{
if ( this->ReadMid(ev, &mParser_Mid) )
{
this->EndSpanOnThisByte(ev, &mParser_SlotSpan);
// this->EndSpanOnThisByte(ev, &mParser_SlotSpan);
if ( (c = this->NextChar(ev)) != EOF && ev->Good() )
{
if ( c != ')' )
@ -593,7 +593,7 @@ morkParser::ReadCell(morkEnv* ev)
}
}
this->EndSpanOnThisByte(ev, &mParser_CellSpan);
// this->EndSpanOnThisByte(ev, &mParser_CellSpan);
mParser_InCell = morkBool_kFalse;
this->OnCellEnd(ev, mParser_CellSpan);
}
@ -623,7 +623,7 @@ void morkParser::ReadRow(morkEnv* ev, int c)
{
if ( ev->Good() )
{
this->StartSpanOnLastByte(ev, &mParser_RowSpan);
// this->StartSpanOnLastByte(ev, &mParser_RowSpan);
if ( mParser_Change )
mParser_RowChange = mParser_Change;
@ -683,7 +683,7 @@ void morkParser::ReadRow(morkEnv* ev, int c)
mParser_Stream->Ungetc(c);
}
this->EndSpanOnThisByte(ev, &mParser_RowSpan);
// this->EndSpanOnThisByte(ev, &mParser_RowSpan);
mParser_InRow = morkBool_kFalse;
this->OnRowEnd(ev, mParser_RowSpan);
@ -710,7 +710,7 @@ void morkParser::ReadRow(morkEnv* ev, int c)
s->Ungetc(c);
}
this->EndSpanOnThisByte(ev, &mParser_RowSpan);
// this->EndSpanOnThisByte(ev, &mParser_RowSpan);
mParser_InRow = morkBool_kFalse;
this->OnRowEnd(ev, mParser_RowSpan);
}
@ -728,7 +728,7 @@ void morkParser::ReadTable(morkEnv* ev)
// zm:TableItem ::= zm:MetaTable | zm:RowRef | zm:Row
// zm:MetaTable ::= zm:S? '{' zm:S? zm:Cell* zm:S? '}' /* meta attributes */
{
this->StartSpanOnLastByte(ev, &mParser_TableSpan);
// this->StartSpanOnLastByte(ev, &mParser_TableSpan);
if ( mParser_Change )
mParser_TableChange = mParser_Change;
@ -787,7 +787,7 @@ void morkParser::ReadTable(morkEnv* ev)
}
}
this->EndSpanOnThisByte(ev, &mParser_TableSpan);
// this->EndSpanOnThisByte(ev, &mParser_TableSpan);
mParser_InTable = morkBool_kFalse;
this->OnTableEnd(ev, mParser_TableSpan);
@ -930,7 +930,7 @@ void morkParser::ReadAlias(morkEnv* ev)
// zm:Alias ::= zm:S? '(' ('#')? zm:Hex+ zm:S? zm:Value ')'
// zm:Value ::= '=' ([^)$\] | '\' zm:NonCRLF | zm:Continue | zm:Dollar)*
{
this->StartSpanOnLastByte(ev, &mParser_AliasSpan);
// this->StartSpanOnLastByte(ev, &mParser_AliasSpan);
int nextChar;
mork_id hex = this->ReadHex(ev, &nextChar);
@ -949,7 +949,7 @@ void morkParser::ReadAlias(morkEnv* ev)
mParser_Mid.mMid_Buf = this->ReadValue(ev);
if ( mParser_Mid.mMid_Buf )
{
this->EndSpanOnThisByte(ev, &mParser_AliasSpan);
// this->EndSpanOnThisByte(ev, &mParser_AliasSpan);
this->OnAlias(ev, mParser_AliasSpan, mParser_Mid);
}
}
@ -963,7 +963,7 @@ void morkParser::ReadMeta(morkEnv* ev, int inEndMeta)
// zm:MetaTable ::= zm:S? '{' zm:S? zm:Cell* zm:S? '}' /* meta attributes */
// zm:MetaRow ::= zm:S? '[' zm:S? zm:Cell* zm:S? ']' /* meta attributes */
{
this->StartSpanOnLastByte(ev, &mParser_MetaSpan);
// this->StartSpanOnLastByte(ev, &mParser_MetaSpan);
mParser_InMeta = morkBool_kTrue;
this->OnNewMeta(ev, *mParser_MetaSpan.AsPlace());
@ -1014,7 +1014,7 @@ void morkParser::ReadMeta(morkEnv* ev, int inEndMeta)
}
}
this->EndSpanOnThisByte(ev, &mParser_MetaSpan);
// this->EndSpanOnThisByte(ev, &mParser_MetaSpan);
mParser_InMeta = morkBool_kFalse;
this->OnMetaEnd(ev, mParser_MetaSpan);
}
@ -1062,7 +1062,7 @@ mork_bool morkParser::FindGroupEnd(morkEnv* ev)
{
if ( c == '@' ) // maybe start of group ending?
{
this->EndSpanOnThisByte(ev, &mParser_GroupSpan);
// this->EndSpanOnThisByte(ev, &mParser_GroupSpan);
if ( (c = s->Getc(ev)) == '$' ) // '$' follows '@' ?
{
if ( (c = s->Getc(ev)) == '$' ) // '$' follows "@$" ?
@ -1070,7 +1070,7 @@ mork_bool morkParser::FindGroupEnd(morkEnv* ev)
if ( (c = s->Getc(ev)) == '}' )
{
foundEnd = this->ReadEndGroupId(ev);
this->EndSpanOnThisByte(ev, &mParser_GroupSpan);
// this->EndSpanOnThisByte(ev, &mParser_GroupSpan);
}
else
@ -1095,6 +1095,7 @@ void morkParser::ReadGroup(morkEnv* ev)
register int c;
if ( (c = s->Getc(ev)) == '@' )
{
// we really need the following span inside morkBuilder::OnNewGroup():
this->StartSpanOnThisByte(ev, &mParser_GroupSpan);
mork_pos startPos = mParser_GroupSpan.mSpan_Start.mPlace_Pos;
@ -1216,7 +1217,7 @@ void morkParser::ReadDict(morkEnv* ev)
mParser_Change = morkChange_kNil;
mParser_AtomChange = morkChange_kNil;
this->StartSpanOnLastByte(ev, &mParser_DictSpan);
// this->StartSpanOnLastByte(ev, &mParser_DictSpan);
mParser_InDict = morkBool_kTrue;
this->OnNewDict(ev, *mParser_DictSpan.AsPlace());
@ -1239,7 +1240,7 @@ void morkParser::ReadDict(morkEnv* ev)
}
}
this->EndSpanOnThisByte(ev, &mParser_DictSpan);
// this->EndSpanOnThisByte(ev, &mParser_DictSpan);
mParser_InDict = morkBool_kFalse;
this->OnDictEnd(ev, mParser_DictSpan);
@ -1476,3 +1477,4 @@ morkParser::ParseMore( // return count of bytes consumed now
}
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

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

@ -504,6 +504,19 @@ protected: // protected parser helper methods
void StartSpanOnThisByte(morkEnv* ev, morkSpan* ioSpan);
// void EndSpanOnThisByte(morkEnv* ev, morkSpan* ioSpan)
// { MORK_USED_2(ev,ioSpan); }
// void EndSpanOnLastByte(morkEnv* ev, morkSpan* ioSpan)
// { MORK_USED_2(ev,ioSpan); }
// void StartSpanOnLastByte(morkEnv* ev, morkSpan* ioSpan)
// { MORK_USED_2(ev,ioSpan); }
// void StartSpanOnThisByte(morkEnv* ev, morkSpan* ioSpan)
// { MORK_USED_2(ev,ioSpan); }
int eat_line_break(morkEnv* ev, int inLast);
int eat_line_continue(morkEnv* ev); // last char was '\\'
int eat_comment(morkEnv* ev); // last char was '/'
@ -532,3 +545,4 @@ public: // typesafe refcounting inlines calling inherited morkNode methods
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#endif /* _MORKPARSER_ */

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

@ -520,6 +520,43 @@ morkPool::NewBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom,
return newAtom;
}
morkBookAtom*
morkPool::NewFarBookAtomCopy(morkEnv* ev, const morkFarBookAtom& inAtom,
morkZone* ioZone)
// 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.mFarBookAtom_Form;
mork_fill fill = inAtom.mFarBookAtom_Size;
mork_bool needBig = ( form || fill > 255 );
mork_size size = ( needBig )?
morkBigBookAtom::SizeForFill(fill) :
morkWeeBookAtom::SizeForFill(fill);
#ifdef morkZone_CONFIG_ARENA
// a zone 'chip' remembers no size, and so cannot be deallocated:
newAtom = (morkBookAtom*) ioZone->ZoneNewChip(ev, size);
#else /*morkZone_CONFIG_ARENA*/
MORK_USED_1(ioZone);
mPool_Heap->Alloc(ev->AsMdbEnv(), size, (void**) &newAtom);
#endif /*morkZone_CONFIG_ARENA*/
if ( newAtom )
{
morkBuf buf(inAtom.mFarBookAtom_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

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

@ -41,6 +41,7 @@ class morkHandle;
class morkHandleFrame;
class morkHandleFace; // just an opaque cookie type
class morkBigBookAtom;
class morkFarBookAtom;
#define morkDerived_kPool /*i*/ 0x706C /* ascii 'pl' */
@ -149,6 +150,11 @@ public: // other pool methods
// 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* NewFarBookAtomCopy(morkEnv* ev, const morkFarBookAtom& inAtom, morkZone* ioZone);
// 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.
public: // typesafe refcounting inlines calling inherited morkNode methods
static void SlotWeakPool(morkPool* me,
@ -163,3 +169,4 @@ public: // typesafe refcounting inlines calling inherited morkNode methods
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#endif /* _MORKPOOL_ */

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

@ -458,6 +458,59 @@ morkRow::NewCell(morkEnv* ev, mdb_column inColumn,
return (morkCell*) 0;
}
void morkRow::SeekColumn(morkEnv* ev, mdb_pos inPos,
mdb_column* outColumn, mdbYarn* outYarn)
{
morkCell* cells = mRow_Cells;
if ( cells && inPos < mRow_Length && inPos >= 0 )
{
morkCell* c = cells + inPos;
if ( outColumn )
*outColumn = c->GetColumn();
if ( outYarn )
c->mCell_Atom->GetYarn(outYarn); // nil atom works okay here
}
else
{
if ( outColumn )
*outColumn = 0;
if ( outYarn )
((morkAtom*) 0)->GetYarn(outYarn); // yes this will work
}
}
void
morkRow::NextColumn(morkEnv* ev, mdb_column* ioColumn, mdbYarn* outYarn)
{
morkCell* cells = mRow_Cells;
if ( cells )
{
mork_column last = 0;
mork_column inCol = *ioColumn;
morkCell* end = cells + mRow_Length;
while ( cells < end )
{
if ( inCol == last ) // found column?
{
if ( outYarn )
cells->mCell_Atom->GetYarn(outYarn); // nil atom works okay here
*ioColumn = cells->GetColumn();
return; // stop, we are done
}
else
{
last = cells->GetColumn();
++cells;
}
}
}
*ioColumn = 0;
if ( outYarn )
((morkAtom*) 0)->GetYarn(outYarn); // yes this will work
}
morkCell*
morkRow::CellAt(morkEnv* ev, mork_pos inPos) const
{
@ -798,6 +851,18 @@ void morkRow::CutColumn(morkEnv* ev, mdb_column inColumn)
}
}
morkAtom* morkRow::GetColumnAtom(morkEnv* ev, mdb_column inColumn)
{
if ( ev->Good() )
{
mork_pos pos = -1;
morkCell* cell = this->GetCell(ev, inColumn, &pos);
if ( cell )
return cell->mCell_Atom;
}
return (morkAtom*) 0;
}
void morkRow::AddColumn(morkEnv* ev, mdb_column inColumn,
const mdbYarn* inYarn, morkStore* ioStore)
{
@ -885,3 +950,4 @@ morkRow::NewRowCellCursor(morkEnv* ev, mdb_pos inPos)
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

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

@ -105,6 +105,9 @@ public: // flags bit twiddling
mork_bool IsRowDirty() const
{ return ( mRow_Flags & morkRow_kDirtyBit ) != 0; }
mork_bool IsRowUsed() const
{ return mRow_GcUses != 0; }
public: // other row methods
morkRow( ) { }
@ -172,6 +175,13 @@ public: // external row methods
void AddColumn(morkEnv* ev, mdb_column inColumn,
const mdbYarn* inYarn, morkStore* ioStore);
morkAtom* GetColumnAtom(morkEnv* ev, mdb_column inColumn);
void NextColumn(morkEnv* ev, mdb_column* ioColumn, mdbYarn* outYarn);
void SeekColumn(morkEnv* ev, mdb_pos inPos,
mdb_column* outColumn, mdbYarn* outYarn);
void CutColumn(morkEnv* ev, mdb_column inColumn);
morkRowCellCursor* NewRowCellCursor(morkEnv* ev, mdb_pos inPos);
@ -229,3 +239,4 @@ private: // copying is not allowed
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#endif /* _MORKROW_ */

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

@ -404,8 +404,8 @@ morkStore::AcquireStoreHandle(morkEnv* ev)
}
morkMaxBookAtom*
morkStore::StageAliasAsBookAtom(morkEnv* ev, const morkMid* inMid,
morkFarBookAtom*
morkStore::StageAliasAsFarBookAtom(morkEnv* ev, const morkMid* inMid,
morkAtomSpace* ioSpace, mork_cscode inForm)
{
if ( inMid && inMid->mMid_Buf )
@ -415,19 +415,22 @@ morkStore::StageAliasAsBookAtom(morkEnv* ev, const morkMid* inMid,
if ( length <= morkBookAtom_kMaxBodySize )
{
mork_aid dummyAid = 1;
mStore_BookAtom.InitMaxBookAtom(ev, *buf,
//mStore_BookAtom.InitMaxBookAtom(ev, *buf,
// inForm, ioSpace, dummyAid);
mStore_FarBookAtom.InitFarBookAtom(ev, *buf,
inForm, ioSpace, dummyAid);
return &mStore_BookAtom;
return &mStore_FarBookAtom;
}
}
else
ev->NilPointerError();
return (morkMaxBookAtom*) 0;
return (morkFarBookAtom*) 0;
}
morkMaxBookAtom*
morkStore::StageYarnAsBookAtom(morkEnv* ev, const mdbYarn* inYarn,
morkFarBookAtom*
morkStore::StageYarnAsFarBookAtom(morkEnv* ev, const mdbYarn* inYarn,
morkAtomSpace* ioSpace)
{
if ( inYarn && inYarn->mYarn_Buf )
@ -437,25 +440,22 @@ morkStore::StageYarnAsBookAtom(morkEnv* ev, const mdbYarn* inYarn,
{
morkBuf buf(inYarn->mYarn_Buf, length);
mork_aid dummyAid = 1;
mStore_BookAtom.InitMaxBookAtom(ev, buf,
//mStore_BookAtom.InitMaxBookAtom(ev, buf,
// inYarn->mYarn_Form, ioSpace, dummyAid);
mStore_FarBookAtom.InitFarBookAtom(ev, buf,
inYarn->mYarn_Form, ioSpace, dummyAid);
return &mStore_BookAtom;
return &mStore_FarBookAtom;
}
}
else
ev->NilPointerError();
return (morkMaxBookAtom*) 0;
return (morkFarBookAtom*) 0;
}
morkMaxBookAtom*
morkStore::StageStringAsBookAtom(morkEnv* ev, const char* inString,
morkFarBookAtom*
morkStore::StageStringAsFarBookAtom(morkEnv* ev, const char* inString,
mork_cscode inForm, morkAtomSpace* ioSpace)
// StageStringAsBookAtom() returns &mStore_BookAtom if inString is small
// enough, such that strlen(inString) < morkBookAtom_kMaxBodySize. And
// content inside mStore_BookAtom will be the valid atom format for
// inString. This method is the standard way to stage a string as an
// atom for searching or adding new atoms into an atom space hash table.
{
if ( inString )
{
@ -464,14 +464,15 @@ morkStore::StageStringAsBookAtom(morkEnv* ev, const char* inString,
{
morkBuf buf(inString, length);
mork_aid dummyAid = 1;
mStore_BookAtom.InitMaxBookAtom(ev, buf, inForm, ioSpace, dummyAid);
return &mStore_BookAtom;
//mStore_BookAtom.InitMaxBookAtom(ev, buf, inForm, ioSpace, dummyAid);
mStore_FarBookAtom.InitFarBookAtom(ev, buf, inForm, ioSpace, dummyAid);
return &mStore_FarBookAtom;
}
}
else
ev->NilPointerError();
return (morkMaxBookAtom*) 0;
return (morkFarBookAtom*) 0;
}
morkAtomSpace* morkStore::LazyGetOidAtomSpace(morkEnv* ev)
@ -727,8 +728,8 @@ morkStore::YarnToAtom(morkEnv* ev, const mdbYarn* inYarn)
morkAtomSpace* groundSpace = this->LazyGetGroundAtomSpace(ev);
if ( groundSpace )
{
morkMaxBookAtom* keyAtom =
this->StageYarnAsBookAtom(ev, inYarn, groundSpace);
morkFarBookAtom* keyAtom =
this->StageYarnAsFarBookAtom(ev, inYarn, groundSpace);
if ( keyAtom )
{
@ -775,8 +776,8 @@ morkStore::MidToOid(morkEnv* ev, const morkMid& inMid, mdbOid* outOid)
{
mork_cscode form = 0; // default
mork_aid aid = 1; // dummy
mStore_BookAtom.InitMaxBookAtom(ev, *buf, form, groundSpace, aid);
morkMaxBookAtom* keyAtom = &mStore_BookAtom;
mStore_FarBookAtom.InitFarBookAtom(ev, *buf, form, groundSpace, aid);
morkFarBookAtom* keyAtom = &mStore_FarBookAtom;
morkAtomBodyMap* map = &groundSpace->mAtomSpace_AtomBodies;
morkBookAtom* bookAtom = map->GetAtom(ev, keyAtom);
if ( bookAtom )
@ -961,8 +962,8 @@ morkStore::AddAlias(morkEnv* ev, const morkMid& inMid, mork_cscode inForm)
morkAtomSpace* atomSpace = this->LazyGetAtomSpace(ev, oid->mOid_Scope);
if ( atomSpace )
{
morkMaxBookAtom* keyAtom =
this->StageAliasAsBookAtom(ev, &inMid, atomSpace, inForm);
morkFarBookAtom* keyAtom =
this->StageAliasAsFarBookAtom(ev, &inMid, atomSpace, inForm);
if ( keyAtom )
{
morkAtomAidMap* map = &atomSpace->mAtomSpace_AtomAids;
@ -1040,12 +1041,13 @@ morkStore::BufToToken(morkEnv* ev, const morkBuf* inBuf)
morkAtomSpace* space = this->LazyGetGroundColumnSpace(ev);
if ( space )
{
morkMaxBookAtom* keyAtom = 0;
morkFarBookAtom* keyAtom = 0;
if ( length <= morkBookAtom_kMaxBodySize )
{
mork_aid aid = 1; // dummy
mStore_BookAtom.InitMaxBookAtom(ev, *inBuf, form, space, aid);
keyAtom = &mStore_BookAtom;
//mStore_BookAtom.InitMaxBookAtom(ev, *inBuf, form, space, aid);
mStore_FarBookAtom.InitFarBookAtom(ev, *inBuf, form, space, aid);
keyAtom = &mStore_FarBookAtom;
}
if ( keyAtom )
{
@ -1087,8 +1089,8 @@ morkStore::StringToToken(morkEnv* ev, const char* inTokenName)
morkAtomSpace* groundSpace = this->LazyGetGroundColumnSpace(ev);
if ( groundSpace )
{
morkMaxBookAtom* keyAtom =
this->StageStringAsBookAtom(ev, inTokenName, form, groundSpace);
morkFarBookAtom* keyAtom =
this->StageStringAsFarBookAtom(ev, inTokenName, form, groundSpace);
if ( keyAtom )
{
morkAtomBodyMap* map = &groundSpace->mAtomSpace_AtomBodies;
@ -1129,8 +1131,8 @@ morkStore::QueryToken(morkEnv* ev, const char* inTokenName)
morkAtomSpace* groundSpace = this->LazyGetGroundColumnSpace(ev);
if ( groundSpace )
{
morkMaxBookAtom* keyAtom =
this->StageStringAsBookAtom(ev, inTokenName, form, groundSpace);
morkFarBookAtom* keyAtom =
this->StageStringAsFarBookAtom(ev, inTokenName, form, groundSpace);
if ( keyAtom )
{
morkAtomBodyMap* map = &groundSpace->mAtomSpace_AtomBodies;
@ -1334,3 +1336,4 @@ morkStore::OidToTable(morkEnv* ev, const mdbOid* inOid,
}
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

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

@ -178,7 +178,9 @@ public: // state is public because the entire Mork system is private
morkPool mStore_Pool;
// we alloc a max size book atom to reuse space for atom map key searches:
morkMaxBookAtom mStore_BookAtom; // staging area for atom map searches
// morkMaxBookAtom mStore_BookAtom; // staging area for atom map searches
morkFarBookAtom mStore_FarBookAtom; // staging area for atom map searches
// GroupIdentity should be one more than largest seen in a parsed db file:
mork_gid mStore_CommitGroupIdentity; // transaction ID number
@ -241,21 +243,16 @@ public: // setting store and all subspaces canDirty:
void SetStoreAndAllSpacesCanDirty(morkEnv* ev, mork_bool inCanDirty);
public: // building an atom inside mStore_BookAtom from a char* string
public: // building an atom inside mStore_FarBookAtom from a char* string
morkMaxBookAtom* StageAliasAsBookAtom(morkEnv* ev,
morkFarBookAtom* StageAliasAsFarBookAtom(morkEnv* ev,
const morkMid* inMid, morkAtomSpace* ioSpace, mork_cscode inForm);
morkMaxBookAtom* StageYarnAsBookAtom(morkEnv* ev,
morkFarBookAtom* StageYarnAsFarBookAtom(morkEnv* ev,
const mdbYarn* inYarn, morkAtomSpace* ioSpace);
morkMaxBookAtom* StageStringAsBookAtom(morkEnv* ev,
morkFarBookAtom* StageStringAsFarBookAtom(morkEnv* ev,
const char* inString, mork_cscode inForm, morkAtomSpace* ioSpace);
// StageStringAsBookAtom() returns &mStore_BookAtom if inString is small
// enough, such that strlen(inString) < morkBookAtom_kMaxBodySize. And
// content inside mStore_BookAtom will be the valid atom format for
// inString. This method is the standard way to stage a string as an
// atom for searching or adding new atoms into an atom space hash table.
public: // determining whether incremental writing is a good use of time:
@ -410,3 +407,4 @@ public: // typesafe refcounting inlines calling inherited morkNode methods
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#endif /* _MORKSTORE_ */

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

@ -827,3 +827,4 @@ morkTableMap::morkTableMap(morkEnv* ev, const morkUsage& inUsage,
}
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

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

@ -143,7 +143,7 @@ public: // state is public because the entire Mork system is private
mork_u1 mTable_Pad; // for u4 alignment
public: // flags bit twiddling
void SetTableUnique() { mTable_Flags |= morkTable_kUniqueBit; }
void SetTableVerbose() { mTable_Flags |= morkTable_kVerboseBit; }
void SetTableNoted() { mTable_Flags |= morkTable_kNotedBit; }
@ -260,6 +260,9 @@ public: // other table methods
mork_count GetRowCount() const { return mTable_RowArray.mArray_Fill; }
mork_bool IsTableUsed() const
{ return (mTable_GcUses != 0 || this->GetRowCount() != 0); }
void GetTableOid(morkEnv* ev, mdbOid* outOid);
mork_pos ArrayHasOid(morkEnv* ev, const mdbOid* inOid);
mork_bool MapHasOid(morkEnv* ev, const mdbOid* inOid);
@ -441,3 +444,4 @@ public:
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#endif /* _MORKTABLE_ */

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

@ -547,7 +547,56 @@ morkWriter::WriteAtomSpaceAsDict(morkEnv* ev, morkAtomSpace* ioSpace)
++mWriter_LineSize;
}
}
/*
(I'm putting the text of this message in file morkWriter.cpp.)
I'm making a change which should cause rows and tables to go away
when a Mork db is compress committed, when the rows and tables
are no longer needed. Because this is subtle, I'm describing it
here in case misbehavior is ever observed. Otherwise you'll have
almost no hope of fixing a related bug.
This is done entirely in morkWriter.cpp: morkWriter::DirtyAll(),
which currently marks all rows and tables dirty so they will be
written in a later phase of the commit. My change is to merely
selectively not mark certain rows and tables dirty, when they seem
to be superfluous.
A row is no longer needed when the mRow_GcUses slot hits zero, and
this is used by the following inline morkRow method:
mork_bool IsRowUsed() const { return mRow_GcUses != 0; }
Naturally disaster ensues if mRow_GcUses is ever smaller than right.
Similarly, we should drop tables when mTable_GcUses hits zero, but
only when a table contains no row members. We consider tables to
self reference (and prevent collection) when they contain content.
Again, disaster ensues if mTable_GcUses is ever smaller than right.
mork_count GetRowCount() const
{ return mTable_RowArray.mArray_Fill; }
mork_bool IsTableUsed() const
{ return (mTable_GcUses != 0 || this->GetRowCount() != 0); }
Now let's question why the design involves filtering what gets set
to dirty. Why not apply a filter in the later phase when we write
content? Because I'm afraid of missing some subtle interaction in
updating table and row relationships. It seems safer to write a row
or table when it starts out dirty, before morkWriter::DirtyAll() is
called. So this design calls for writing out rows and tables when
they are still clearly used, and additionally, <i>when we have just
been actively writing to them right before this commit</i>.
Presumably if they are truly useless, they will no longer be dirtied
in later sessions and will get collected during the next compress
commit. So we wait to collect them until they become all dead, and
not just mostly dead. (At which time you can feel free to go through
their pockets looking for loose change.)
*/
mork_bool
morkWriter::DirtyAll(morkEnv* ev)
// DirtyAll() visits every store sub-object and marks
@ -638,10 +687,13 @@ morkWriter::DirtyAll(morkEnv* ev)
for ( c = ri->FirstRow(ev, &row); c && ev->Good();
c = ri->NextRow(ev, &row) )
{
if ( row && row->IsRow() )
if ( row && row->IsRow() ) // need to dirty row?
{
row->DirtyAllRowContent(ev);
++mWriter_TotalCount;
if ( row->IsRowUsed() || row->IsRowDirty() )
{
row->DirtyAllRowContent(ev);
++mWriter_TotalCount;
}
}
else
row->NonRowTypeWarning(ev);
@ -666,13 +718,16 @@ morkWriter::DirtyAll(morkEnv* ev)
c = ti->NextTable(ev, tableKey, &table) )
#endif /*MORK_BEAD_OVER_NODE_MAPS*/
{
if ( table && table->IsTable() )
if ( table && table->IsTable() ) // need to dirty table?
{
// table->DirtyAllTableContent(ev);
// only necessary to mark table itself dirty:
table->SetTableDirty();
table->SetTableRewrite();
++mWriter_TotalCount;
if ( table->IsTableUsed() || table->IsTableDirty() )
{
// table->DirtyAllTableContent(ev);
// only necessary to mark table itself dirty:
table->SetTableDirty();
table->SetTableRewrite();
++mWriter_TotalCount;
}
}
else
table->NonTableTypeWarning(ev);
@ -1043,7 +1098,7 @@ morkWriter::WriteAllStoreTables(morkEnv* ev)
if ( row && row->IsRow() )
{
// later we should also check that table use count is nonzero:
if ( row->IsRowDirty() )
if ( row->IsRowDirty() ) // && row->IsRowUsed() ??
{
mWriter_BeVerbose = ev->mEnv_BeVerbose;
if ( this->PutRowDict(ev, row) )
@ -2107,3 +2162,4 @@ morkWriter::PutRow(morkEnv* ev, morkRow* ioRow)
}
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

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

@ -36,6 +36,10 @@
#include "morkHandle.h"
#endif
#ifndef _MORKATOM_
#include "morkAtom.h"
#endif
#ifndef _MORKROW_
#include "morkRow.h"
#endif
@ -688,8 +692,142 @@ orkinRow::SetRow( // make exact duplicate of another row
}
// } ----- end row methods -----
// { ----- begin blob methods -----
/*virtual*/ mdb_err
orkinRow::SetCellYarn( // synonym for AddColumn()
nsIMdbEnv* mev, // context
mdb_column inColumn, // column to add
const mdbYarn* inYarn)
{
mdb_err outErr = 0;
morkRow* row = 0;
morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
&outErr, &row);
if ( ev )
{
morkStore* store = this->CanUseRowStore(ev);
if ( store )
row->AddColumn(ev, inColumn, inYarn, store);
outErr = ev->AsErr();
}
return outErr;
}
/*virtual*/ mdb_err
orkinRow::GetCellYarn(
nsIMdbEnv* mev, // context
mdb_column inColumn, // column to read
mdbYarn* outYarn) // writes some yarn slots
// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
{
mdb_err outErr = 0;
morkRow* row = 0;
morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
&outErr, &row);
if ( ev )
{
morkStore* store = this->CanUseRowStore(ev);
if ( store )
{
morkAtom* atom = row->GetColumnAtom(ev, inColumn);
atom->GetYarn(outYarn);
// note nil atom works and sets yarn correctly
}
outErr = ev->AsErr();
}
return outErr;
}
/*virtual*/ mdb_err
orkinRow::AliasCellYarn(
nsIMdbEnv* mev, // context
mdb_column inColumn, // column to alias
mdbYarn* outYarn) // writes ALL yarn slots
{
mdb_err outErr = 0;
morkRow* row = 0;
morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
&outErr, &row);
if ( ev )
{
morkStore* store = this->CanUseRowStore(ev);
if ( store )
{
morkAtom* atom = row->GetColumnAtom(ev, inColumn);
atom->AliasYarn(outYarn);
// note nil atom works and sets yarn correctly
}
outErr = ev->AsErr();
}
return outErr;
}
/*virtual*/ mdb_err
orkinRow::NextCellYarn(nsIMdbEnv* mev, // iterative version of GetCellYarn()
mdb_column* ioColumn, // next column to read
mdbYarn* outYarn) // writes some yarn slots
// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
//
// The ioColumn argument is an inout parameter which initially contains the
// last column accessed and returns the next column corresponding to the
// content read into the yarn. Callers should start with a zero column
// value to say 'no previous column', which causes the first column to be
// read. Then the value returned in ioColumn is perfect for the next call
// to NextCellYarn(), since it will then be the previous column accessed.
// Callers need only examine the column token returned to see which cell
// in the row is being read into the yarn. When no more columns remain,
// and the iteration has ended, ioColumn will return a zero token again.
// So iterating over cells starts and ends with a zero column token.
{
mdb_err outErr = 0;
morkRow* row = 0;
morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
&outErr, &row);
if ( ev )
{
morkStore* store = this->CanUseRowStore(ev);
if ( store )
row->NextColumn(ev, ioColumn, outYarn);
outErr = ev->AsErr();
}
return outErr;
}
/*virtual*/ mdb_err
orkinRow::SeekCellYarn( // resembles nsIMdbRowCellCursor::SeekCell()
nsIMdbEnv* mev, // context
mdb_pos inPos, // position of cell in row sequence
mdb_column* outColumn, // column for this particular cell
mdbYarn* outYarn) // writes some yarn slots
// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
// Callers can pass nil for outYarn to indicate no interest in content, so
// only the outColumn value is returned. NOTE to subclasses: you must be
// able to ignore outYarn when the pointer is nil; please do not crash.
{
mdb_err outErr = 0;
morkRow* row = 0;
morkEnv* ev = this->CanUseRow(mev, /*inMutable*/ morkBool_kFalse,
&outErr, &row);
if ( ev )
{
morkStore* store = this->CanUseRowStore(ev);
if ( store )
row->SeekColumn(ev, inPos, outColumn, outYarn);
outErr = ev->AsErr();
}
return outErr;
}
// } ----- end blob methods -----
// } ===== end nsIMdbRow methods =====
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789

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

@ -224,9 +224,53 @@ public: // type identification
nsIMdbRow* ioSourceRow); // row to duplicate
// } ----- end row methods -----
// { ----- begin blob methods -----
virtual mdb_err SetCellYarn(nsIMdbEnv* ev, // synonym for AddColumn()
mdb_column inColumn, // column to write
const mdbYarn* inYarn); // reads from yarn slots
// make this text object contain content from the yarn's buffer
virtual mdb_err GetCellYarn(nsIMdbEnv* ev,
mdb_column inColumn, // column to read
mdbYarn* outYarn); // writes some yarn slots
// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
virtual mdb_err AliasCellYarn(nsIMdbEnv* ev,
mdb_column inColumn, // column to alias
mdbYarn* outYarn); // writes ALL yarn slots
virtual mdb_err NextCellYarn(nsIMdbEnv* ev, // iterative version of GetCellYarn()
mdb_column* ioColumn, // next column to read
mdbYarn* outYarn); // writes some yarn slots
// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
//
// The ioColumn argument is an inout parameter which initially contains the
// last column accessed and returns the next column corresponding to the
// content read into the yarn. Callers should start with a zero column
// value to say 'no previous column', which causes the first column to be
// read. Then the value returned in ioColumn is perfect for the next call
// to NextCellYarn(), since it will then be the previous column accessed.
// Callers need only examine the column token returned to see which cell
// in the row is being read into the yarn. When no more columns remain,
// and the iteration has ended, ioColumn will return a zero token again.
// So iterating over cells starts and ends with a zero column token.
virtual mdb_err SeekCellYarn( // resembles nsIMdbRowCellCursor::SeekCell()
nsIMdbEnv* ev, // context
mdb_pos inPos, // position of cell in row sequence
mdb_column* outColumn, // column for this particular cell
mdbYarn* outYarn); // writes some yarn slots
// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
// Callers can pass nil for outYarn to indicate no interest in content, so
// only the outColumn value is returned. NOTE to subclasses: you must be
// able to ignore outYarn when the pointer is nil; please do not crash.
// } ----- end blob methods -----
// } ===== end nsIMdbRow methods =====
};
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
#endif /* _ORKINROW_ */