List:Commits« Previous MessageNext Message »
From:U-ROWVWADEjas Date:September 4 2007 11:11pm
Subject:bk commit into 6.0-falcon tree (jas:1.2591)
View as plain text  
Below is the list of changes that have just been committed into a local
6.0-falcon repository of . When  does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-09-04 17:11:37-04:00, jas@rowvwade. +25 -0
  Give up trying to track sizes of record age groups in favor
  of taking a "record inventory" as part and parcel of a record
  scavenge.
  
  Also changed the terminology from "record age" to "record
  generation" for clarity.

  storage/falcon/CMakeLists.txt@stripped, 2007-09-04 17:11:13-04:00, jas@rowvwade. +2 -0
    Add new class RecordScavenge to encapsuate record scavenging
    code.

  storage/falcon/Database.cpp@stripped, 2007-09-04 17:11:13-04:00, jas@rowvwade. +31 -59
    Give up trying to track sizes of record age groups in favor
    of taking a "record inventory" as part and parcel of a record
    scavenge.

  storage/falcon/Database.h@stripped, 2007-09-04 17:11:13-04:00, jas@rowvwade. +6 -8
    Give up trying to track sizes of record age groups in favor
    of taking a "record inventory" as part and parcel of a record
    scavenge.

  storage/falcon/Makefile.am@stripped, 2007-09-04 17:11:14-04:00, jas@rowvwade. +4 -1
    Add new class RecordScavenge to encapsuate record scavenging
    code.

  storage/falcon/MemMgr.cpp@stripped, 2007-09-04 17:11:14-04:00, jas@rowvwade. +7 -2
    Track space in use as "big blocks" (or all blocks, if big
    block threshold is low).  This is primary used to determine
    scavenge threshold as part of record scavenge process.

  storage/falcon/MemMgr.h@stripped, 2007-09-04 17:11:15-04:00, jas@rowvwade. +1 -0
    Track space in use as "big blocks" (or all blocks, if big
    block threshold is low).  This is primary used to determine
    scavenge threshold as part of record scavenge process.

  storage/falcon/Record.cpp@stripped, 2007-09-04 17:11:15-04:00, jas@rowvwade. +21 -14
    Give up trying to track sizes of record age groups in favor
    of taking a "record inventory" as part and parcel of a record
    scavenge.

  storage/falcon/Record.h@stripped, 2007-09-04 17:11:15-04:00, jas@rowvwade. +5 -14
    Give up trying to track sizes of record age groups in favor
    of taking a "record inventory" as part and parcel of a record
    scavenge.

  storage/falcon/RecordGroup.cpp@stripped, 2007-09-04 17:11:16-04:00, jas@rowvwade. +7 -0
    Give up trying to track sizes of record age groups in favor
    of taking a "record inventory" as part and parcel of a record
    scavenge.

  storage/falcon/RecordGroup.h@stripped, 2007-09-04 17:11:16-04:00, jas@rowvwade. +6 -4
    Give up trying to track sizes of record age groups in favor
    of taking a "record inventory" as part and parcel of a record
    scavenge.

  storage/falcon/RecordLeaf.cpp@stripped, 2007-09-04 17:11:16-04:00, jas@rowvwade. +15 -4
    Give up trying to track sizes of record age groups in favor
    of taking a "record inventory" as part and parcel of a record
    scavenge.

  storage/falcon/RecordLeaf.h@stripped, 2007-09-04 17:11:17-04:00, jas@rowvwade. +1 -0
    Give up trying to track sizes of record age groups in favor
    of taking a "record inventory" as part and parcel of a record
    scavenge.

  storage/falcon/RecordScavenge.cpp@stripped, 2007-09-04 17:11:22-04:00, jas@rowvwade. +89 -0
    New BitKeeper file ``storage/falcon/RecordScavenge.cpp''

  storage/falcon/RecordScavenge.cpp@stripped, 2007-09-04 17:11:22-04:00, jas@rowvwade. +0 -0

  storage/falcon/RecordScavenge.h@stripped, 2007-09-04 17:11:22-04:00, jas@rowvwade. +48 -0
    New BitKeeper file ``storage/falcon/RecordScavenge.h''

  storage/falcon/RecordScavenge.h@stripped, 2007-09-04 17:11:22-04:00, jas@rowvwade. +0 -0

  storage/falcon/RecordSection.h@stripped, 2007-09-04 17:11:18-04:00, jas@rowvwade. +8 -6
    Stylistic edit for clarity.

  storage/falcon/RecordVersion.cpp@stripped, 2007-09-04 17:11:18-04:00, jas@rowvwade. +3 -1
    Switch terminology from "record age" to "record generation".

  storage/falcon/SerialLog.cpp@stripped, 2007-09-04 17:11:18-04:00, jas@rowvwade. +7 -7
    Deactivate a large number of relatively expensive serial
    log validations.

  storage/falcon/SerialLogControl.cpp@stripped, 2007-09-04 17:11:19-04:00, jas@rowvwade. +5 -5
    Deactivate a large number of relatively expensive serial
    log validations.

  storage/falcon/SerialLogWindow.cpp@stripped, 2007-09-04 17:11:19-04:00, jas@rowvwade. +1 -1
    Deactivate a large number of relatively expensive serial
    log validations.

  storage/falcon/Table.cpp@stripped, 2007-09-04 17:11:19-04:00, jas@rowvwade. +15 -4
    Give up trying to track sizes of record age groups in favor
    of taking a "record inventory" as part and parcel of a record
    scavenge.

  storage/falcon/Table.h@stripped, 2007-09-04 17:11:20-04:00, jas@rowvwade. +2 -2
    Give up trying to track sizes of record age groups in favor
    of taking a "record inventory" as part and parcel of a record
    scavenge.

  storage/falcon/Transaction.cpp@stripped, 2007-09-04 17:11:20-04:00, jas@rowvwade. +8 -0
    Put in debugging mechanism to print the transaction "wait for"
    tree from the debugger.

  storage/falcon/Transaction.h@stripped, 2007-09-04 17:11:21-04:00, jas@rowvwade. +6 -6
    Put in debugging mechanism to print the transaction "wait for"
    tree from the debugger.

  storage/falcon/TransactionManager.cpp@stripped, 2007-09-04 17:11:21-04:00, jas@rowvwade. +17
-0
    Put in debugging mechanism to print the transaction "wait for"
    tree from the debugger.

  storage/falcon/TransactionManager.h@stripped, 2007-09-04 17:11:21-04:00, jas@rowvwade. +2 -0
    Put in debugging mechanism to print the transaction "wait for"
    tree from the debugger.

diff -Nrup a/storage/falcon/CMakeLists.txt b/storage/falcon/CMakeLists.txt
--- a/storage/falcon/CMakeLists.txt	2007-08-25 16:32:19 -04:00
+++ b/storage/falcon/CMakeLists.txt	2007-09-04 17:11:13 -04:00
@@ -167,6 +167,7 @@ ADD_LIBRARY(ha_falcon
 		RecordLeaf.cpp 
 		RecordLocatorPage.cpp
 		RecordSection.cpp
+		RecordScavenge.cpp
 		RecordVersion.cpp 
 		RecoveryObjects.cpp
 		RecoveryPage.cpp
@@ -430,6 +431,7 @@ ADD_LIBRARY(ha_falcon
 		RecordGroup.h 
 		RecordLeaf.h 
 		RecordLocatorPage.h
+		RecordScavenge.h
 		RecordSection.h
 		RecordVersion.h 
 		RecoveryObjects.h
diff -Nrup a/storage/falcon/Database.cpp b/storage/falcon/Database.cpp
--- a/storage/falcon/Database.cpp	2007-08-27 11:24:20 -04:00
+++ b/storage/falcon/Database.cpp	2007-09-04 17:11:13 -04:00
@@ -69,7 +69,8 @@
 #include "TableSpace.h"
 #include "InfoTable.h"
 #include "MemoryManager.h"
-#include "Record.h"
+#include "MemMgr.h"
+#include "RecordScavenge.h"
 
 #ifndef STORAGE_ENGINE
 #include "Applications.h"
@@ -398,9 +399,9 @@ Database::Database(const char *dbName, C
 	memset(tablesModId, 0, sizeof (tablesModId));
 	memset(unTables, 0, sizeof (unTables));
 	memset(schemas, 0, sizeof (schemas));
-	currentAgeGroup = 1;
-	overflowSize = 0;
-	memset((void*) ageGroupSizes, 0, sizeof (ageGroupSizes));
+	currentGeneration = 1;
+	//overflowSize = 0;
+	//memset((void*) ageGroupSizes, 0, sizeof (ageGroupSizes));
 	tableList = NULL;
 	recordMemoryMax = configuration->recordMemoryMax;
 	recordScavengeFloor = configuration->recordScavengeFloor;
@@ -1699,47 +1700,31 @@ void Database::retireRecords(bool forced
 	if (systemConnection->transaction)
 		commitSystemTransaction();
 		
-	int threshold = 0;
-	int64 total = 0;
 	transactionManager->purgeTransactions();
 	TransId oldestActiveTransaction = transactionManager->findOldestActive();
-	int n;
-
-	// Compute record memory in use.  Note point we pass lower limit
-
-	for (n = 0; n < AGE_GROUPS; ++n)
-		{
-		int64 size = ageGroupSizes[n];
-		
-		if (size > 0)
-			total += size;
-			
-		if (!threshold && total > (int64)recordScavengeFloor)
-			threshold = currentAgeGroup - n;
-		}
-
-	total += overflowSize;
-	RecordScavenge recordScavenge;
-	memset(&recordScavenge, 0, sizeof(recordScavenge));
-	recordScavenge.age = threshold;
-	recordScavenge.transactionId = oldestActiveTransaction;
-
-	if (forced)
-		recordScavenge.age = MAX(threshold, currentAgeGroup - AGE_GROUPS / 2);
-		
+	int threshold = 0;
+	uint64 total = recordDataPool->activeMemory;
+	RecordScavenge recordScavenge(this, oldestActiveTransaction);
+	
 	// If we passed the upper limit, scavenge.  If we didn't pick up
 	// a significant amount of memory since the last cycle, don't bother
 	// bumping the age group.
 
-	if (forced || total > (int64)recordScavengeThreshold)
+	if (forced || total >  recordScavengeThreshold)
 		{
-		printRecordMemory (threshold, total);
-		Sync sync (&syncTables, "Database::retireRecords");
-		sync.lock (Shared);
+		Sync syncTbl (&syncTables, "Database::retireRecords");
+		syncTbl.lock (Shared);
+		Table *table;
+		
+		for (table = tableList; table; table = table->next)
+			table->inventoryRecords(&recordScavenge);
+		
+		threshold = recordScavenge.computeThreshold(recordScavengeFloor);
+		recordScavenge.printRecordMemory();	
 		int count = 0;
 		int skipped = 0;
 		
-		for (Table *table = tableList; table; table = table->next)
+		for (table = tableList; table; table = table->next)
 			{
 			try
 				{
@@ -1752,53 +1737,39 @@ void Database::retireRecords(bool forced
 				}
 			catch (SQLException &exception)
 				{
-				sync.unlock();
+				syncTbl.unlock();
 				Log::debug ("Exception during scavenger of table %s.%s: %s\n",
 						table->schemaName, table->name, exception.getText());
 				}
 			}
 
-		sync.unlock();
-		int64 newTotal = overflowSize;
-		
-		for (int n = 0; n < AGE_GROUPS; ++n)
-			newTotal += ageGroupSizes [n];
-		
+		syncTbl.unlock();
 		Log::log(LogScavenge, " %d records, " I64FORMAT " bytes reclaimed\n", 
 					recordScavenge.recordsReclaimed, recordScavenge.spaceReclaimed);
 			
-		total = newTotal;
+		total = recordScavenge.spaceRemaining;
 		}
-	else if ((total - lastRecordMemory) < (int64) recordScavengeThreshold / 4)
+	else if ((total - lastRecordMemory) < recordScavengeThreshold / 4)
 		{
-		recordScavenge.age = -1;
+		recordScavenge.scavengeGeneration = -1;
 		cleanupRecords (&recordScavenge);
 		
 		return;
 		}
 	else
 		{
-		recordScavenge.age = -1;
+		recordScavenge.scavengeGeneration = -1;
 		cleanupRecords (&recordScavenge);
-		printRecordMemory (threshold, total);
+		//printRecordMemory (threshold, total);
+		recordScavenge.printRecordMemory();
 		}
 
 	lastRecordMemory = total;
-	INTERLOCKED_INCREMENT (currentAgeGroup);
-	INTERLOCKED_ADD(&overflowSize, ageGroupSizes [AGE_GROUPS - 1]);
-	//overflowSize += ageGroupSizes [AGE_GROUPS - 1];
-
-	for (n = AGE_GROUPS - 1; n > 0; --n)
-		{
-		long size = ageGroupSizes [n - 1];
-		INTERLOCKED_EXCHANGE(ageGroupSizes + n, (size >= 0) ? size : 0);
-		}
-		
-	//ageGroupSizes [0] = 0;
-	INTERLOCKED_EXCHANGE(ageGroupSizes + 0, 0);
+	INTERLOCKED_INCREMENT (currentGeneration);
 	lastRetireRecords = timestamp;
 }
 
+/***
 void Database::printRecordMemory(int64 threshold, int64 total)
 {
 	Log::debug ("Record Memory usage for %s:\n", (const char*) name);
@@ -1815,6 +1786,7 @@ void Database::printRecordMemory(int64 t
 	Log::log(LogScavenge, " total: " I64FORMAT ", threshold " I64FORMAT "%s\n", total,
threshold,
 				(total > (int64)recordScavengeThreshold) ? " -- scavenge" : "");
 }
+***/
 
 void Database::ticker(void * database)
 {
diff -Nrup a/storage/falcon/Database.h b/storage/falcon/Database.h
--- a/storage/falcon/Database.h	2007-08-26 13:08:57 -04:00
+++ b/storage/falcon/Database.h	2007-09-04 17:11:13 -04:00
@@ -35,7 +35,7 @@
 #define ODS_MINOR_VERSION2	2		// Has SequencePages external to the section tree
 #define ODS_MINOR_VERSION3	3		// Switch to variable length record numbers in index
 #define ODS_MINOR_VERSION	ODS_MINOR_VERSION3
-#define AGE_GROUPS			32
+//#define AGE_GROUPS			32
 
 #define COMBINED_VERSION(major,minor)	(major * 100 + minor)
 #define VERSION_CURRENT					COMBINED_VERSION(ODS_VERSION, ODS_MINOR_VERSION)					
@@ -93,9 +93,9 @@ class IndexKey;
 class InfoTable;
 class TableSpace;
 class MemMgr;
+class RecordScavenge;
 
 struct JavaCallback;
-struct RecordScavenge;
 
 class Database
 {
@@ -119,7 +119,7 @@ public:
 	void			licenseCheck();
 	void			cleanupRecords (RecordScavenge *recordScavenge);
 	void			serverOperation (int op, Parameters *parameters);
-	void			printRecordMemory(int64 threshold, int64 tota);
+	//void			printRecordMemory(int64 threshold, int64 tota);
 	void			retireRecords(bool forced);
 	int				getMemorySize (const char *string);
 	JString			analyze(int mask);
@@ -186,7 +186,6 @@ public:
 	void			addRef();
 	PreparedStatement* prepareStatement (const char *sqlStr);
 	void			addSystemTables();
-	//int32			createSection(Transaction *transaction);
 	Table*			addTable (User *owner, const char *name, const char *schema, TableSpace
*tableSpace);
 	Table*			findTable (const char *schema, const char *name);
 	Statement*		createStatement();
@@ -267,7 +266,6 @@ public:
 	PageWriter			*pageWriter;
 	PreparedStatement	*updateCardinality;
 	MemMgr				*recordDataPool;
-	//MemMgr			*recordObjectPool;
 	
 	volatile time_t	timestamp;
 	volatile int	numberQueries;
@@ -277,9 +275,9 @@ public:
 	int				odsVersion;
 	int				noSchedule;
 
-	volatile INTERLOCK_TYPE	currentAgeGroup;
-	volatile long	overflowSize;
-	volatile long 	ageGroupSizes [AGE_GROUPS];
+	volatile INTERLOCK_TYPE	currentGeneration;
+	//volatile long	overflowSize;
+	//volatile long 	ageGroupSizes [AGE_GROUPS];
 	uint64			recordMemoryMax;
 	uint64			recordScavengeThreshold;
 	uint64			recordScavengeFloor;
diff -Nrup a/storage/falcon/Makefile.am b/storage/falcon/Makefile.am
--- a/storage/falcon/Makefile.am	2007-08-30 13:36:30 -04:00
+++ b/storage/falcon/Makefile.am	2007-09-04 17:11:14 -04:00
@@ -98,7 +98,9 @@ falcon_headers= Agent.h Alias.h Applicat
 		Protocol.h PStatement.h Queue.h QueryString.h RecordGroup.h \
 		Record.h RecordLeaf.h \
 		RecordLocatorPage.h \
-		RecordSection.h RecordVersion.h \
+		RecordSection.h \
+		RecordScavenge.h \
+		RecordVersion.h \
 		RecoveryObjects.h \
 		RecoveryPage.h \
 		Registry.h Repository.h RepositoryManager.h RepositoryVolume.h \
@@ -248,6 +250,7 @@ falcon_sources= Agent.cpp Alias.cpp \
 		RecordGroup.cpp RecordLeaf.cpp \
 		RecordLocatorPage.cpp \
 		RecordSection.cpp \
+		RecordScavenge.cpp \
 		RecordVersion.cpp \
 		RecoveryObjects.cpp \
 		RecoveryPage.cpp \
diff -Nrup a/storage/falcon/MemMgr.cpp b/storage/falcon/MemMgr.cpp
--- a/storage/falcon/MemMgr.cpp	2007-08-30 21:04:06 -04:00
+++ b/storage/falcon/MemMgr.cpp	2007-09-04 17:11:14 -04:00
@@ -285,6 +285,7 @@ MemMgr::MemMgr(int rounding, int cutoff,
 	currentMemory		= 0;
 	blocksAllocated		= 0;
 	blocksActive		= 0;
+	activeMemory		= 0;
 	numberBigHunks		= 0;
 	numberSmallHunks	= 0;
 	bigHunks			= NULL;
@@ -402,8 +403,6 @@ MemBlock* MemMgr::alloc(int length)
 	 */
 	
 	
-	//Sync sync (&mutex, "MemMgr::alloc");
-	//sync.lock(Exclusive);
 	MemFreeBlock *freeBlock;
 
 	if (length < (int) (OFFSET(MemBlock*, body) + sizeof (MemFreeBlock) - sizeof
(MemBigObject)))
@@ -424,6 +423,8 @@ MemBlock* MemMgr::alloc(int length)
 			if (tail < (int) sizeof (MemFreeBlock))
 				{
 				block->pool = this;
+				activeMemory += block->length;
+				
 				return block;
 				}
 			
@@ -434,6 +435,7 @@ MemBlock* MemMgr::alloc(int length)
 			freeBlock->memHeader.length = tail - sizeof (MemBigHeader); 
 			block->length = length;
 			block->pool = this;
+			activeMemory += length;
 			
 			if ( (freeBlock->next = newBlock->next) )
 				freeBlock->next->prior = freeBlock;
@@ -478,6 +480,7 @@ MemBlock* MemMgr::alloc(int length)
 	MemBlock *block = (MemBlock*) &newBlock->memHeader;
 	block->pool = this;
 	block->length = length;
+	activeMemory += length;
 	
 	// If there is space left over, create a free block
 	
@@ -631,6 +634,8 @@ void MemMgr::releaseBlock(MemBlock *bloc
 	sync.lock(Exclusive);
 	//validateFreeList();
 	block->pool = NULL;
+	ASSERT(length <= activeMemory);
+	activeMemory -= length;
 	
 	if (freeBlock->next && !freeBlock->next->memHeader.pool)
 		{
diff -Nrup a/storage/falcon/MemMgr.h b/storage/falcon/MemMgr.h
--- a/storage/falcon/MemMgr.h	2007-08-23 11:20:45 -04:00
+++ b/storage/falcon/MemMgr.h	2007-09-04 17:11:15 -04:00
@@ -121,6 +121,7 @@ public:
 	MemFreeBlock	junk;
 	Mutex			mutex;		// Win32 critical regions are faster than SyncObject
 	int64			currentMemory;
+	uint64			activeMemory;
 	int				blocksAllocated;
 	int				blocksActive;
 
diff -Nrup a/storage/falcon/Record.cpp b/storage/falcon/Record.cpp
--- a/storage/falcon/Record.cpp	2007-08-31 12:23:28 -04:00
+++ b/storage/falcon/Record.cpp	2007-09-04 17:11:15 -04:00
@@ -68,6 +68,7 @@ Record::Record(Table *tbl, int32 recordN
 	recordNumber = recordNum;
 	const short *p = (short*) stream->segments->address;
 	size = sizeof (*this);
+	generation = table->database->currentGeneration;
 #ifdef CHECK_RECORD_ACTIVITY
 	active = false;
 #endif
@@ -78,8 +79,8 @@ Record::Record(Table *tbl, int32 recordN
 		data.record = stream->decompress(table->tableId, recordNumber);
 		format = table->getFormat (*(short*) data.record);
 		size += format->length;
-		setAgeGroup();
-
+		//setAgeGroup();
+		
 		if (stream->decompressedLength != format->length)
 			throw SQLEXCEPTION (RUNTIME_ERROR,
 					"wrong length record (got %d, expected %d), table %s.%s, section %d, record %d",
@@ -109,7 +110,7 @@ Record::Record(Table * tbl, Format *fmt)
 	size = sizeof (RecordVersion);
 	encoding = noEncoding;
 	state = recData;
-	ageGroup = table->database->currentAgeGroup;	// to avoid a Valgrind warning
+	generation = table->database->currentGeneration;
 	
 #ifdef CHECK_RECORD_ACTIVITY
 	active = false;
@@ -130,10 +131,11 @@ Record::~Record()
 #ifdef CHECK_RECORD_ACTIVITY
 	ASSERT(!active);
 #endif
-	
+	/***
 	if (table)
 		unsetAgeGroup();
-
+	***/
+	
 	deleteData();
 }
 
@@ -677,7 +679,6 @@ int Record::setEncodedRecord(Stream *str
 	encoding = shortVector;
 	int vectorLength = format->count * sizeof(short);
 	int totalLength = vectorLength + stream->totalLength;
-	//char *dataBuffer = ALLOCATE_RECORD(totalLength);
 	char *dataBuffer = allocRecordData(totalLength);
 	memset(dataBuffer, 0, vectorLength);
 	stream->getSegment(0, stream->totalLength, dataBuffer + vectorLength);
@@ -685,7 +686,8 @@ int Record::setEncodedRecord(Stream *str
 	
 	highWater = 0;
 	size +=  vectorLength + stream->totalLength;
-	setAgeGroup();
+	//setAgeGroup();
+	generation = table->database->currentGeneration;
 
 	if (interlocked)
 		{
@@ -798,21 +800,21 @@ bool Record::isNull(int fieldId)
 
 // Set age group and add size to database
 
+/***
 void Record::setAgeGroup()
 {
 	Database *database = table->database;
-	ageGroup = database->currentAgeGroup;
+	generation = database->currentGeneration;
 	//database->ageGroupSizes [0] += size;
 	INTERLOCKED_ADD(database->ageGroupSizes + 0, size);
 }
 
-
 void Record::unsetAgeGroup(void)
 {
 	if (table)
 		{
 		Database *database = table->database;
-		int n = database->currentAgeGroup - ageGroup;
+		int n = database->currentGeneration - generation;
 		
 		if (n >= AGE_GROUPS)
 			INTERLOCKED_ADD(&database->overflowSize, -size);
@@ -821,18 +823,22 @@ void Record::unsetAgeGroup(void)
 		}
 
 }
+***/
 
 void Record::poke()
 {
+	generation = table->database->currentGeneration;
+	
+	/***
 	Database *database = table->database;
-	int32 currentAgeGroup = database->currentAgeGroup;
-	int32 n = currentAgeGroup - ageGroup;
+	int32 currentGeneration = database->currentGeneration;
+	int32 n = currentGeneration - generation;
 
 	if (n == 0)
 		return;
 
 	ASSERT (n > 0);
-	ageGroup = currentAgeGroup;
+	generation = currentGeneration;
 
 	if (n >= AGE_GROUPS)
 		INTERLOCKED_ADD(&database->overflowSize, -size);
@@ -840,6 +846,7 @@ void Record::poke()
 		INTERLOCKED_ADD(database->ageGroupSizes + n, -size);
 
 	INTERLOCKED_ADD(database->ageGroupSizes + 0, size);
+	***/
 }
 
 Record* Record::releaseNonRecursive(void)
@@ -911,7 +918,7 @@ void Record::deleteData(void)
 void Record::print(void)
 {
 	printf("  %p\tId %d, enc %d, state %d, use %d, grp %d\n",
-			this, recordNumber, encoding, state, useCount, ageGroup);
+			this, recordNumber, encoding, state, useCount, generation);
 }
 
 void Record::printRecord(const char* header)
diff -Nrup a/storage/falcon/Record.h b/storage/falcon/Record.h
--- a/storage/falcon/Record.h	2007-08-25 16:32:22 -04:00
+++ b/storage/falcon/Record.h	2007-09-04 17:11:15 -04:00
@@ -29,17 +29,6 @@
 
 #define CHECK_RECORD_ACTIVITY
 
-struct RecordScavenge
-	{
-	TransId	transactionId;
-	int		age;
-	uint	recordsReclaimed;
-	uint	recordsRemaining;
-	uint	versionsRemaining;
-	uint64	spaceReclaimed;
-	uint64	spaceRemaining;
-	};
-	
 enum RecordEncoding {
 	noEncoding = 0,
 	traditional,
@@ -64,6 +53,7 @@ class Transaction;
 class Value;
 class Stream;
 class Database;
+class RecordScavenge;
 CLASS(Field);
 
 extern char	*RecordAllocate (int size, const char *file, int line);
@@ -104,11 +94,13 @@ public:
 	void			getEncodedValue (int fieldId, Value *value);
 	void			getRecord (Stream *stream);
 	int				getEncodedSize();
-	void			setAgeGroup();
 	void			deleteData(void);
 	void			printRecord(const char* header);
 	void			validateData(void);
 	char*			allocRecordData(int length);
+	
+	//void			setAgeGroup();
+	//void			unsetAgeGroup(void);
 
 	Record (Table *table, Format *recordFormat);
 	Record(Table *table, int32 recordNumber, Stream *stream);
@@ -132,7 +124,7 @@ public:
 	Format		*format;
 	int			recordNumber;
 	int			size;
-	int			ageGroup;
+	int			generation;
 	short		highWater;
 	UCHAR		encoding;
 	UCHAR		state;
@@ -140,7 +132,6 @@ public:
 #ifdef CHECK_RECORD_ACTIVITY
 	UCHAR		active;					// this is for debugging only
 #endif
-	void unsetAgeGroup(void);
 };
 
 #endif // !defined(AFX_RECORD_H__02AD6A50_A433_11D2_AB5B_0000C01D2301__INCLUDED_)
diff -Nrup a/storage/falcon/RecordGroup.cpp b/storage/falcon/RecordGroup.cpp
--- a/storage/falcon/RecordGroup.cpp	2007-08-29 18:22:36 -04:00
+++ b/storage/falcon/RecordGroup.cpp	2007-09-04 17:11:16 -04:00
@@ -160,3 +160,10 @@ int RecordGroup::countActiveRecords()
 
 	return count;
 }
+
+void RecordGroup::inventoryRecords(RecordScavenge* recordScavenge)
+{
+	for (RecordSection **section = records, **end = records + RECORD_SLOTS; section <
end; ++section)
+		if (*section)
+			(*section)->inventoryRecords(recordScavenge);
+}
diff -Nrup a/storage/falcon/RecordGroup.h b/storage/falcon/RecordGroup.h
--- a/storage/falcon/RecordGroup.h	2007-08-25 12:01:26 -04:00
+++ b/storage/falcon/RecordGroup.h	2007-09-04 17:11:16 -04:00
@@ -29,13 +29,15 @@
 class RecordGroup : public RecordSection  
 {
 public:
-	virtual int countActiveRecords();
-	virtual int retireRecords (Table *table, int base, RecordScavenge *recordScavenge);
 	RecordGroup (int32 base, int32 id, RecordSection *section);
 	RecordGroup(int32 base);
-	virtual bool store (Record *record, Record *prior, int32 id, RecordSection **parentPtr);
-	virtual Record* fetch (int32 id);
 	virtual ~RecordGroup();
+
+	virtual int		countActiveRecords();
+	virtual int		retireRecords (Table *table, int base, RecordScavenge *recordScavenge);
+	virtual bool	store (Record *record, Record *prior, int32 id, RecordSection **parentPtr);
+	virtual void	inventoryRecords(RecordScavenge* recordScavenge);
+	virtual Record* fetch (int32 id);
 
 	RecordSection	*records [RECORD_SLOTS];
 	int32			base;
diff -Nrup a/storage/falcon/RecordLeaf.cpp b/storage/falcon/RecordLeaf.cpp
--- a/storage/falcon/RecordLeaf.cpp	2007-08-29 18:22:38 -04:00
+++ b/storage/falcon/RecordLeaf.cpp	2007-09-04 17:11:16 -04:00
@@ -26,6 +26,7 @@
 #include "Table.h"
 #include "Sync.h"
 #include "Interlock.h"
+#include "RecordScavenge.h"
 
 #ifdef _DEBUG
 #undef THIS_FILE
@@ -129,7 +130,7 @@ int RecordLeaf::retireRecords (Table *ta
 			if (record->isVersion())
 				{
 				if ((record->scavenge(oldestActiveTransaction)) &&
-				    ((!record->hasRecord()) || ((record->useCount == 1) &&
(record->ageGroup <= age))))
+				    ((!record->hasRecord()) || ((record->useCount == 1) &&
(record->generation <= age))))
 				    {
 				    redo = true;
 				    
@@ -138,7 +139,7 @@ int RecordLeaf::retireRecords (Table *ta
 				else
 					++count;
 				}
-			else if (record->ageGroup <= age && record->useCount == 1)
+			else if (record->generation <= age && record->useCount == 1)
 				{
 				redo = true;
 				
@@ -166,7 +167,7 @@ int RecordLeaf::retireRecords (Table *ta
 			if (record->isVersion())
 				{
 				if ((record->scavenge(recordScavenge)) &&
-				    ((!record->hasRecord()) || ((record->useCount == 1) &&
(record->ageGroup <= recordScavenge->age))))
+				    ((!record->hasRecord()) || ((record->useCount == 1) &&
(record->generation <= recordScavenge->scavengeGeneration))))
 					{
 					*ptr = NULL;
 					recordScavenge->spaceReclaimed += record->size;
@@ -183,7 +184,7 @@ int RecordLeaf::retireRecords (Table *ta
 					++count;
 					}
 				}
-			else if (record->ageGroup <= recordScavenge->age &&
record->useCount == 1)
+			else if (record->generation <= recordScavenge->scavengeGeneration &&
record->useCount == 1)
 				{
 				*ptr = NULL;
 				recordScavenge->spaceReclaimed += record->size;
@@ -220,4 +221,14 @@ int RecordLeaf::countActiveRecords()
 			++count;
 
 	return count;
+}
+
+void RecordLeaf::inventoryRecords(RecordScavenge* recordScavenge)
+{
+	Sync sync(&syncObject, "RecordLeaf::inventoryRecords");
+	sync.lock(Shared);
+
+	for (Record **ptr = records, **end = records + RECORD_SLOTS; ptr < end; ++ptr)
+		if (*ptr)
+			recordScavenge->inventoryRecord(*ptr);
 }
diff -Nrup a/storage/falcon/RecordLeaf.h b/storage/falcon/RecordLeaf.h
--- a/storage/falcon/RecordLeaf.h	2007-08-25 12:01:27 -04:00
+++ b/storage/falcon/RecordLeaf.h	2007-09-04 17:11:17 -04:00
@@ -40,6 +40,7 @@ public:
 
 	Record		*records [RECORD_SLOTS];
 	SyncObject	syncObject;
+	void inventoryRecords(RecordScavenge* recordScavenge);
 };
 
 #endif // !defined(AFX_RECORDLEAF_H__02AD6A56_A433_11D2_AB5B_0000C01D2301__INCLUDED_)
diff -Nrup a/storage/falcon/RecordScavenge.cpp b/storage/falcon/RecordScavenge.cpp
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/storage/falcon/RecordScavenge.cpp	2007-09-04 17:11:22 -04:00
@@ -0,0 +1,89 @@
+/* Copyright (C) 2007 MySQL AB
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#include <memory.h>
+#include "Engine.h"
+#include "RecordScavenge.h"
+#include "Database.h"
+#include "Record.h"
+#include "Log.h"
+
+
+RecordScavenge::RecordScavenge(Database *db, TransId oldestTransaction)
+{
+	database = db;
+	transactionId = oldestTransaction;
+	baseGeneration = database->currentGeneration;
+	memset(ageGroups, 0, sizeof(ageGroups));
+	recordsReclaimed = 0;
+	recordsRemaining = 0;
+	versionsRemaining = 0;
+	spaceReclaimed = 0;
+	spaceRemaining = 0;
+	overflowSpace = 0;
+	
+}
+
+RecordScavenge::~RecordScavenge(void)
+{
+}
+
+void RecordScavenge::inventoryRecord(Record* record)
+{
+	for (Record *rec = record; rec; rec = rec->getPriorVersion())
+		{
+		int age = baseGeneration - record->generation;
+		
+		if (age >= 0 && age < AGE_GROUPS)
+			ageGroups[age] += record->size;
+		else if (age >= AGE_GROUPS)
+			overflowSpace += record->size;
+		else
+			ageGroups[0] = record->size;
+		}
+}
+
+int RecordScavenge::computeThreshold(uint64 target)
+{
+	totalSpace = overflowSpace;
+	scavengeGeneration = 0;
+	
+	for (int n = AGE_GROUPS - 1; n >= 0; --n)
+		{
+		totalSpace += ageGroups[n];
+		
+		if (totalSpace >= target && scavengeGeneration == 0)
+			scavengeGeneration = baseGeneration + n;
+		}
+	
+	return scavengeGeneration;
+}
+
+void RecordScavenge::printRecordMemory(void)
+{
+	Log::debug ("Record Memory usage for %s:\n", (const char*) database->name);
+	int max;
+
+	for (max = AGE_GROUPS - 1; max > 0; --max)
+		if (ageGroups[max])
+			break;
+
+	for (int n = 0; n <= max; ++n)
+		if (ageGroups [n])
+			Log::debug ("  %d. %d\n", baseGeneration - n, ageGroups[n]);
+
+	Log::log(LogScavenge, " total: " I64FORMAT ", threshold %d%s\n", totalSpace,
scavengeGeneration,
+				(scavengeGeneration) ? " -- scavenge" : "");
+}
diff -Nrup a/storage/falcon/RecordScavenge.h b/storage/falcon/RecordScavenge.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/storage/falcon/RecordScavenge.h	2007-09-04 17:11:22 -04:00
@@ -0,0 +1,48 @@
+/* Copyright (C) 2007 MySQL AB
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifndef _RECORD_SCAVENGE_H_
+#define _RECORD_SCAVENGE_H_
+
+static const int AGE_GROUPS = 20;
+
+class Database;
+class Record;
+
+class RecordScavenge
+{
+public:
+	Database	*database;
+	TransId		transactionId;
+	int			scavengeGeneration;
+	int			baseGeneration;
+	uint		recordsReclaimed;
+	uint		recordsRemaining;
+	uint		versionsRemaining;
+	uint64		spaceReclaimed;
+	uint64		spaceRemaining;
+	uint64		ageGroups[AGE_GROUPS];
+	uint64		overflowSpace;
+	uint64		totalSpace;
+	
+	RecordScavenge(Database *db, TransId oldestTransaction);
+	~RecordScavenge(void);
+
+	void		inventoryRecord(Record* record);
+	int computeThreshold(uint64 target);
+	void printRecordMemory(void);
+};
+
+#endif
diff -Nrup a/storage/falcon/RecordSection.h b/storage/falcon/RecordSection.h
--- a/storage/falcon/RecordSection.h	2007-08-25 12:01:27 -04:00
+++ b/storage/falcon/RecordSection.h	2007-09-04 17:11:18 -04:00
@@ -26,19 +26,21 @@
 
 class Record;
 class Table;
+class RecordScavenge;
 
-struct RecordScavenge;
 
 #define RECORD_SLOTS		100
 
 class RecordSection  
 {
 public:
-	virtual ~RecordSection();
-	virtual Record* fetch (int32 id) = 0;
-	virtual bool store (Record *record, Record *prior, int32 id, RecordSection **parentPtr)
= 0;
-	virtual int retireRecords(Table *table, int base, RecordScavenge *recordScavenge) = 0;
-	virtual int countActiveRecords() = 0;
+	virtual		~RecordSection();
+	
+	virtual	Record*	fetch (int32 id) = 0;
+	virtual	bool	store (Record *record, Record *prior, int32 id, RecordSection **parentPtr)
= 0;
+	virtual	int		retireRecords(Table *table, int base, RecordScavenge *recordScavenge) = 0;
+	virtual	void	inventoryRecords(RecordScavenge* recordScavenge) = 0;
+	virtual	int		countActiveRecords() = 0;
 };
 
 #endif // !defined(AFX_RECORDSECTION_H__02AD6A54_A433_11D2_AB5B_0000C01D2301__INCLUDED_)
diff -Nrup a/storage/falcon/RecordVersion.cpp b/storage/falcon/RecordVersion.cpp
--- a/storage/falcon/RecordVersion.cpp	2007-08-25 12:44:15 -04:00
+++ b/storage/falcon/RecordVersion.cpp	2007-09-04 17:11:18 -04:00
@@ -28,6 +28,8 @@
 #include "SerialLogControl.h"
 #include "Stream.h"
 #include "Dbb.h"
+#include "RecordScavenge.h"
+
 //////////////////////////////////////////////////////////////////////
 // Construction/Destruction
 //////////////////////////////////////////////////////////////////////
@@ -331,7 +333,7 @@ void RecordVersion::print(void)
 {
 	Log::debug("  %p\tId %d, enc %d, state %d, tid %d, use %d, grp %d, prior %p\n",
 			this, recordNumber, encoding, state, transactionId, useCount,
-			ageGroup, priorVersion);
+			generation, priorVersion);
 	
 	if (priorVersion)
 		priorVersion->print();
diff -Nrup a/storage/falcon/SerialLog.cpp b/storage/falcon/SerialLog.cpp
--- a/storage/falcon/SerialLog.cpp	2007-08-31 12:23:29 -04:00
+++ b/storage/falcon/SerialLog.cpp	2007-09-04 17:11:18 -04:00
@@ -442,7 +442,7 @@ void SerialLog::overflowFlush(void)
 	writeBlock->length = (int) (writePtr - (UCHAR*) writeBlock);
 	writeWindow->setLastBlock(writeBlock);
 	lastReadBlock = writeBlock->readBlockNumber = getReadBlock();
-	ASSERT(writeWindow->validate(writeBlock));
+	//ASSERT(writeWindow->validate(writeBlock));
 	
 	// Keep track of what needs to be written
 
@@ -463,7 +463,7 @@ void SerialLog::overflowFlush(void)
 		throw;
 		}	
 		
-	ASSERT(flushWindow->validate(flushBlock));
+	//ASSERT(flushWindow->validate(flushBlock));
 	++physicalFlushes;
 	mutex.unlock();		
 	
@@ -570,7 +570,7 @@ uint64 SerialLog::flush(bool forceNewWin
 		throw;
 		}
 			
-	ASSERT(flushWindow->validate(flushBlock));
+	//ASSERT(flushWindow->validate(flushBlock));
 	++physicalFlushes;
 	mutex.unlock();
 	
@@ -581,7 +581,7 @@ uint64 SerialLog::flush(bool forceNewWin
 	wakeupFlushQueue(thread);
 	ASSERT(writer != thread);
 	ASSERT(writer || !srlQueue);
-	ASSERT(writeWindow->validate(writeBlock));
+	//ASSERT(writeWindow->validate(writeBlock));
 	syncPtr->unlock();
 
 	return nextBlockNumber;
@@ -619,7 +619,7 @@ void SerialLog::createNewWindow(void)
 	writeWindow->firstBlockNumber = nextBlockNumber;
 	initializeWriteBlock(writeWindow->firstBlock());
 	ASSERT(writeWindow->firstBlockNumber == writeBlock->blockNumber);
-	ASSERT(writeWindow->validate(writeBlock));
+	//ASSERT(writeWindow->validate(writeBlock));
 }
 
 void SerialLog::shutdown()
@@ -686,7 +686,7 @@ void SerialLog::putData(uint32 length, c
 	writeBlock->length = (int) (writePtr - (UCHAR*) writeBlock);
 	writeWindow->currentLength = (int) (writePtr - writeWindow->buffer);
 	recordStart = writeBlock->data;
-	ASSERT(writeWindow->validate(writeBlock));
+	//ASSERT(writeWindow->validate(writeBlock));
 }
 
 void SerialLog::startRecord()
@@ -988,7 +988,7 @@ void SerialLog::initializeWriteBlock(Ser
 	writeBlock->length = (int) (writePtr - (UCHAR*) writeBlock);
 	writeWindow->setLastBlock(writeBlock);
 	writeWarningTrack = writeWindow->warningTrack;
-	ASSERT(writeWindow->validate(writeBlock));
+	//ASSERT(writeWindow->validate(writeBlock));
 }
 
 
diff -Nrup a/storage/falcon/SerialLogControl.cpp b/storage/falcon/SerialLogControl.cpp
--- a/storage/falcon/SerialLogControl.cpp	2007-07-12 16:58:19 -04:00
+++ b/storage/falcon/SerialLogControl.cpp	2007-09-04 17:11:19 -04:00
@@ -170,10 +170,10 @@ SerialLogRecord* SerialLogControl::getRe
 
 void SerialLogControl::setWindow(SerialLogWindow *window, SerialLogBlock *block, int
offset)
 {
-	ASSERT(window->validate(block));
+	//ASSERT(window->validate(block));
 	SerialLogWindow *priorWindow = inputWindow;
 	SerialLogBlock *priorBlock = inputBlock;
-	ASSERT(!priorWindow || priorWindow->validate(priorBlock));
+	//ASSERT(!priorWindow || priorWindow->validate(priorBlock));
 
 	if (inputWindow != window)
 		{
@@ -186,8 +186,8 @@ void SerialLogControl::setWindow(SerialL
 
 	Sync sync(&log->syncWrite, "SerialLogControl::setWindow");
 	sync.lock(Shared);
-	inputWindow->validate(block);
-	ASSERT(inputWindow->validate(block));
+	//inputWindow->validate(block);
+	//ASSERT(inputWindow->validate(block));
 	inputBlock = block;
 	input = inputBlock->data;
 	inputEnd = (const UCHAR*) inputBlock + block->length;
@@ -196,7 +196,7 @@ void SerialLogControl::setWindow(SerialL
 	if (inputBlock == log->writeBlock && log->recordIncomplete)
 		inputEnd = log->recordStart;
 	
-	ASSERT(inputWindow->validate(inputEnd));	
+	//ASSERT(inputWindow->validate(inputEnd));	
 	version = srlVersion0;
 
 	if (input < inputEnd)
diff -Nrup a/storage/falcon/SerialLogWindow.cpp b/storage/falcon/SerialLogWindow.cpp
--- a/storage/falcon/SerialLogWindow.cpp	2007-08-29 18:23:19 -04:00
+++ b/storage/falcon/SerialLogWindow.cpp	2007-09-04 17:11:19 -04:00
@@ -184,7 +184,7 @@ SerialLogBlock* SerialLogWindow::nextBlo
 		 nextBlk->creationTime == (uint32) log->creationTime &&
 		 nextBlk->blockNumber == block->blockNumber + 1)
 		{
-		ASSERT(validate(nextBlk));
+		//ASSERT(validate(nextBlk));
 		return nextBlk;
 		}
 
diff -Nrup a/storage/falcon/Table.cpp b/storage/falcon/Table.cpp
--- a/storage/falcon/Table.cpp	2007-08-31 12:23:30 -04:00
+++ b/storage/falcon/Table.cpp	2007-09-04 17:11:19 -04:00
@@ -53,6 +53,7 @@
 #include "Interlock.h"
 #include "Collation.h"
 #include "TableSpace.h"
+#include "RecordScavenge.h"
 
 #ifndef STORAGE_ENGINE
 #include "Trigger.h"
@@ -584,7 +585,7 @@ Record* Table::fetchNext(int32 start)
 Record* Table::databaseFetch(int32 recordNumber)
 {
 	Stream stream;
-	ageGroup = database->currentAgeGroup;
+	ageGroup = database->currentGeneration;
 
 	if (!dataSection)
 		dataSection = dbb->findSection(dataSectionId);
@@ -762,7 +763,7 @@ void Table::loadIndexes()
 
 void Table::init(int id, const char *schema, const char *tableName, TableSpace *tblSpace)
 {
-	ageGroup = database->currentAgeGroup;
+	ageGroup = database->currentGeneration;
 
 	if ( (tableSpace = tblSpace) )
 		dbb = tableSpace->dbb;
@@ -1258,7 +1259,7 @@ void Table::deleteRecord(Transaction * t
 		}
 
 	record->state = recDeleted;
-	record->setAgeGroup();
+	//record->setAgeGroup();
 	fireTriggers(transaction, PreDelete, oldRecord, NULL);
 
 	// Do any necessary cascading
@@ -1559,9 +1560,19 @@ int Table::retireRecords(RecordScavenge 
 	return count;
 }
 
+void Table::inventoryRecords(RecordScavenge* recordScavenge)
+{
+	if (!records)
+		return;
+		
+	Sync sync(&syncObject, "Table::inventoryRecords");
+	sync.lock(Shared);
+	records->inventoryRecords(recordScavenge);
+}
+
 bool Table::insert(Record * record, Record *prior, int recordNumber)
 {
-	ageGroup = database->currentAgeGroup;
+	ageGroup = database->currentGeneration;
 	Sync sync(&syncObject, "Table::insert");
 
 	if (record)
diff -Nrup a/storage/falcon/Table.h b/storage/falcon/Table.h
--- a/storage/falcon/Table.h	2007-08-25 12:44:16 -04:00
+++ b/storage/falcon/Table.h	2007-09-04 17:11:20 -04:00
@@ -67,8 +67,7 @@ class AsciiBlob;
 class BinaryBlob;
 class Section;
 class TableSpace;
-
-struct RecordScavenge;
+class RecordScavenge;
 
 class Table : public PrivilegeObject
 {
@@ -246,6 +245,7 @@ protected:
 public:
 	RecordVersion* allocRecordVersion(Format* format, Transaction* transaction, Record*
priorVersion);
 	Record* allocRecord(int recordNumber, Stream* stream);
+	void inventoryRecords(RecordScavenge* recordScavenge);
 };
 
 #endif // !defined(AFX_TABLE_H__02AD6A42_A433_11D2_AB5B_0000C01D2301__INCLUDED_)
diff -Nrup a/storage/falcon/Transaction.cpp b/storage/falcon/Transaction.cpp
--- a/storage/falcon/Transaction.cpp	2007-08-23 21:21:26 -04:00
+++ b/storage/falcon/Transaction.cpp	2007-09-04 17:11:20 -04:00
@@ -54,6 +54,8 @@ static const char *stateNames [] = {
 	"Initial"
 	};
 
+static const int INDENT = 5;
+
 #ifdef _DEBUG
 #undef THIS_FILE
 static const char THIS_FILE[]=__FILE__;
@@ -1103,6 +1105,12 @@ void Transaction::print(void)
 	Log::debug("  %p Id %d, state %d, updates %d, wrtPend %d, states %d, dependencies %d,
records %d\n",
 			this, transactionId, state, hasUpdates, writePending, 
 			numberStates, dependencies, firstRecord != NULL);
+}
+
+void Transaction::printBlocking(int level)
+{
+	Log::debug ("%*s Trans %p, id %d\n", 
+				level * INDENT, "", this, transactionId);
 }
 
 void Transaction::getInfo(InfoTable* infoTable)
diff -Nrup a/storage/falcon/Transaction.h b/storage/falcon/Transaction.h
--- a/storage/falcon/Transaction.h	2007-08-22 13:49:08 -04:00
+++ b/storage/falcon/Transaction.h	2007-09-04 17:11:21 -04:00
@@ -120,6 +120,12 @@ public:
 	void		thaw(DeferredIndex* deferredIndex);
 	void		print(void);
 	void		getInfo(InfoTable* infoTable);
+	void		fullyCommitted(void);
+	void		releaseCommittedTransaction(void);
+	void		commitNoUpdates(void);
+	void		validateDependencies(bool noDependencies);
+	void		releaseSavePoints(void);
+	void		printBlocking(int level);
 
 	inline bool isActive()
 		{
@@ -179,12 +185,6 @@ protected:
 	RecordVersion	**recordPtr;
 
 	virtual ~Transaction();
-public:
-	void fullyCommitted(void);
-	void releaseCommittedTransaction(void);
-	void commitNoUpdates(void);
-	void validateDependencies(bool noDependencies);
-	void releaseSavePoints(void);
 };
 
 #endif // !defined(AFX_TRANSACTION_H__02AD6A4D_A433_11D2_AB5B_0000C01D2301__INCLUDED_)
diff -Nrup a/storage/falcon/TransactionManager.cpp b/storage/falcon/TransactionManager.cpp
--- a/storage/falcon/TransactionManager.cpp	2007-08-23 21:21:26 -04:00
+++ b/storage/falcon/TransactionManager.cpp	2007-09-04 17:11:21 -04:00
@@ -427,3 +427,20 @@ void TransactionManager::removeTransacti
 				}
 		}
 }
+
+void TransactionManager::printBlockage(void)
+{
+	Sync sync (&activeTransactions.syncObject, "TransactionManager::printBlockage");
+	sync.lock (Shared);
+
+	for (Transaction *trans = activeTransactions.first; trans; trans = trans->next)
+		if (trans->state == Active && !trans->waitingFor)
+			trans->printBlocking(1);
+}
+
+void TransactionManager::printBlocking(Transaction* transaction, int level)
+{
+	for (Transaction *trans = activeTransactions.first; trans; trans = trans->next)
+		if (trans->state == Active && trans->waitingFor == transaction)
+			trans->printBlocking(level + 1);
+}
diff -Nrup a/storage/falcon/TransactionManager.h b/storage/falcon/TransactionManager.h
--- a/storage/falcon/TransactionManager.h	2007-07-17 17:23:17 -04:00
+++ b/storage/falcon/TransactionManager.h	2007-09-04 17:11:21 -04:00
@@ -59,6 +59,8 @@ public:
 	int				priorRolledBack;
 	Queue<Transaction>	activeTransactions;
 	Queue<Transaction>	committedTransactions;
+	void printBlockage(void);
+	void printBlocking(Transaction* transaction, int level);
 };
 
 #endif
Thread
bk commit into 6.0-falcon tree (jas:1.2591)U-ROWVWADEjas4 Sep