Fixed the bug where the sort order of transactions with equal timestamps
 was not stable, i.e. due to the lack of a total order, different merges
 produced different sortings and hence messed up transactions which
 have already been merged.
This commit is contained in:
Johannes Schlatow 2012-09-10 22:53:44 +02:00
parent 89a7f2a459
commit 68c1ca3f69
4 changed files with 104 additions and 24 deletions

View file

@ -1024,8 +1024,8 @@ void TDB2::merge (const std::string& mergeFile)
mods.splice (mods.begin (), rmods);
DEBUG_STR ("sorting taskmod list");
mods.sort ();
mods_history.sort ();
mods.sort (compareTaskmod);
mods_history.sort (compareTaskmod);
}
else if (rit == r.end ())
{
@ -1232,7 +1232,7 @@ void TDB2::merge (const std::string& mergeFile)
// at this point undo contains the lines up to the branch-off point
// now we merge mods (new modifications from mergefile)
// with lmods (part of old undo.data)
lmods.sort();
lmods.sort(compareTaskmod);
mods.merge (lmods);
mods.merge (mods_history);

View file

@ -33,22 +33,38 @@
#include <assert.h>
#include <Taskmod.h>
unsigned long Taskmod::curSequenceNumber = 0;
bool compareTaskmod (Taskmod first, Taskmod second)
{
if (first._timestamp == second._timestamp)
{
return first._sequenceNumber < second._sequenceNumber;
}
else
{
return first._timestamp < second._timestamp;
}
}
////////////////////////////////////////////////////////////////////////////////
Taskmod::Taskmod ()
{
_timestamp = 0;
_bAfterSet = false;
_bBeforeSet = false;
_sequenceNumber = curSequenceNumber++;
}
////////////////////////////////////////////////////////////////////////////////
Taskmod::Taskmod (const Taskmod& other)
{
this->_before = other._before;
this->_after = other._after;
this->_timestamp = other._timestamp;
this->_bAfterSet = other._bAfterSet;
this->_bBeforeSet = other._bBeforeSet;
this->_before = other._before;
this->_after = other._after;
this->_timestamp = other._timestamp;
this->_bAfterSet = other._bAfterSet;
this->_bBeforeSet = other._bBeforeSet;
this->_sequenceNumber = other._sequenceNumber;
}
////////////////////////////////////////////////////////////////////////////////
@ -87,11 +103,12 @@ Taskmod& Taskmod::operator= (const Taskmod& other)
{
if (this != &other)
{
this->_before = other._before;
this->_after = other._after;
this->_timestamp = other._timestamp;
this->_bAfterSet = other._bAfterSet;
this->_bBeforeSet = other._bBeforeSet;
this->_before = other._before;
this->_after = other._after;
this->_timestamp = other._timestamp;
this->_bAfterSet = other._bAfterSet;
this->_bBeforeSet = other._bBeforeSet;
this->_sequenceNumber = other._sequenceNumber;
}
return *this;
@ -100,9 +117,10 @@ Taskmod& Taskmod::operator= (const Taskmod& other)
////////////////////////////////////////////////////////////////////////////////
void Taskmod::reset (long timestamp)
{
this->_bAfterSet = false;
this->_bBeforeSet = false;
this->_timestamp = timestamp;
this->_bAfterSet = false;
this->_bBeforeSet = false;
this->_timestamp = timestamp;
this->_sequenceNumber = curSequenceNumber++;
}
////////////////////////////////////////////////////////////////////////////////
@ -177,6 +195,12 @@ void Taskmod::setTimestamp (long timestamp)
this->_timestamp = timestamp;
}
////////////////////////////////////////////////////////////////////////////////
void Taskmod::incSequenceNumber ()
{
this->_sequenceNumber++;
}
////////////////////////////////////////////////////////////////////////////////
Task& Taskmod::getAfter ()
{
@ -195,6 +219,12 @@ long Taskmod::getTimestamp () const
return _timestamp;
}
////////////////////////////////////////////////////////////////////////////////
unsigned long Taskmod::getSequenceNumber () const
{
return _sequenceNumber;
}
////////////////////////////////////////////////////////////////////////////////
std::string Taskmod::getTimeStr () const
{

View file

@ -33,6 +33,8 @@
#include <Task.h>
class Taskmod {
friend bool compareTaskmod (Taskmod first, Taskmod second);
public:
Taskmod ();
Taskmod (const Taskmod& other);
@ -59,11 +61,13 @@ public:
void setAfter (const Task& after);
void setBefore (const Task& before);
void setTimestamp (long timestamp);
void incSequenceNumber ();
// getter
Task& getAfter ();
Task& getBefore ();
long getTimestamp () const;
unsigned long getSequenceNumber () const;
std::string getTimeStr () const;
protected:
@ -72,7 +76,12 @@ protected:
long _timestamp;
bool _bAfterSet;
bool _bBeforeSet;
unsigned long _sequenceNumber;
static unsigned long curSequenceNumber;
};
bool compareTaskmod (Taskmod first, Taskmod second);
#endif