Try to fix some issues with journal replay and compaction.

This commit is contained in:
Jonathan Moore Liles 2008-05-05 18:24:21 -05:00
parent 03cd2a1c45
commit 89d64f66e4
3 changed files with 61 additions and 55 deletions

View File

@ -31,7 +31,8 @@ int Loggable::_log_id = 0;
int Loggable::_level = 0;
int Loggable::_undo_index = 1;
vector <Loggable *> Loggable::_loggables;
size_t Loggable::_loggables_size = 0;
Loggable ** Loggable::_loggables;
map <string, create_func*> Loggable::_class_map;
queue <char *> Loggable::_transaction;
@ -96,42 +97,31 @@ Loggable::close ( void )
return true;
}
/* /\** return a new copy of string /s/ with all newlines escaped *\/ */
/* static char * */
/* escape ( const char *s ) */
/* { */
/* size_t l = strlen( s ) + 20; */
/* char *result = (char*)malloc( l ); */
/** must be called after construction in create() methods */
void
Loggable::update_id ( int id )
{
/* make sure we're the last one */
assert( _id == _log_id );
assert( _loggables[ _id - 1 ] == this );
/* char *r = result; */
_loggables[ _id - 1 ] = NULL;
/* int ri = 0; */
_log_id = max( _log_id, id );
/* int i = strlen( s ); */
/* return this id number to the system */
// --_log_id;
/* again: */
_id = id;
/* for ( ; i-- && ri < l; ++s, ri++ ) */
/* { */
/* if ( '\n' == *s ) */
/* { */
/* r[ ri++ ] = '\\'; */
/* r[ ri ] = 'n'; */
/* } */
/* else */
/* r[ ri ] = *s; */
/* } */
/* make sure it'll fit */
ensure_size( _id );
/* if ( ri == l ) */
/* { */
/* result = (char*) realloc( result, l += 20 ); */
/* goto again; */
/* } */
/* return result; */
/* } */
ASSERT( ! _loggables[ _id - 1 ], "Attempt to create object with an ID (0x%X) that already exists. The existing object is of type \"%s\", the new one is \"%s\". Corrupt journal?", _id, _loggables[ _id - 1 ]->class_name(), class_name() );
_loggables[ _id - 1 ] = this;
}
/** return a pointer to a static copy of /s/ with all special characters escaped */
const char *
@ -139,7 +129,7 @@ Loggable::escape ( const char *s )
{
static char r[512];
for ( int i = 0; i < sizeof( r ); ++i, ++s )
for ( size_t i = 0; i < sizeof( r ); ++i, ++s )
{
if ( '\n' == *s )
{
@ -467,6 +457,23 @@ Loggable::snapshot( FILE *fp )
return false;
}
/* first, make all ids consecutive */
int id = 0;
for ( int i = 0; i < _log_id; ++i )
if ( _loggables[ i ] )
{
++id;
if ( _loggables[ id - 1 ] )
continue;
_loggables[ id - 1 ] = _loggables[ i ];
_loggables[ i ] = NULL;
_loggables[ id - 1 ]->_id = id;
}
_log_id = id;
block_start();
for ( int i = 0; i < _log_id; ++i )

View File

@ -88,7 +88,8 @@ class Loggable
static int _level;
static int _undo_index;
static vector <Loggable *> _loggables;
static size_t _loggables_size;
static Loggable ** _loggables;
static map <string, create_func*> _class_map;
@ -103,6 +104,21 @@ private:
int _nest;
static void ensure_size ( size_t n )
{
if ( n > _loggables_size )
{
size_t p = 0;
while ( ( (unsigned)1 << p ) < n ) ++p;
size_t os = _loggables_size;
_loggables_size = 1 << p ;
_loggables = (Loggable**) realloc( _loggables, sizeof( Loggable ** ) * _loggables_size );
memset( _loggables + os, 0, _loggables_size - os );
}
}
void log_print( char **o, char **n ) const;
static void log ( const char *fmt, ... );
@ -166,36 +182,16 @@ public:
_old_state = NULL;
_nest = 0;
_loggables.push_back( this );
ensure_size( _id );
_loggables[ _id - 1 ] = this;
}
else
_id = 0;
}
/** must be called after construction in create() methods */
void
update_id ( int id )
{
assert( _id == _log_id );
assert( _loggables[ _id - 1 ] == this );
_loggables[ _id - 1 ] = NULL;
// --_log_id;
_id = id;
/* make sure it'll fit */
_loggables.reserve( _id );
// assert( ! _loggables[ _id - 1 ] );
ASSERT( ! _loggables[ _id - 1 ], "Attempt to create object with an ID (0x%X) that already exists. The existing object is of type \"%s\", the new one is \"%s\". Corrupt journal?", _id, _loggables[ _id -1 ]->class_name(), class_name() );
_loggables[ _id - 1 ] = this;
}
void update_id ( int id );
virtual ~Loggable ( )
{

View File

@ -173,8 +173,11 @@ public:
track( t );
}
}
}
}
}