From 89d64f66e4f8e90d122e5b75fd815f3065bf0dbe Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Mon, 5 May 2008 18:24:21 -0500 Subject: [PATCH] Try to fix some issues with journal replay and compaction. --- Timeline/Loggable.C | 67 +++++++++++++++++++++++++-------------------- Timeline/Loggable.H | 46 ++++++++++++++----------------- Timeline/Track.H | 3 ++ 3 files changed, 61 insertions(+), 55 deletions(-) diff --git a/Timeline/Loggable.C b/Timeline/Loggable.C index f847445..2ed51cf 100644 --- a/Timeline/Loggable.C +++ b/Timeline/Loggable.C @@ -31,7 +31,8 @@ int Loggable::_log_id = 0; int Loggable::_level = 0; int Loggable::_undo_index = 1; -vector Loggable::_loggables; +size_t Loggable::_loggables_size = 0; +Loggable ** Loggable::_loggables; map Loggable::_class_map; queue 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 ) diff --git a/Timeline/Loggable.H b/Timeline/Loggable.H index a82de5c..80c1f58 100644 --- a/Timeline/Loggable.H +++ b/Timeline/Loggable.H @@ -88,7 +88,8 @@ class Loggable static int _level; static int _undo_index; - static vector _loggables; + static size_t _loggables_size; + static Loggable ** _loggables; static map _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 ( ) { diff --git a/Timeline/Track.H b/Timeline/Track.H index 86ed8fc..fb04920 100644 --- a/Timeline/Track.H +++ b/Timeline/Track.H @@ -173,8 +173,11 @@ public: track( t ); } + } + } + } }