зеркало из https://github.com/mozilla/pjs.git
moving row positions
This commit is contained in:
Родитель
cd19ad349e
Коммит
4c490446a8
|
@ -207,8 +207,11 @@ morkTable::CutTableGcUse(morkEnv* ev)
|
||||||
|
|
||||||
void morkTable::SetTableClean(morkEnv* ev)
|
void morkTable::SetTableClean(morkEnv* ev)
|
||||||
{
|
{
|
||||||
nsIMdbHeap* heap = mTable_Store->mPort_Heap;
|
if ( mTable_ChangeList.HasListMembers() )
|
||||||
mTable_ChangeList.CutAndZapAllListMembers(ev, heap); // forget changes
|
{
|
||||||
|
nsIMdbHeap* heap = mTable_Store->mPort_Heap;
|
||||||
|
mTable_ChangeList.CutAndZapAllListMembers(ev, heap); // forget changes
|
||||||
|
}
|
||||||
mTable_ChangesCount = 0;
|
mTable_ChangesCount = 0;
|
||||||
|
|
||||||
mTable_Flags = 0;
|
mTable_Flags = 0;
|
||||||
|
@ -242,6 +245,31 @@ void morkTable::NoteTableMoveRow(morkEnv* ev, morkRow* ioRow, mork_pos inPos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void morkTable::note_row_move(morkEnv* ev, morkRow* ioRow, mork_pos inNewPos)
|
||||||
|
{
|
||||||
|
if ( this->IsTableRewrite() || this->HasChangeOverflow() )
|
||||||
|
this->NoteTableSetAll(ev);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nsIMdbHeap* heap = mTable_Store->mPort_Heap;
|
||||||
|
morkTableChange* tableChange = new(*heap, ev)
|
||||||
|
morkTableChange(ev, ioRow, inNewPos);
|
||||||
|
if ( tableChange )
|
||||||
|
{
|
||||||
|
if ( ev->Good() )
|
||||||
|
{
|
||||||
|
mTable_ChangeList.PushTail(tableChange);
|
||||||
|
++mTable_ChangesCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tableChange->ZapOldNext(ev, heap);
|
||||||
|
this->NoteTableSetAll(ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void morkTable::note_row_change(morkEnv* ev, mork_change inChange,
|
void morkTable::note_row_change(morkEnv* ev, mork_change inChange,
|
||||||
morkRow* ioRow)
|
morkRow* ioRow)
|
||||||
{
|
{
|
||||||
|
@ -270,8 +298,11 @@ void morkTable::note_row_change(morkEnv* ev, mork_change inChange,
|
||||||
|
|
||||||
void morkTable::NoteTableSetAll(morkEnv* ev)
|
void morkTable::NoteTableSetAll(morkEnv* ev)
|
||||||
{
|
{
|
||||||
nsIMdbHeap* heap = mTable_Store->mPort_Heap;
|
if ( mTable_ChangeList.HasListMembers() )
|
||||||
mTable_ChangeList.CutAndZapAllListMembers(ev, heap); // forget changes
|
{
|
||||||
|
nsIMdbHeap* heap = mTable_Store->mPort_Heap;
|
||||||
|
mTable_ChangeList.CutAndZapAllListMembers(ev, heap); // forget changes
|
||||||
|
}
|
||||||
mTable_ChangesCount = 0;
|
mTable_ChangesCount = 0;
|
||||||
this->SetTableRewrite();
|
this->SetTableRewrite();
|
||||||
}
|
}
|
||||||
|
@ -470,6 +501,118 @@ morkRow* morkTable::find_member_row(morkEnv* ev, morkRow* ioRow)
|
||||||
return (morkRow*) 0;
|
return (morkRow*) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mork_pos
|
||||||
|
morkTable::MoveRow(morkEnv* ev, morkRow* ioRow, // change row position
|
||||||
|
mork_pos inHintFromPos, // suggested hint regarding start position
|
||||||
|
mork_pos inToPos) // desired new position for row ioRow
|
||||||
|
// MoveRow() returns the actual position of ioRow afterwards; this
|
||||||
|
// position is -1 if and only if ioRow was not found as a member.
|
||||||
|
{
|
||||||
|
mork_pos outPos = -1; // means ioRow was not a table member
|
||||||
|
mork_bool canDirty = ( this->IsTableClean() )?
|
||||||
|
this->MaybeDirtySpaceStoreAndTable() : morkBool_kTrue;
|
||||||
|
|
||||||
|
morkRow** rows = (morkRow**) mTable_RowArray.mArray_Slots;
|
||||||
|
mork_count count = mTable_RowArray.mArray_Fill;
|
||||||
|
if ( count && rows && ev->Good() ) // any members at all? no errors?
|
||||||
|
{
|
||||||
|
mork_pos lastPos = count - 1; // index of last row slot
|
||||||
|
|
||||||
|
if ( inToPos > lastPos ) // beyond last used array slot?
|
||||||
|
inToPos = lastPos; // put row into last available slot
|
||||||
|
else if ( inToPos < 0 ) // before first usable slot?
|
||||||
|
inToPos = 0; // put row in very first slow
|
||||||
|
|
||||||
|
if ( inHintFromPos > lastPos ) // beyond last used array slot?
|
||||||
|
inHintFromPos = lastPos; // seek row in last available slot
|
||||||
|
else if ( inHintFromPos < 0 ) // before first usable slot?
|
||||||
|
inHintFromPos = 0; // seek row in very first slow
|
||||||
|
|
||||||
|
morkRow** fromSlot = 0; // becomes nonzero of ioRow is ever found
|
||||||
|
morkRow** rowsEnd = rows + count; // one past last used array slot
|
||||||
|
|
||||||
|
if ( inHintFromPos <= 0 ) // start of table? just scan for row?
|
||||||
|
{
|
||||||
|
morkRow** cursor = rows - 1; // before first array slot
|
||||||
|
while ( ++cursor < rowsEnd )
|
||||||
|
{
|
||||||
|
if ( *cursor == ioRow )
|
||||||
|
{
|
||||||
|
fromSlot = cursor;
|
||||||
|
break; // end while loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // search near the start position and work outwards
|
||||||
|
{
|
||||||
|
morkRow** lo = rows + inHintFromPos; // lowest search point
|
||||||
|
morkRow** hi = lo; // highest search point starts at lowest point
|
||||||
|
|
||||||
|
// Seek ioRow in spiral widening search below and above inHintFromPos.
|
||||||
|
// This is faster when inHintFromPos is at all accurate, but is slower
|
||||||
|
// than a straightforward scan when inHintFromPos is nearly random.
|
||||||
|
|
||||||
|
while ( lo >= rows || hi < rowsEnd ) // keep searching?
|
||||||
|
{
|
||||||
|
if ( lo >= rows ) // low direction search still feasible?
|
||||||
|
{
|
||||||
|
if ( *lo == ioRow ) // actually found the row?
|
||||||
|
{
|
||||||
|
fromSlot = lo;
|
||||||
|
break; // end while loop
|
||||||
|
}
|
||||||
|
--lo; // advance further lower
|
||||||
|
}
|
||||||
|
if ( hi < rowsEnd ) // high direction search still feasible?
|
||||||
|
{
|
||||||
|
if ( *hi == ioRow ) // actually found the row?
|
||||||
|
{
|
||||||
|
fromSlot = hi;
|
||||||
|
break; // end while loop
|
||||||
|
}
|
||||||
|
++hi; // advance further higher
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( fromSlot ) // ioRow was found as a table member?
|
||||||
|
{
|
||||||
|
outPos = fromSlot - rows; // actual position where row was found
|
||||||
|
if ( outPos != inToPos ) // actually need to move this row?
|
||||||
|
{
|
||||||
|
morkRow** toSlot = rows + inToPos; // slot where row must go
|
||||||
|
|
||||||
|
++mTable_RowArray.mArray_Seed; // we modify the array now:
|
||||||
|
|
||||||
|
if ( fromSlot < toSlot ) // row is moving upwards?
|
||||||
|
{
|
||||||
|
morkRow** up = fromSlot; // leading pointer going upward
|
||||||
|
while ( ++up <= toSlot ) // have not gone above destination?
|
||||||
|
{
|
||||||
|
*fromSlot = *up; // shift down one
|
||||||
|
fromSlot = up; // shift trailing pointer up
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // ( fromSlot > toSlot ) // row is moving downwards
|
||||||
|
{
|
||||||
|
morkRow** down = fromSlot; // leading pointer going downward
|
||||||
|
while ( --down >= toSlot ) // have not gone below destination?
|
||||||
|
{
|
||||||
|
*fromSlot = *down; // shift up one
|
||||||
|
fromSlot = down; // shift trailing pointer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*toSlot = ioRow;
|
||||||
|
outPos = inToPos; // okay, we actually moved the row here
|
||||||
|
|
||||||
|
if ( canDirty )
|
||||||
|
this->note_row_move(ev, ioRow, inToPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return outPos;
|
||||||
|
}
|
||||||
|
|
||||||
mork_bool
|
mork_bool
|
||||||
morkTable::AddRow(morkEnv* ev, morkRow* ioRow)
|
morkTable::AddRow(morkEnv* ev, morkRow* ioRow)
|
||||||
{
|
{
|
||||||
|
|
|
@ -209,13 +209,14 @@ public: // noting table changes
|
||||||
void NoteTableMoveRow(morkEnv* ev, morkRow* ioRow, mork_pos inPos);
|
void NoteTableMoveRow(morkEnv* ev, morkRow* ioRow, mork_pos inPos);
|
||||||
|
|
||||||
void note_row_change(morkEnv* ev, mork_change inChange, morkRow* ioRow);
|
void note_row_change(morkEnv* ev, mork_change inChange, morkRow* ioRow);
|
||||||
|
void note_row_move(morkEnv* ev, morkRow* ioRow, mork_pos inNewPos);
|
||||||
|
|
||||||
void NoteTableAddRow(morkEnv* ev, morkRow* ioRow)
|
void NoteTableAddRow(morkEnv* ev, morkRow* ioRow)
|
||||||
{ this->note_row_change(ev, morkChange_kAdd, ioRow); }
|
{ this->note_row_change(ev, morkChange_kAdd, ioRow); }
|
||||||
|
|
||||||
void NoteTableCutRow(morkEnv* ev, morkRow* ioRow)
|
void NoteTableCutRow(morkEnv* ev, morkRow* ioRow)
|
||||||
{ this->note_row_change(ev, morkChange_kCut, ioRow); }
|
{ this->note_row_change(ev, morkChange_kCut, ioRow); }
|
||||||
|
|
||||||
protected: // internal row map methods
|
protected: // internal row map methods
|
||||||
|
|
||||||
morkRow* find_member_row(morkEnv* ev, morkRow* ioRow);
|
morkRow* find_member_row(morkEnv* ev, morkRow* ioRow);
|
||||||
|
@ -247,6 +248,13 @@ public: // other table methods
|
||||||
mork_bool AddRow(morkEnv* ev, morkRow* ioRow); // returns ev->Good()
|
mork_bool AddRow(morkEnv* ev, morkRow* ioRow); // returns ev->Good()
|
||||||
mork_bool CutRow(morkEnv* ev, morkRow* ioRow); // returns ev->Good()
|
mork_bool CutRow(morkEnv* ev, morkRow* ioRow); // returns ev->Good()
|
||||||
mork_bool CutAllRows(morkEnv* ev); // returns ev->Good()
|
mork_bool CutAllRows(morkEnv* ev); // returns ev->Good()
|
||||||
|
|
||||||
|
mork_pos MoveRow(morkEnv* ev, morkRow* ioRow, // change row position
|
||||||
|
mork_pos inHintFromPos, // suggested hint regarding start position
|
||||||
|
mork_pos inToPos); // desired new position for row ioRow
|
||||||
|
// MoveRow() returns the actual position of ioRow afterwards; this
|
||||||
|
// position is -1 if and only if ioRow was not found as a member.
|
||||||
|
|
||||||
|
|
||||||
morkTableRowCursor* NewTableRowCursor(morkEnv* ev, mork_pos inRowPos);
|
morkTableRowCursor* NewTableRowCursor(morkEnv* ev, mork_pos inRowPos);
|
||||||
|
|
||||||
|
|
|
@ -1122,18 +1122,25 @@ orkinTable::MoveOid( // change position of row in unsorted table
|
||||||
nsIMdbEnv* mev, // context
|
nsIMdbEnv* mev, // context
|
||||||
const mdbOid* inOid, // row oid to find in table
|
const mdbOid* inOid, // row oid to find in table
|
||||||
mdb_pos inHintFromPos, // suggested hint regarding start position
|
mdb_pos inHintFromPos, // suggested hint regarding start position
|
||||||
mdb_pos inToPos, // desired new position for row inRowId
|
mdb_pos inToPos, // desired new position for row inOid
|
||||||
mdb_pos* outActualPos) // actual new position of row in table
|
mdb_pos* outActualPos) // actual new position of row in table
|
||||||
{
|
{
|
||||||
MORK_USED_3(inHintFromPos,inToPos,inOid);
|
|
||||||
mdb_err outErr = 0;
|
mdb_err outErr = 0;
|
||||||
mdb_pos actualPos = 0;
|
mdb_pos actualPos = -1; // meaning it was never found in table
|
||||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||||
if ( ev )
|
if ( ev )
|
||||||
{
|
{
|
||||||
// remember table->MaybeDirtySpaceStoreAndTable();
|
morkTable* table = (morkTable*) mHandle_Object;
|
||||||
|
morkStore* store = table->mTable_Store;
|
||||||
|
if ( inOid && store )
|
||||||
|
{
|
||||||
|
morkRow* row = store->GetRow(ev, inOid);
|
||||||
|
if ( row )
|
||||||
|
actualPos = table->MoveRow(ev, row, inHintFromPos, inToPos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ev->NilPointerError();
|
||||||
|
|
||||||
ev->StubMethodOnlyError();
|
|
||||||
outErr = ev->AsErr();
|
outErr = ev->AsErr();
|
||||||
}
|
}
|
||||||
if ( outActualPos )
|
if ( outActualPos )
|
||||||
|
@ -1146,18 +1153,21 @@ orkinTable::MoveRow( // change position of row in unsorted table
|
||||||
nsIMdbEnv* mev, // context
|
nsIMdbEnv* mev, // context
|
||||||
nsIMdbRow* ioRow, // row oid to find in table
|
nsIMdbRow* ioRow, // row oid to find in table
|
||||||
mdb_pos inHintFromPos, // suggested hint regarding start position
|
mdb_pos inHintFromPos, // suggested hint regarding start position
|
||||||
mdb_pos inToPos, // desired new position for row inRowId
|
mdb_pos inToPos, // desired new position for row ioRow
|
||||||
mdb_pos* outActualPos) // actual new position of row in table
|
mdb_pos* outActualPos) // actual new position of row in table
|
||||||
{
|
{
|
||||||
MORK_USED_3(inHintFromPos,inToPos,ioRow);
|
mdb_pos actualPos = -1; // meaning it was never found in table
|
||||||
mdb_pos actualPos = 0;
|
|
||||||
mdb_err outErr = 0;
|
mdb_err outErr = 0;
|
||||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||||
if ( ev )
|
if ( ev )
|
||||||
{
|
{
|
||||||
// remember table->MaybeDirtySpaceStoreAndTable();
|
morkRow* row = 0;
|
||||||
|
orkinRow* orow = (orkinRow*) ioRow;
|
||||||
ev->StubMethodOnlyError();
|
if ( orow->CanUseRow(mev, /*inMutable*/ morkBool_kFalse, &outErr, &row) )
|
||||||
|
{
|
||||||
|
morkTable* table = (morkTable*) mHandle_Object;
|
||||||
|
actualPos = table->MoveRow(ev, row, inHintFromPos, inToPos);
|
||||||
|
}
|
||||||
outErr = ev->AsErr();
|
outErr = ev->AsErr();
|
||||||
}
|
}
|
||||||
if ( outActualPos )
|
if ( outActualPos )
|
||||||
|
|
|
@ -207,8 +207,11 @@ morkTable::CutTableGcUse(morkEnv* ev)
|
||||||
|
|
||||||
void morkTable::SetTableClean(morkEnv* ev)
|
void morkTable::SetTableClean(morkEnv* ev)
|
||||||
{
|
{
|
||||||
nsIMdbHeap* heap = mTable_Store->mPort_Heap;
|
if ( mTable_ChangeList.HasListMembers() )
|
||||||
mTable_ChangeList.CutAndZapAllListMembers(ev, heap); // forget changes
|
{
|
||||||
|
nsIMdbHeap* heap = mTable_Store->mPort_Heap;
|
||||||
|
mTable_ChangeList.CutAndZapAllListMembers(ev, heap); // forget changes
|
||||||
|
}
|
||||||
mTable_ChangesCount = 0;
|
mTable_ChangesCount = 0;
|
||||||
|
|
||||||
mTable_Flags = 0;
|
mTable_Flags = 0;
|
||||||
|
@ -242,6 +245,31 @@ void morkTable::NoteTableMoveRow(morkEnv* ev, morkRow* ioRow, mork_pos inPos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void morkTable::note_row_move(morkEnv* ev, morkRow* ioRow, mork_pos inNewPos)
|
||||||
|
{
|
||||||
|
if ( this->IsTableRewrite() || this->HasChangeOverflow() )
|
||||||
|
this->NoteTableSetAll(ev);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nsIMdbHeap* heap = mTable_Store->mPort_Heap;
|
||||||
|
morkTableChange* tableChange = new(*heap, ev)
|
||||||
|
morkTableChange(ev, ioRow, inNewPos);
|
||||||
|
if ( tableChange )
|
||||||
|
{
|
||||||
|
if ( ev->Good() )
|
||||||
|
{
|
||||||
|
mTable_ChangeList.PushTail(tableChange);
|
||||||
|
++mTable_ChangesCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tableChange->ZapOldNext(ev, heap);
|
||||||
|
this->NoteTableSetAll(ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void morkTable::note_row_change(morkEnv* ev, mork_change inChange,
|
void morkTable::note_row_change(morkEnv* ev, mork_change inChange,
|
||||||
morkRow* ioRow)
|
morkRow* ioRow)
|
||||||
{
|
{
|
||||||
|
@ -270,8 +298,11 @@ void morkTable::note_row_change(morkEnv* ev, mork_change inChange,
|
||||||
|
|
||||||
void morkTable::NoteTableSetAll(morkEnv* ev)
|
void morkTable::NoteTableSetAll(morkEnv* ev)
|
||||||
{
|
{
|
||||||
nsIMdbHeap* heap = mTable_Store->mPort_Heap;
|
if ( mTable_ChangeList.HasListMembers() )
|
||||||
mTable_ChangeList.CutAndZapAllListMembers(ev, heap); // forget changes
|
{
|
||||||
|
nsIMdbHeap* heap = mTable_Store->mPort_Heap;
|
||||||
|
mTable_ChangeList.CutAndZapAllListMembers(ev, heap); // forget changes
|
||||||
|
}
|
||||||
mTable_ChangesCount = 0;
|
mTable_ChangesCount = 0;
|
||||||
this->SetTableRewrite();
|
this->SetTableRewrite();
|
||||||
}
|
}
|
||||||
|
@ -470,6 +501,118 @@ morkRow* morkTable::find_member_row(morkEnv* ev, morkRow* ioRow)
|
||||||
return (morkRow*) 0;
|
return (morkRow*) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mork_pos
|
||||||
|
morkTable::MoveRow(morkEnv* ev, morkRow* ioRow, // change row position
|
||||||
|
mork_pos inHintFromPos, // suggested hint regarding start position
|
||||||
|
mork_pos inToPos) // desired new position for row ioRow
|
||||||
|
// MoveRow() returns the actual position of ioRow afterwards; this
|
||||||
|
// position is -1 if and only if ioRow was not found as a member.
|
||||||
|
{
|
||||||
|
mork_pos outPos = -1; // means ioRow was not a table member
|
||||||
|
mork_bool canDirty = ( this->IsTableClean() )?
|
||||||
|
this->MaybeDirtySpaceStoreAndTable() : morkBool_kTrue;
|
||||||
|
|
||||||
|
morkRow** rows = (morkRow**) mTable_RowArray.mArray_Slots;
|
||||||
|
mork_count count = mTable_RowArray.mArray_Fill;
|
||||||
|
if ( count && rows && ev->Good() ) // any members at all? no errors?
|
||||||
|
{
|
||||||
|
mork_pos lastPos = count - 1; // index of last row slot
|
||||||
|
|
||||||
|
if ( inToPos > lastPos ) // beyond last used array slot?
|
||||||
|
inToPos = lastPos; // put row into last available slot
|
||||||
|
else if ( inToPos < 0 ) // before first usable slot?
|
||||||
|
inToPos = 0; // put row in very first slow
|
||||||
|
|
||||||
|
if ( inHintFromPos > lastPos ) // beyond last used array slot?
|
||||||
|
inHintFromPos = lastPos; // seek row in last available slot
|
||||||
|
else if ( inHintFromPos < 0 ) // before first usable slot?
|
||||||
|
inHintFromPos = 0; // seek row in very first slow
|
||||||
|
|
||||||
|
morkRow** fromSlot = 0; // becomes nonzero of ioRow is ever found
|
||||||
|
morkRow** rowsEnd = rows + count; // one past last used array slot
|
||||||
|
|
||||||
|
if ( inHintFromPos <= 0 ) // start of table? just scan for row?
|
||||||
|
{
|
||||||
|
morkRow** cursor = rows - 1; // before first array slot
|
||||||
|
while ( ++cursor < rowsEnd )
|
||||||
|
{
|
||||||
|
if ( *cursor == ioRow )
|
||||||
|
{
|
||||||
|
fromSlot = cursor;
|
||||||
|
break; // end while loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // search near the start position and work outwards
|
||||||
|
{
|
||||||
|
morkRow** lo = rows + inHintFromPos; // lowest search point
|
||||||
|
morkRow** hi = lo; // highest search point starts at lowest point
|
||||||
|
|
||||||
|
// Seek ioRow in spiral widening search below and above inHintFromPos.
|
||||||
|
// This is faster when inHintFromPos is at all accurate, but is slower
|
||||||
|
// than a straightforward scan when inHintFromPos is nearly random.
|
||||||
|
|
||||||
|
while ( lo >= rows || hi < rowsEnd ) // keep searching?
|
||||||
|
{
|
||||||
|
if ( lo >= rows ) // low direction search still feasible?
|
||||||
|
{
|
||||||
|
if ( *lo == ioRow ) // actually found the row?
|
||||||
|
{
|
||||||
|
fromSlot = lo;
|
||||||
|
break; // end while loop
|
||||||
|
}
|
||||||
|
--lo; // advance further lower
|
||||||
|
}
|
||||||
|
if ( hi < rowsEnd ) // high direction search still feasible?
|
||||||
|
{
|
||||||
|
if ( *hi == ioRow ) // actually found the row?
|
||||||
|
{
|
||||||
|
fromSlot = hi;
|
||||||
|
break; // end while loop
|
||||||
|
}
|
||||||
|
++hi; // advance further higher
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( fromSlot ) // ioRow was found as a table member?
|
||||||
|
{
|
||||||
|
outPos = fromSlot - rows; // actual position where row was found
|
||||||
|
if ( outPos != inToPos ) // actually need to move this row?
|
||||||
|
{
|
||||||
|
morkRow** toSlot = rows + inToPos; // slot where row must go
|
||||||
|
|
||||||
|
++mTable_RowArray.mArray_Seed; // we modify the array now:
|
||||||
|
|
||||||
|
if ( fromSlot < toSlot ) // row is moving upwards?
|
||||||
|
{
|
||||||
|
morkRow** up = fromSlot; // leading pointer going upward
|
||||||
|
while ( ++up <= toSlot ) // have not gone above destination?
|
||||||
|
{
|
||||||
|
*fromSlot = *up; // shift down one
|
||||||
|
fromSlot = up; // shift trailing pointer up
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // ( fromSlot > toSlot ) // row is moving downwards
|
||||||
|
{
|
||||||
|
morkRow** down = fromSlot; // leading pointer going downward
|
||||||
|
while ( --down >= toSlot ) // have not gone below destination?
|
||||||
|
{
|
||||||
|
*fromSlot = *down; // shift up one
|
||||||
|
fromSlot = down; // shift trailing pointer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*toSlot = ioRow;
|
||||||
|
outPos = inToPos; // okay, we actually moved the row here
|
||||||
|
|
||||||
|
if ( canDirty )
|
||||||
|
this->note_row_move(ev, ioRow, inToPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return outPos;
|
||||||
|
}
|
||||||
|
|
||||||
mork_bool
|
mork_bool
|
||||||
morkTable::AddRow(morkEnv* ev, morkRow* ioRow)
|
morkTable::AddRow(morkEnv* ev, morkRow* ioRow)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,368 +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 _MORKTABLE_
|
|
||||||
#define _MORKTABLE_ 1
|
|
||||||
|
|
||||||
#ifndef _MORK_
|
|
||||||
#include "mork.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _MORKNODE_
|
|
||||||
#include "morkNode.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _MORKDEQUE_
|
|
||||||
#include "morkDeque.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _MORKOBJECT_
|
|
||||||
#include "morkObject.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _MORKARRAY_
|
|
||||||
#include "morkArray.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _MORKROWMAP_
|
|
||||||
#include "morkRowMap.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _MORKNODEMAP_
|
|
||||||
#include "morkNodeMap.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
|
||||||
|
|
||||||
class nsIMdbTable;
|
|
||||||
#define morkDerived_kTable /*i*/ 0x5462 /* ascii 'Tb' */
|
|
||||||
|
|
||||||
/*| kStartRowArraySize: starting physical size of array for mTable_RowArray.
|
|
||||||
**| We want this number very small, so that a table containing exactly one
|
|
||||||
**| row member will not pay too significantly in space overhead. But we want
|
|
||||||
**| a number bigger than one, so there is some space for growth.
|
|
||||||
|*/
|
|
||||||
#define morkTable_kStartRowArraySize 3 /* modest starting size for array */
|
|
||||||
|
|
||||||
/*| kMakeRowMapThreshold: this is the number of rows in a table which causes
|
|
||||||
**| a hash table (mTable_RowMap) to be lazily created for faster member row
|
|
||||||
**| identification, during such operations as cuts and adds. This number must
|
|
||||||
**| be small enough that linear searches are not bad for member counts less
|
|
||||||
**| than this; but this number must also be large enough that creating a hash
|
|
||||||
**| table does not increase the per-row space overhead by a big percentage.
|
|
||||||
**| For speed, numbers on the order of ten to twenty are all fine; for space,
|
|
||||||
**| I believe a number as small as ten will have too much space overhead.
|
|
||||||
|*/
|
|
||||||
#define morkTable_kMakeRowMapThreshold 17 /* when to build mTable_RowMap */
|
|
||||||
|
|
||||||
#define morkTable_kStartRowMapSlotCount 13
|
|
||||||
#define morkTable_kMaxTableGcUses 0x0FF /* max for 8-bit unsigned int */
|
|
||||||
|
|
||||||
#define morkTable_kUniqueBit ((mork_u1) (1 << 0))
|
|
||||||
#define morkTable_kVerboseBit ((mork_u1) (1 << 1))
|
|
||||||
#define morkTable_kNotedBit ((mork_u1) (1 << 2)) /* space has change notes */
|
|
||||||
#define morkTable_kRewriteBit ((mork_u1) (1 << 3)) /* must rewrite all rows */
|
|
||||||
#define morkTable_kNewMetaBit ((mork_u1) (1 << 4)) /* new table meta row */
|
|
||||||
|
|
||||||
class morkTable : public morkObject, public morkLink {
|
|
||||||
|
|
||||||
// NOTE the morkLink base is for morkRowSpace::mRowSpace_TablesByPriority
|
|
||||||
|
|
||||||
// public: // slots inherited from morkObject (meant to inform only)
|
|
||||||
// nsIMdbHeap* mNode_Heap;
|
|
||||||
|
|
||||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
|
||||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
|
||||||
|
|
||||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
|
||||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
|
||||||
// mork_able mNode_Mutable; // can this node be modified?
|
|
||||||
// mork_load mNode_Load; // is this node clean or dirty?
|
|
||||||
|
|
||||||
// mork_uses mNode_Uses; // refcount for strong refs
|
|
||||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
|
||||||
|
|
||||||
// morkHandle* mObject_Handle; // weak ref to handle for this object
|
|
||||||
|
|
||||||
public: // state is public because the entire Mork system is private
|
|
||||||
|
|
||||||
morkStore* mTable_Store; // weak ref to port
|
|
||||||
|
|
||||||
// mTable_RowSpace->mSpace_Scope is row scope
|
|
||||||
morkRowSpace* mTable_RowSpace; // weak ref to containing space
|
|
||||||
|
|
||||||
morkRow* mTable_MetaRow; // table's actual meta row
|
|
||||||
mdbOid mTable_MetaRowOid; // oid for meta row
|
|
||||||
|
|
||||||
morkRowMap* mTable_RowMap; // (strong ref) hash table of all members
|
|
||||||
morkArray mTable_RowArray; // array of morkRow pointers
|
|
||||||
|
|
||||||
morkList mTable_ChangeList; // list of table changes
|
|
||||||
mork_u2 mTable_ChangesCount; // length of changes list
|
|
||||||
mork_u2 mTable_ChangesMax; // max list length before rewrite
|
|
||||||
|
|
||||||
mork_tid mTable_Id;
|
|
||||||
mork_kind mTable_Kind;
|
|
||||||
|
|
||||||
mork_u1 mTable_Flags; // bit flags
|
|
||||||
mork_priority mTable_Priority; // 0..9, any other value equals 9
|
|
||||||
mork_u1 mTable_GcUses; // persistent references from cells
|
|
||||||
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; }
|
|
||||||
void SetTableRewrite() { mTable_Flags |= morkTable_kRewriteBit; }
|
|
||||||
void SetTableNewMeta() { mTable_Flags |= morkTable_kNewMetaBit; }
|
|
||||||
|
|
||||||
void ClearTableUnique() { mTable_Flags &= (mork_u1) ~morkTable_kUniqueBit; }
|
|
||||||
void ClearTableVerbose() { mTable_Flags &= (mork_u1) ~morkTable_kVerboseBit; }
|
|
||||||
void ClearTableNoted() { mTable_Flags &= (mork_u1) ~morkTable_kNotedBit; }
|
|
||||||
void ClearTableRewrite() { mTable_Flags &= (mork_u1) ~morkTable_kRewriteBit; }
|
|
||||||
void ClearTableNewMeta() { mTable_Flags &= (mork_u1) ~morkTable_kNewMetaBit; }
|
|
||||||
|
|
||||||
mork_bool IsTableUnique() const
|
|
||||||
{ return ( mTable_Flags & morkTable_kUniqueBit ) != 0; }
|
|
||||||
|
|
||||||
mork_bool IsTableVerbose() const
|
|
||||||
{ return ( mTable_Flags & morkTable_kVerboseBit ) != 0; }
|
|
||||||
|
|
||||||
mork_bool IsTableNoted() const
|
|
||||||
{ return ( mTable_Flags & morkTable_kNotedBit ) != 0; }
|
|
||||||
|
|
||||||
mork_bool IsTableRewrite() const
|
|
||||||
{ return ( mTable_Flags & morkTable_kRewriteBit ) != 0; }
|
|
||||||
|
|
||||||
mork_bool IsTableNewMeta() const
|
|
||||||
{ return ( mTable_Flags & morkTable_kNewMetaBit ) != 0; }
|
|
||||||
|
|
||||||
public: // table dirty handling more complex than morkNode::SetNodeDirty() etc.
|
|
||||||
|
|
||||||
void SetTableDirty() { this->SetNodeDirty(); }
|
|
||||||
void SetTableClean(morkEnv* ev);
|
|
||||||
|
|
||||||
mork_bool IsTableClean() const { return this->IsNodeClean(); }
|
|
||||||
mork_bool IsTableDirty() const { return this->IsNodeDirty(); }
|
|
||||||
|
|
||||||
public: // morkNode memory management operators
|
|
||||||
void* operator new(size_t inSize, nsIMdbHeap& ioHeap, morkEnv* ev)
|
|
||||||
{ return morkNode::MakeNew(inSize, ioHeap, ev); }
|
|
||||||
|
|
||||||
void operator delete(void* ioAddress)
|
|
||||||
{ morkNode::OnDeleteAssert(ioAddress); }
|
|
||||||
// do NOT call delete on morkNode instances. Call ZapOld() instead.
|
|
||||||
|
|
||||||
// { ===== begin morkNode interface =====
|
|
||||||
public: // morkNode virtual methods
|
|
||||||
virtual void CloseMorkNode(morkEnv* ev); // CloseTable() if open
|
|
||||||
virtual ~morkTable(); // assert that close executed earlier
|
|
||||||
|
|
||||||
public: // morkTable construction & destruction
|
|
||||||
morkTable(morkEnv* ev, const morkUsage& inUsage,
|
|
||||||
nsIMdbHeap* ioNodeHeap, morkStore* ioStore,
|
|
||||||
nsIMdbHeap* ioSlotHeap, morkRowSpace* ioRowSpace,
|
|
||||||
const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
|
|
||||||
mork_tid inTableId,
|
|
||||||
mork_kind inKind, mork_bool inMustBeUnique);
|
|
||||||
void CloseTable(morkEnv* ev); // called by CloseMorkNode();
|
|
||||||
|
|
||||||
private: // copying is not allowed
|
|
||||||
morkTable(const morkTable& other);
|
|
||||||
morkTable& operator=(const morkTable& other);
|
|
||||||
|
|
||||||
public: // dynamic type identification
|
|
||||||
mork_bool IsTable() const
|
|
||||||
{ return IsNode() && mNode_Derived == morkDerived_kTable; }
|
|
||||||
// } ===== end morkNode methods =====
|
|
||||||
|
|
||||||
public: // errors
|
|
||||||
static void NonTableTypeError(morkEnv* ev);
|
|
||||||
static void NonTableTypeWarning(morkEnv* ev);
|
|
||||||
static void NilRowSpaceError(morkEnv* ev);
|
|
||||||
|
|
||||||
public: // warnings
|
|
||||||
static void TableGcUsesUnderflowWarning(morkEnv* ev);
|
|
||||||
|
|
||||||
public: // noting table changes
|
|
||||||
|
|
||||||
mork_bool HasChangeOverflow() const
|
|
||||||
{ return mTable_ChangesCount >= mTable_ChangesMax; }
|
|
||||||
|
|
||||||
void NoteTableSetAll(morkEnv* ev);
|
|
||||||
void NoteTableMoveRow(morkEnv* ev, morkRow* ioRow, mork_pos inPos);
|
|
||||||
|
|
||||||
void note_row_change(morkEnv* ev, mork_change inChange, morkRow* ioRow);
|
|
||||||
|
|
||||||
void NoteTableAddRow(morkEnv* ev, morkRow* ioRow)
|
|
||||||
{ this->note_row_change(ev, morkChange_kAdd, ioRow); }
|
|
||||||
|
|
||||||
void NoteTableCutRow(morkEnv* ev, morkRow* ioRow)
|
|
||||||
{ this->note_row_change(ev, morkChange_kCut, ioRow); }
|
|
||||||
|
|
||||||
protected: // internal row map methods
|
|
||||||
|
|
||||||
morkRow* find_member_row(morkEnv* ev, morkRow* ioRow);
|
|
||||||
void build_row_map(morkEnv* ev);
|
|
||||||
|
|
||||||
public: // other table methods
|
|
||||||
|
|
||||||
mork_bool MaybeDirtySpaceStoreAndTable();
|
|
||||||
|
|
||||||
morkRow* GetMetaRow(morkEnv* ev, const mdbOid* inOptionalMetaRowOid);
|
|
||||||
|
|
||||||
mork_u2 AddTableGcUse(morkEnv* ev);
|
|
||||||
mork_u2 CutTableGcUse(morkEnv* ev);
|
|
||||||
|
|
||||||
// void DirtyAllTableContent(morkEnv* ev);
|
|
||||||
|
|
||||||
mork_seed TableSeed() const { return mTable_RowArray.mArray_Seed; }
|
|
||||||
|
|
||||||
morkRow* SafeRowAt(morkEnv* ev, mork_pos inPos)
|
|
||||||
{ return (morkRow*) mTable_RowArray.SafeAt(ev, inPos); }
|
|
||||||
|
|
||||||
nsIMdbTable* AcquireTableHandle(morkEnv* ev); // mObject_Handle
|
|
||||||
|
|
||||||
mork_count GetRowCount() const { return mTable_RowArray.mArray_Fill; }
|
|
||||||
|
|
||||||
void GetTableOid(morkEnv* ev, mdbOid* outOid);
|
|
||||||
mork_pos ArrayHasOid(morkEnv* ev, const mdbOid* inOid);
|
|
||||||
mork_bool MapHasOid(morkEnv* ev, const mdbOid* inOid);
|
|
||||||
mork_bool AddRow(morkEnv* ev, morkRow* ioRow); // returns ev->Good()
|
|
||||||
mork_bool CutRow(morkEnv* ev, morkRow* ioRow); // returns ev->Good()
|
|
||||||
mork_bool CutAllRows(morkEnv* ev); // returns ev->Good()
|
|
||||||
|
|
||||||
morkTableRowCursor* NewTableRowCursor(morkEnv* ev, mork_pos inRowPos);
|
|
||||||
|
|
||||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
|
||||||
static void SlotWeakTable(morkTable* me,
|
|
||||||
morkEnv* ev, morkTable** ioSlot)
|
|
||||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
|
||||||
|
|
||||||
static void SlotStrongTable(morkTable* me,
|
|
||||||
morkEnv* ev, morkTable** ioSlot)
|
|
||||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
|
||||||
};
|
|
||||||
|
|
||||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
|
||||||
|
|
||||||
// use negative values for kCut and kAdd, to keep non-neg move pos distinct:
|
|
||||||
#define morkTableChange_kCut ((mork_pos) -1) /* shows row was cut */
|
|
||||||
#define morkTableChange_kAdd ((mork_pos) -2) /* shows row was added */
|
|
||||||
#define morkTableChange_kNone ((mork_pos) -3) /* unknown change */
|
|
||||||
|
|
||||||
class morkTableChange : public morkNext {
|
|
||||||
public: // state is public because the entire Mork system is private
|
|
||||||
|
|
||||||
morkRow* mTableChange_Row; // the row in the change
|
|
||||||
|
|
||||||
mork_pos mTableChange_Pos; // kAdd, kCut, or non-neg for row move
|
|
||||||
|
|
||||||
public:
|
|
||||||
morkTableChange(morkEnv* ev, mork_change inChange, morkRow* ioRow);
|
|
||||||
// use this constructor for inChange == morkChange_kAdd or morkChange_kCut
|
|
||||||
|
|
||||||
morkTableChange(morkEnv* ev, morkRow* ioRow, mork_pos inPos);
|
|
||||||
// use this constructor when the row is moved
|
|
||||||
|
|
||||||
public:
|
|
||||||
void UnknownChangeError(morkEnv* ev) const; // morkChange_kAdd or morkChange_kCut
|
|
||||||
void NegativeMovePosError(morkEnv* ev) const; // move must be non-neg position
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
mork_bool IsAddRowTableChange() const
|
|
||||||
{ return ( mTableChange_Pos == morkTableChange_kAdd ); }
|
|
||||||
|
|
||||||
mork_bool IsCutRowTableChange() const
|
|
||||||
{ return ( mTableChange_Pos == morkTableChange_kCut ); }
|
|
||||||
|
|
||||||
mork_bool IsMoveRowTableChange() const
|
|
||||||
{ return ( mTableChange_Pos >= 0 ); }
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
mork_pos GetMovePos() const { return mTableChange_Pos; }
|
|
||||||
// GetMovePos() assumes that IsMoveRowTableChange() is true.
|
|
||||||
};
|
|
||||||
|
|
||||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
|
||||||
|
|
||||||
#define morkDerived_kTableMap /*i*/ 0x744D /* ascii 'tM' */
|
|
||||||
|
|
||||||
/*| morkTableMap: maps mork_token -> morkTable
|
|
||||||
|*/
|
|
||||||
class morkTableMap : public morkNodeMap { // for mapping tokens to tables
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
virtual ~morkTableMap();
|
|
||||||
morkTableMap(morkEnv* ev, const morkUsage& inUsage,
|
|
||||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap);
|
|
||||||
|
|
||||||
public: // other map methods
|
|
||||||
|
|
||||||
mork_bool AddTable(morkEnv* ev, morkTable* ioTable)
|
|
||||||
{ return this->AddNode(ev, ioTable->mTable_Id, ioTable); }
|
|
||||||
// the AddTable() boolean return equals ev->Good().
|
|
||||||
|
|
||||||
mork_bool CutTable(morkEnv* ev, mork_tid inTid)
|
|
||||||
{ return this->CutNode(ev, inTid); }
|
|
||||||
// The CutTable() boolean return indicates whether removal happened.
|
|
||||||
|
|
||||||
morkTable* GetTable(morkEnv* ev, mork_tid inTid)
|
|
||||||
{ return (morkTable*) this->GetNode(ev, inTid); }
|
|
||||||
// Note the returned table does NOT have an increase in refcount for this.
|
|
||||||
|
|
||||||
mork_num CutAllTables(morkEnv* ev)
|
|
||||||
{ return this->CutAllNodes(ev); }
|
|
||||||
// CutAllTables() releases all the referenced table values.
|
|
||||||
};
|
|
||||||
|
|
||||||
class morkTableMapIter: public morkMapIter{ // typesafe wrapper class
|
|
||||||
|
|
||||||
public:
|
|
||||||
morkTableMapIter(morkEnv* ev, morkTableMap* ioMap)
|
|
||||||
: morkMapIter(ev, ioMap) { }
|
|
||||||
|
|
||||||
morkTableMapIter( ) : morkMapIter() { }
|
|
||||||
void InitTableMapIter(morkEnv* ev, morkTableMap* ioMap)
|
|
||||||
{ this->InitMapIter(ev, ioMap); }
|
|
||||||
|
|
||||||
mork_change*
|
|
||||||
FirstTable(morkEnv* ev, mork_tid* outTid, morkTable** outTable)
|
|
||||||
{ return this->First(ev, outTid, outTable); }
|
|
||||||
|
|
||||||
mork_change*
|
|
||||||
NextTable(morkEnv* ev, mork_tid* outTid, morkTable** outTable)
|
|
||||||
{ return this->Next(ev, outTid, outTable); }
|
|
||||||
|
|
||||||
mork_change*
|
|
||||||
HereTable(morkEnv* ev, mork_tid* outTid, morkTable** outTable)
|
|
||||||
{ return this->Here(ev, outTid, outTable); }
|
|
||||||
|
|
||||||
// cutting while iterating hash map might dirty the parent table:
|
|
||||||
mork_change*
|
|
||||||
CutHereTable(morkEnv* ev, mork_tid* outTid, morkTable** outTable)
|
|
||||||
{ return this->CutHere(ev, outTid, outTable); }
|
|
||||||
};
|
|
||||||
|
|
||||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
|
||||||
|
|
||||||
#endif /* _MORKTABLE_ */
|
|
|
@ -1122,18 +1122,25 @@ orkinTable::MoveOid( // change position of row in unsorted table
|
||||||
nsIMdbEnv* mev, // context
|
nsIMdbEnv* mev, // context
|
||||||
const mdbOid* inOid, // row oid to find in table
|
const mdbOid* inOid, // row oid to find in table
|
||||||
mdb_pos inHintFromPos, // suggested hint regarding start position
|
mdb_pos inHintFromPos, // suggested hint regarding start position
|
||||||
mdb_pos inToPos, // desired new position for row inRowId
|
mdb_pos inToPos, // desired new position for row inOid
|
||||||
mdb_pos* outActualPos) // actual new position of row in table
|
mdb_pos* outActualPos) // actual new position of row in table
|
||||||
{
|
{
|
||||||
MORK_USED_3(inHintFromPos,inToPos,inOid);
|
|
||||||
mdb_err outErr = 0;
|
mdb_err outErr = 0;
|
||||||
mdb_pos actualPos = 0;
|
mdb_pos actualPos = -1; // meaning it was never found in table
|
||||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||||
if ( ev )
|
if ( ev )
|
||||||
{
|
{
|
||||||
// remember table->MaybeDirtySpaceStoreAndTable();
|
morkTable* table = (morkTable*) mHandle_Object;
|
||||||
|
morkStore* store = table->mTable_Store;
|
||||||
|
if ( inOid && store )
|
||||||
|
{
|
||||||
|
morkRow* row = store->GetRow(ev, inOid);
|
||||||
|
if ( row )
|
||||||
|
actualPos = table->MoveRow(ev, row, inHintFromPos, inToPos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ev->NilPointerError();
|
||||||
|
|
||||||
ev->StubMethodOnlyError();
|
|
||||||
outErr = ev->AsErr();
|
outErr = ev->AsErr();
|
||||||
}
|
}
|
||||||
if ( outActualPos )
|
if ( outActualPos )
|
||||||
|
@ -1146,18 +1153,21 @@ orkinTable::MoveRow( // change position of row in unsorted table
|
||||||
nsIMdbEnv* mev, // context
|
nsIMdbEnv* mev, // context
|
||||||
nsIMdbRow* ioRow, // row oid to find in table
|
nsIMdbRow* ioRow, // row oid to find in table
|
||||||
mdb_pos inHintFromPos, // suggested hint regarding start position
|
mdb_pos inHintFromPos, // suggested hint regarding start position
|
||||||
mdb_pos inToPos, // desired new position for row inRowId
|
mdb_pos inToPos, // desired new position for row ioRow
|
||||||
mdb_pos* outActualPos) // actual new position of row in table
|
mdb_pos* outActualPos) // actual new position of row in table
|
||||||
{
|
{
|
||||||
MORK_USED_3(inHintFromPos,inToPos,ioRow);
|
mdb_pos actualPos = -1; // meaning it was never found in table
|
||||||
mdb_pos actualPos = 0;
|
|
||||||
mdb_err outErr = 0;
|
mdb_err outErr = 0;
|
||||||
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
morkEnv* ev = this->CanUseTable(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||||
if ( ev )
|
if ( ev )
|
||||||
{
|
{
|
||||||
// remember table->MaybeDirtySpaceStoreAndTable();
|
morkRow* row = 0;
|
||||||
|
orkinRow* orow = (orkinRow*) ioRow;
|
||||||
ev->StubMethodOnlyError();
|
if ( orow->CanUseRow(mev, /*inMutable*/ morkBool_kFalse, &outErr, &row) )
|
||||||
|
{
|
||||||
|
morkTable* table = (morkTable*) mHandle_Object;
|
||||||
|
actualPos = table->MoveRow(ev, row, inHintFromPos, inToPos);
|
||||||
|
}
|
||||||
outErr = ev->AsErr();
|
outErr = ev->AsErr();
|
||||||
}
|
}
|
||||||
if ( outActualPos )
|
if ( outActualPos )
|
||||||
|
|
Загрузка…
Ссылка в новой задаче