List:Commits« Previous MessageNext Message »
From:Kevin Lewis Date:October 16 2008 3:04am
Subject:bzr push into mysql-6.0-falcon-team branch (klewis:2865 to 2869) Bug#39672
View as plain text  
 2869 Kevin Lewis	2008-10-15
      Latest updates to the Deadlock Predictor.  
      Adds the type of lock and better reporting and analysis.
modified:
  storage/falcon/SyncHandler.cpp
  storage/falcon/SyncHandler.h
  storage/falcon/SyncObject.cpp

 2868 Kevin Lewis	2008-10-15
      This call to poke() is not needed when a RecordVersion 
      is committed.  It only delays the ability of the scavenger 
      to reclaim the memory for this record.
      No bug. No testcase.  Most likely, not measurable.
modified:
  storage/falcon/RecordVersion.cpp

 2867 Kevin Lewis	2008-10-15
      Various code cleanup changes.
modified:
  storage/falcon/Dbb.cpp
  storage/falcon/DeferredIndex.cpp
  storage/falcon/DeferredIndex.h
  storage/falcon/DeferredIndexWalker.cpp
  storage/falcon/Index.cpp
  storage/falcon/SRLUpdateIndex.cpp
  storage/falcon/SRLUpdateRecords.cpp
  storage/falcon/Scavenger.cpp
  storage/falcon/Scavenger.h
  storage/falcon/SerialLogFile.cpp
  storage/falcon/StorageDatabase.cpp
  storage/falcon/StorageDatabase.h
  storage/falcon/Table.cpp
  storage/falcon/Table.h
  storage/falcon/Transaction.cpp
  storage/falcon/TransactionManager.cpp
  storage/falcon/WalkDeferred.cpp
  storage/falcon/ha_falcon.cpp
  storage/falcon/ha_falcon.h

 2866 Kevin Lewis	2008-10-15
      Bug#39672 - Using BitMap::nextSet does not work correctly
      when you clear the previous set bit.  This was fixed by
      the other changeset for this bug.  This caused half of 
      the RecordLeafs to remain in memory.  In order to process 
      the bitmap more reliably and make this loop like others 
      in the Falcon code, we use nextSet(0).  
      
      Also, do not spread out the numbers in the emptySections 
      bitmap by setting record numbers.  Use section numbers 
      for a tighter bitmap.
      
      Also, add some reporting features to analyze the RecordLeaf
      objects and their contents.
      
      Also, use RecordSection::anyActiveRecords() instead of
      RecordSection::countActiveRecords() when the count is not 
      important. This will improve speed.
modified:
  storage/falcon/Bitmap.h
  storage/falcon/Connection.h
  storage/falcon/Database.cpp
  storage/falcon/RecordGroup.cpp
  storage/falcon/RecordGroup.h
  storage/falcon/RecordLeaf.cpp
  storage/falcon/RecordLeaf.h
  storage/falcon/RecordSection.h
  storage/falcon/Table.cpp
  storage/falcon/Table.h

 2865 Kevin Lewis	2008-10-15
      Bug#39672 - Using Bitmap::nextSet() failed after searching
      from last bit cleard and crossing multiples of 1024.
      
      To show the problem, I added a unit test that can be 
      activated by "SET GLOBAL FALCON_DEBUG_TRACE=64".  The unit
      test contains 4 different tests that print "** Error" when
      something goes wrong. 
modified:
  storage/falcon/Bitmap.cpp
  storage/falcon/Database.cpp
  storage/falcon/Database.h

=== modified file 'storage/falcon/Bitmap.cpp'
--- a/storage/falcon/Bitmap.cpp	2008-06-19 15:09:45 +0000
+++ b/storage/falcon/Bitmap.cpp	2008-10-16 01:04:03 +0000
@@ -19,6 +19,7 @@
 
 #include <memory.h>
 #include "Engine.h"
+#include "Log.h"
 #include "Bitmap.h"
 
 #ifndef FALCONDB
@@ -207,7 +208,7 @@ int32 Bitmap::nextSet(int32 start)
 
 	uint indexes[6];
 	decompose (start, indexes);
-    void **vectors [5];
+	void **vectors [5];
 	vectors [level] = vector;
 	int index;
 
@@ -244,7 +245,8 @@ int32 Bitmap::nextSet(int32 start)
 			void **vec = vectors [lvl];
 			
 			for (index = indexes[lvl]; index < BITMAP_VECTOR_SIZE && !vec [index]; ++index)
-				;
+				for (int n = 0; n < lvl; ++n)
+					indexes[n] = 0;
 				
 			if (index < BITMAP_VECTOR_SIZE)
 				{
@@ -702,3 +704,116 @@ bool Bitmap::setSafe(int32 bitNumber)
 	
 	return true;
 }
+
+void Bitmap::unitTest(void)
+{
+	int bitNumber;
+	Bitmap *tester = new Bitmap;
+
+	// Set numbers incremented by random amounts.
+	// Check that what is set is set.
+	// Clear sequentially searching from zero.
+	// Check that what was cleared is not still set.
+	Log::log("\nBitmap Test #1\n");
+
+	for (bitNumber = 0; bitNumber < 20000; bitNumber += rand() % 200)
+		{
+		Log::log("Setting bit %d\n", bitNumber);
+		tester->set(bitNumber);
+		}
+
+	for (int bitNumber = 0; (bitNumber = tester->nextSet(0)) >= 0;)
+		{
+		if (!tester->isSet(bitNumber))
+			Log::log("** Error - %d should be set\n", bitNumber);
+
+		Log::log("Clearing bit %d\n", bitNumber);
+		tester->clear(bitNumber);
+
+		if (tester->isSet(bitNumber))
+			Log::log("** Error - %d is still set\n", bitNumber);
+		}
+
+	for (bitNumber = 0; (bitNumber = tester->nextSet(bitNumber + 1)) >= 0;)
+		Log::log("** Error - bit %d is still set\n", bitNumber);
+
+	tester->clear();
+
+	// Set numbers incremented by large random amounts.
+	// Clear bits after searching from last bit cleard.
+	// Check that all bits are cleared.
+	Log::log("\nBitmap Test #2\n");
+
+	for (bitNumber = 0; bitNumber < 2000000; bitNumber += rand() % 20000)
+		{
+		Log::log("Setting bit %d\n", bitNumber);
+		tester->set(bitNumber);
+		}
+
+	for (int bitNumber = 0; (bitNumber = tester->nextSet(bitNumber)) >= 0;)
+		{
+		Log::log("Clearing bit %d\n", bitNumber);
+		tester->clear(bitNumber);
+		}
+
+	for (bitNumber = 0; (bitNumber = tester->nextSet(bitNumber + 1)) >= 0;)
+		Log::log("** Error - bit %d is still set\n", bitNumber);
+
+	tester->clear();
+
+	// Set numbers incremented by larger random amounts.
+	// Clear bits after searching from random locations.
+	// Finish clearing after searching from zero.
+	// Check that all bits are cleared.
+	Log::log("\nBitmap Test #3\n");
+
+	for (bitNumber = 0; bitNumber < 2000000; bitNumber += rand() % 20000)
+		{
+		Log::log("Setting bit %d\n", bitNumber);
+		tester->set(bitNumber);
+		}
+
+	for (int bitNumber = 0; (bitNumber = tester->nextSet( ((int32) rand() * (int32) rand()) % 1800000)) >= 0;)
+		{
+		Log::log("Clearing bit %d\n", bitNumber);
+			tester->clear(bitNumber);
+		}
+
+	for (int bitNumber = 0; (bitNumber = tester->nextSet(0)) >= 0;)
+		{
+		Log::log("Clearing bit %d\n", bitNumber);
+		tester->clear(bitNumber);
+		}
+
+	for (bitNumber = 0; (bitNumber = tester->nextSet(bitNumber + 1)) >= 0;)
+		Log::log("** Error - bit %d is still set\n", bitNumber);
+
+	tester->clear();
+
+	// Set specific numbers around 1024 and 2048.
+	// Clear bits after searching from last bit cleared.
+	// Check that all bits are cleared.
+	Log::log("\nBitmap Test #4\n");
+	for (bitNumber = 1020; bitNumber <= 1040; bitNumber += 1)
+		{
+		Log::log("Setting bit %d\n", bitNumber);
+		tester->set(bitNumber);
+		}
+
+	for (bitNumber = 2040; bitNumber <= 2060; bitNumber += 1)  // rand() % 1000)
+		{
+		Log::log("Setting bit %d\n", bitNumber);
+		tester->set(bitNumber);
+		}
+
+	for (bitNumber = 0; (bitNumber = tester->nextSet(bitNumber)) >= 0;)
+		{
+		Log::log("Clearing bit %d\n", bitNumber);
+		tester->clear(bitNumber);
+		}
+
+	for (bitNumber = 0; (bitNumber = tester->nextSet(bitNumber + 1)) >= 0;)
+		Log::log("** Error - bit %d is still set \n", bitNumber);
+
+	tester->clear();
+}

=== modified file 'storage/falcon/Bitmap.h'
--- a/storage/falcon/Bitmap.h	2007-09-20 15:44:25 +0000
+++ b/storage/falcon/Bitmap.h	2008-10-16 02:40:08 +0000
@@ -64,6 +64,8 @@ public:
 	void	addRef();
 
 	INTERLOCK_TYPE		count;
+	
+	static void unitTest(void);
 
 protected:
 	void	decompose (int32 number, uint *indexes);

=== modified file 'storage/falcon/Connection.h'
--- a/storage/falcon/Connection.h	2008-02-25 12:17:55 +0000
+++ b/storage/falcon/Connection.h	2008-10-16 02:40:08 +0000
@@ -72,6 +72,7 @@ const int analyzeObjects	= 64;
 const int analyzeSpace		= 128;
 const int analyzeSync		= 256;
 const int analyzeIO			= 512;
+const int analyzeRecordLeafs = 1024;
 
 const int traceBooleans		= 1;
 const int traceTriggers		= 2;

=== modified file 'storage/falcon/Database.cpp'
--- a/storage/falcon/Database.cpp	2008-10-13 21:02:24 +0000
+++ b/storage/falcon/Database.cpp	2008-10-16 02:40:08 +0000
@@ -73,12 +73,14 @@
 #include "MemoryManager.h"
 #include "MemMgr.h"
 #include "RecordScavenge.h"
+#include "RecordSection.h"
 #include "LogStream.h"
 #include "SyncTest.h"
 #include "SyncHandler.h"
 #include "PriorityScheduler.h"
 #include "Sequence.h"
 #include "BackLog.h"
+#include "Bitmap.h"
 
 #ifdef _WIN32
 #define PATH_MAX			_MAX_PATH
@@ -1825,7 +1827,7 @@ void Database::retireRecords(bool forced
 			catch (SQLException &exception)
 				{
 				//syncTbl.unlock();
-				Log::debug ("Exception during scavenger of table %s.%s: %s\n",
+				Log::debug ("Exception during scavenge of table %s.%s: %s\n",
 						table->schemaName, table->name, exception.getText());
 				}
 			}
@@ -2049,6 +2051,30 @@ JString Database::analyze(int mask)
 		stream.putCharacter ('\n');
 		}
 
+	if (mask & analyzeRecordLeafs)
+		{
+		int *chart = new int [RECORD_SLOTS + 1];
+		stream.putSegment ("\nRecordLeafs\n");
+
+		for (Table *table = tableList; table; table = table->next)
+			{
+			memset(chart, 0, sizeof(int) * (RECORD_SLOTS + 1));
+			int count = table->chartActiveRecords(chart);
+
+			if (count)
+				{
+				stream.format ("%s.%s\t%d\t", table->schemaName, table->name, count);
+				for (int a = 0; a < RECORD_SLOTS + 1; a++)
+					if (chart[a])
+						stream.format ("[%d]%d ", a, chart[a]);
+
+				stream.format ("\n");
+				}
+			}
+			
+		stream.putCharacter ('\n');
+		}
+
 	if (mask & analyzeStatements)
 		{
 		stream.putSegment ("\nStatements\n");
@@ -2501,6 +2527,9 @@ void Database::debugTrace(void)
 	if (falcon_debug_trace & FALC0N_FREEZE)
 		Synchronize::freezeSystem();
 	
+	if (falcon_debug_trace & FALC0N_TEST_BITMAP)
+		Bitmap::unitTest();
+
 	falcon_debug_trace = 0;
 #endif
 }

=== modified file 'storage/falcon/Database.h'
--- a/storage/falcon/Database.h	2008-09-03 21:49:18 +0000
+++ b/storage/falcon/Database.h	2008-10-16 01:04:03 +0000
@@ -46,6 +46,7 @@ static const int FALC0N_SYNC_OBJECTS		= 
 static const int FALC0N_FREEZE				= 8;
 static const int FALC0N_REPORT_WRITES		= 16;
 static const int FALC0N_SYNC_HANDLER		= 32;
+static const int FALC0N_TEST_BITMAP			= 64;
 
 #define TABLE_HASH_SIZE		101
 
@@ -305,7 +306,7 @@ public:
 	int					noSchedule;
 	int					pendingIOErrorCode;
 	uint32				serialLogBlockSize;
-	
+
 	volatile INTERLOCK_TYPE	currentGeneration;
 	uint64				recordMemoryMax;
 	uint64				recordScavengeThreshold;

=== modified file 'storage/falcon/Dbb.cpp'
--- a/storage/falcon/Dbb.cpp	2008-08-07 21:11:55 +0000
+++ b/storage/falcon/Dbb.cpp	2008-10-16 02:53:35 +0000
@@ -668,10 +668,10 @@ void Dbb::validate(int optionMask)
 	Validation validation (this, optionMask);
 	validation.inUse ((int32) HEADER_PAGE, "HeaderPage");
 	PageInventoryPage::validate (this, &validation);
-	
+
 	if (inversion)
 		inversion->validate (&validation);
-		
+
 	Section::validateIndexes (this, &validation);
 	Section::validateSections (this, &validation);
 	PageInventoryPage::validateInventory (this, &validation);

=== modified file 'storage/falcon/DeferredIndex.cpp'
--- a/storage/falcon/DeferredIndex.cpp	2008-10-04 00:10:34 +0000
+++ b/storage/falcon/DeferredIndex.cpp	2008-10-16 02:53:35 +0000
@@ -819,7 +819,7 @@ void DeferredIndex::scanIndex(IndexKey *
 void DeferredIndex::detachIndex(void)
 {
 	Sync sync(&syncObject, "DeferredIndex::detachIndex");
-	sync.lock(Exclusive); // was Shared
+	sync.lock(Exclusive); // Do not change while index is in use.
 	index = NULL;
 }
 
@@ -882,8 +882,10 @@ void DeferredIndex::addRef()
 	INTERLOCKED_INCREMENT (useCount);
 }
 
-void DeferredIndex::releaseRef()
+void DeferredIndex::release()
 {
+	ASSERT(useCount > 0);
+
 	if (INTERLOCKED_DECREMENT(useCount) == 0)
 		delete this;
 }

=== modified file 'storage/falcon/DeferredIndex.h'
--- a/storage/falcon/DeferredIndex.h	2008-07-25 18:07:24 +0000
+++ b/storage/falcon/DeferredIndex.h	2008-10-16 02:53:35 +0000
@@ -100,6 +100,8 @@ public:
 	void			initializeSpace(void);
 	DINode*			findMaxValue(void);
 	DINode*			findMinValue(void);
+	void			addRef();
+	void			release();
 
 	SyncObject		syncObject;	
 	volatile INTERLOCK_TYPE useCount;
@@ -124,8 +126,6 @@ public:
 	uint64			virtualOffset;		// virtual offset into the serial log where this DI was flushed.
 	uint64			virtualOffsetAtEnd;
 	SerialLogWindow	*window;
-	void			addRef();
-	void			releaseRef();
 };
 
 #endif

=== modified file 'storage/falcon/DeferredIndexWalker.cpp'
--- a/storage/falcon/DeferredIndexWalker.cpp	2008-09-10 19:51:03 +0000
+++ b/storage/falcon/DeferredIndexWalker.cpp	2008-10-16 02:53:35 +0000
@@ -96,7 +96,7 @@ void DeferredIndexWalker::initialize(Def
 DeferredIndexWalker::~DeferredIndexWalker(void)
 {
 	if (deferredIndex)
-		deferredIndex->releaseRef();
+		deferredIndex->release();
 }
 
 DINode* DeferredIndexWalker::next(void)

=== modified file 'storage/falcon/Index.cpp'
--- a/storage/falcon/Index.cpp	2008-08-19 03:33:01 +0000
+++ b/storage/falcon/Index.cpp	2008-10-16 02:53:35 +0000
@@ -123,6 +123,7 @@ Index::~Index()
 			{
 			ASSERT(deferredIndex->index == this);
 			deferredIndex->detachIndex();
+//			deferredIndex->release();  not currently refCounted;
 			}
 		}
 
@@ -277,6 +278,7 @@ DeferredIndex *Index::getDeferredIndex(T
 	deferredIndex = new DeferredIndex(this, transaction);
 	sync.lock(Exclusive);
 	deferredIndexes.append(deferredIndex);
+//	deferredIndex->addRef() not currently refCounted;
 	sync.unlock();
 	transaction->add(deferredIndex);
 
@@ -843,6 +845,7 @@ void Index::detachDeferredIndex(Deferred
 	Sync sync(&deferredIndexes.syncObject, "Index::detachDeferredIndex(1)");
 	sync.lock(Exclusive);
 	deferredIndexes.remove(deferredIndex);
+//	deferredIndex->release();  not currently refCounted;
 	sync.unlock();
 
 	if (   (database->configuration->useDeferredIndexHash)

=== modified file 'storage/falcon/RecordGroup.cpp'
--- a/storage/falcon/RecordGroup.cpp	2008-03-11 16:15:47 +0000
+++ b/storage/falcon/RecordGroup.cpp	2008-10-16 02:40:08 +0000
@@ -154,6 +154,35 @@ int RecordGroup::countActiveRecords()
 	return count;
 }
 
+bool RecordGroup::anyActiveRecords()
+{
+	for (RecordSection **ptr = records, **end = records + RECORD_SLOTS; ptr < end; ++ptr)
+		{
+		RecordSection *section = *ptr;
+		
+		if (section)
+			if (section->anyActiveRecords())
+				return true;
+		}
+
+	return false;
+}
+
+int RecordGroup::chartActiveRecords(int *chart)
+{
+	int count = 0;
+
+	for (RecordSection **ptr = records, **end = records + RECORD_SLOTS; ptr < end; ++ptr)
+		{
+		RecordSection *section = *ptr;
+		
+		if (section)
+			count += section->chartActiveRecords(chart);
+		}
+
+	return count;
+}
+
 bool RecordGroup::inactive()
 {
 	for (int slot = 0; slot < RECORD_SLOTS; slot++)

=== modified file 'storage/falcon/RecordGroup.h'
--- a/storage/falcon/RecordGroup.h	2007-10-26 21:42:32 +0000
+++ b/storage/falcon/RecordGroup.h	2008-10-16 02:40:08 +0000
@@ -33,16 +33,17 @@ public:
 	RecordGroup(int32 base);
 	virtual ~RecordGroup();
 
-	virtual int		countActiveRecords();
-	virtual bool	store (Record *record, Record *prior, int32 id, RecordSection **parentPtr);
-	virtual void	inventoryRecords(RecordScavenge* recordScavenge);
+	virtual int     countActiveRecords();
+	virtual bool    anyActiveRecords();
+	virtual	int    chartActiveRecords(int *chart);
+	virtual bool    store (Record *record, Record *prior, int32 id, RecordSection **parentPtr);
+	virtual void    inventoryRecords(RecordScavenge* recordScavenge);
 	virtual Record* fetch (int32 id);
-	virtual int		retireRecords(Table *table, int base, RecordScavenge *recordScavenge);
-	virtual bool	retireSections(Table * table, int id);
-	virtual bool	inactive();
+	virtual int     retireRecords(Table *table, int base, RecordScavenge *recordScavenge);
+	virtual bool    retireSections(Table * table, int id);
+	virtual bool    inactive();
 	
-	RecordSection	*records [RECORD_SLOTS];
-	//int32			base;
+	RecordSection   *records [RECORD_SLOTS];
 };
 
 #endif // !defined(AFX_RECORDGROUP_H__02AD6A55_A433_11D2_AB5B_0000C01D2301__INCLUDED_)

=== modified file 'storage/falcon/RecordLeaf.cpp'
--- a/storage/falcon/RecordLeaf.cpp	2008-07-15 18:57:27 +0000
+++ b/storage/falcon/RecordLeaf.cpp	2008-10-16 02:40:08 +0000
@@ -118,7 +118,7 @@ int RecordLeaf::retireRecords (Table *ta
 {
 	int count = 0;
 	Record **ptr, **end;
-	Sync sync(&syncObject, "RecordLeaf::retireRecords(1)");
+	Sync sync(&syncObject, "RecordLeaf::retireRecords(syncObject)");
 	sync.lock(Shared);
 	
 	// Get a shared lock to find at least one record to scavenge
@@ -134,7 +134,7 @@ int RecordLeaf::retireRecords (Table *ta
 				++count;
 			else if (record->isVersion())
 				{
-				Sync syncPrior(record->getSyncPrior(), "RecordLeaf::retireRecords(2)");
+				Sync syncPrior(record->getSyncPrior(), "RecordLeaf::retireRecords(prior)");
 				syncPrior.lock(Shared);
 	
 				if (record->scavenge(recordScavenge, Shared))
@@ -220,7 +220,7 @@ int RecordLeaf::retireRecords (Table *ta
 	// identifier when the leaf node is scavenged later.
 	
 	if (!count && table->emptySections)
-		table->emptySections->set(base * RECORD_SLOTS);
+		table->emptySections->set(base);
 
 	return count;
 }
@@ -232,7 +232,7 @@ bool RecordLeaf::retireSections(Table * 
 
 bool RecordLeaf::inactive()
 {
-	return countActiveRecords() == 0;
+	return (!anyActiveRecords());
 }
 
 int RecordLeaf::countActiveRecords()
@@ -246,6 +246,23 @@ int RecordLeaf::countActiveRecords()
 	return count;
 }
 
+bool RecordLeaf::anyActiveRecords()
+{
+	for (Record **ptr = records, **end = records + RECORD_SLOTS; ptr < end; ++ptr)
+		if (*ptr)
+			return true;
+
+	return false;
+}
+
+int RecordLeaf::chartActiveRecords(int *chart)
+{
+	int count = countActiveRecords();
+	chart[count]++;
+
+	return count;
+}
+
 void RecordLeaf::inventoryRecords(RecordScavenge* recordScavenge)
 {
 	Sync sync(&syncObject, "RecordLeaf::inventoryRecords");

=== modified file 'storage/falcon/RecordLeaf.h'
--- a/storage/falcon/RecordLeaf.h	2007-09-25 05:14:45 +0000
+++ b/storage/falcon/RecordLeaf.h	2008-10-16 02:40:08 +0000
@@ -31,8 +31,10 @@
 class RecordLeaf : public RecordSection  
 {
 public:
-	virtual int countActiveRecords();
-	virtual int retireRecords(Table *table, int id, RecordScavenge *recordScavenge);
+	virtual int  countActiveRecords();
+	virtual bool anyActiveRecords();
+	virtual int  chartActiveRecords(int *chart);
+	virtual int  retireRecords(Table *table, int id, RecordScavenge *recordScavenge);
 	virtual bool retireSections(Table * table, int id);
 	virtual bool inactive();
 	virtual bool store(Record *record, Record *prior, int32 id,RecordSection **parentPtr);

=== modified file 'storage/falcon/RecordSection.h'
--- a/storage/falcon/RecordSection.h	2007-10-26 21:42:32 +0000
+++ b/storage/falcon/RecordSection.h	2008-10-16 02:40:08 +0000
@@ -38,11 +38,13 @@ public:
 	virtual bool inactive() = 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;
+	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;
+	virtual	bool    anyActiveRecords() = false;
+	virtual	int     chartActiveRecords(int *chart) = 0;
 
 	int32			base;
 };

=== modified file 'storage/falcon/RecordVersion.cpp'
--- a/storage/falcon/RecordVersion.cpp	2008-08-27 12:55:46 +0000
+++ b/storage/falcon/RecordVersion.cpp	2008-10-16 02:57:10 +0000
@@ -175,7 +175,6 @@ bool RecordVersion::isVersion()
 void RecordVersion::commit()
 {
 	transaction = NULL;
-	poke();
 }
 
 // Scavenge record versions by the scavenger thread.  Return true if the

=== modified file 'storage/falcon/SRLUpdateIndex.cpp'
--- a/storage/falcon/SRLUpdateIndex.cpp	2008-10-04 00:10:34 +0000
+++ b/storage/falcon/SRLUpdateIndex.cpp	2008-10-16 02:53:35 +0000
@@ -40,25 +40,19 @@ SRLUpdateIndex::~SRLUpdateIndex(void)
 
 void SRLUpdateIndex::append(DeferredIndex* deferredIndex)
 {
-	uint indexId;
-	int idxVersion;
-	int tableSpaceId;
-
-	Sync syncDI(&deferredIndex->syncObject, "SRLUpdateIndex::append");
+	Sync syncDI(&deferredIndex->syncObject, "SRLUpdateIndex::append(DI)");
 	syncDI.lock(Shared);
 
 	if (!deferredIndex->index)
 		return;
-	else
-		{
-		indexId = deferredIndex->index->indexId;
-		idxVersion = deferredIndex->index->indexVersion;
-		tableSpaceId = deferredIndex->index->dbb->tableSpaceId;
-		}
+
+	uint indexId = deferredIndex->index->indexId;
+	int idxVersion = deferredIndex->index->indexVersion;
+	int tableSpaceId = deferredIndex->index->dbb->tableSpaceId;
 
 	syncDI.unlock();
 
-	Sync syncIndexes(&log->syncIndexes, "SRLUpdateIndex::append(1)");
+	Sync syncIndexes(&log->syncIndexes, "SRLUpdateIndex::append(Indexes)");
 	syncIndexes.lock(Shared);
 
 	Transaction *transaction = deferredIndex->transaction;

=== modified file 'storage/falcon/SRLUpdateRecords.cpp'
--- a/storage/falcon/SRLUpdateRecords.cpp	2008-08-27 07:08:18 +0000
+++ b/storage/falcon/SRLUpdateRecords.cpp	2008-10-16 02:53:35 +0000
@@ -247,6 +247,7 @@ void SRLUpdateRecords::append(Transactio
 			log->chilledRecords += chilledRecordsWindow;
 			log->chilledBytes   += chilledBytesWindow;
 			transaction->chilledRecords += chilledRecordsWindow;
+			transaction->chilledBytes += chilledBytesWindow;
 			windowNumber = (uint32)log->writeWindow->virtualOffset / SRL_WINDOW_SIZE;
 			}
 		} // next window

=== modified file 'storage/falcon/Scavenger.cpp'
--- a/storage/falcon/Scavenger.cpp	2007-09-20 15:44:25 +0000
+++ b/storage/falcon/Scavenger.cpp	2008-10-16 02:53:35 +0000
@@ -32,10 +32,10 @@
 // Construction/Destruction
 //////////////////////////////////////////////////////////////////////
 
-Scavenger::Scavenger (Database *db, ScavengeType scavengeType, const char *schedule) : Schedule (schedule)
+Scavenger::Scavenger (Database *db, ScavengerType scavengerType, const char *schedule) : Schedule (schedule)
 {
 	database = db;
-	type = scavengeType;
+	type = scavengerType;
 }
 
 Scavenger::~Scavenger()

=== modified file 'storage/falcon/Scavenger.h'
--- a/storage/falcon/Scavenger.h	2007-09-20 15:44:25 +0000
+++ b/storage/falcon/Scavenger.h	2008-10-16 02:53:35 +0000
@@ -26,7 +26,7 @@
 
 #include "Schedule.h"
 
-enum ScavengeType {
+enum ScavengerType {
 	scvRecords,
 	scvJava,
 	};
@@ -38,13 +38,13 @@ class Scavenger : public Schedule 
 public:
 	virtual void execute (Scheduler *scheduler);
 	void scavenge();
-	Scavenger(Database *db, ScavengeType scavengeType, const char *schedule);
+	Scavenger(Database *db, ScavengerType scavengerType, const char *schedule);
 
 protected:
 	virtual ~Scavenger();
 
 	Database		*database;
-	ScavengeType	type;
+	ScavengerType	type;
 };
 
 #endif // !defined(AFX_SCAVENGER_H__9E139FC3_1F3E_11D3_AB74_0000C01D2301__INCLUDED_)

=== modified file 'storage/falcon/SerialLogFile.cpp'
--- a/storage/falcon/SerialLogFile.cpp	2008-10-14 13:00:31 +0000
+++ b/storage/falcon/SerialLogFile.cpp	2008-10-16 02:53:35 +0000
@@ -128,7 +128,7 @@ void SerialLogFile::open(JString filenam
 	
 
 	if (create)
-		handle = ::open(filename, O_RDWR | O_BINARY | O_CREAT|O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+		handle = ::open(filename, O_RDWR | O_BINARY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
 	else
 		handle = ::open(filename, O_RDWR | O_BINARY);
 

=== modified file 'storage/falcon/StorageDatabase.cpp'
--- a/storage/falcon/StorageDatabase.cpp	2008-08-18 20:17:15 +0000
+++ b/storage/falcon/StorageDatabase.cpp	2008-10-16 02:53:35 +0000
@@ -491,7 +491,7 @@ int StorageDatabase::nextIndexed(Storage
 	
 	return record->recordNumber;
 }
-
+/*
 RecordVersion* StorageDatabase::lockRecord(StorageConnection* storageConnection, Table *table, Record* record)
 {
 	try
@@ -505,7 +505,7 @@ RecordVersion* StorageDatabase::lockReco
 		return NULL;
 		}
 }
-
+*/
 int StorageDatabase::savepointSet(Connection* connection)
 {
 	Transaction *transaction = connection->getTransaction();

=== modified file 'storage/falcon/StorageDatabase.h'
--- a/storage/falcon/StorageDatabase.h	2008-08-18 05:45:29 +0000
+++ b/storage/falcon/StorageDatabase.h	2008-10-16 02:53:35 +0000
@@ -81,7 +81,7 @@ public:
 	int					nextIndexed(StorageTable *storageTable, void* recordBitmap, int recordNumber, bool lockForUpdate);
 	int					nextIndexed(StorageTable* storageTable, IndexWalker* indexWalker, bool lockForUpdate);
 	int					fetch(StorageConnection* storageConnection, StorageTable* storageTable, int recordNumber, bool lockForUpdate);
-	RecordVersion*		lockRecord(StorageConnection* storageConnection, Table *table, Record* record);
+//	RecordVersion*		lockRecord(StorageConnection* storageConnection, Table *table, Record* record);
 	
 	int					updateRow(StorageConnection* storageConnection, Table* table, Record *oldRecord, Stream* stream);
 	int					getSegmentValue(StorageSegment* segment, const UCHAR* ptr, Value* value, Field *field);

=== modified file 'storage/falcon/SyncHandler.cpp'
--- a/storage/falcon/SyncHandler.cpp	2008-09-03 21:49:18 +0000
+++ b/storage/falcon/SyncHandler.cpp	2008-10-16 02:59:09 +0000
@@ -143,7 +143,7 @@ SyncHandler::~SyncHandler(void)
 #endif
 }
 
-void SyncHandler::addLock(SyncObject *syncObj, const char* locationName)
+void SyncHandler::addLock(SyncObject *syncObj, const char* locationName, LockType type)
 {
 #ifdef USE_FALCON_SYNC_HANDLER
 	if (syncObj == &syncObject)
@@ -158,7 +158,7 @@ void SyncHandler::addLock(SyncObject *sy
 
 	SyncThreadInfo *thd = addThread(thread->threadId);
 	SyncObjectInfo *soi = addSyncObject(syncObj->getName());
-	SyncLocationInfo *loc = addLocation(locationName, soi);
+	SyncLocationInfo *loc = addLocation(locationName, soi, type);
 
 	addToThread(thd, loc);
 #endif
@@ -297,29 +297,31 @@ void SyncHandler::showSyncObjects(void)
 			Log::debug("  %s\n", soi->name);
 }
 
-SyncLocationInfo *SyncHandler::findLocation(const char* locationName, int slot)
+SyncLocationInfo *SyncHandler::findLocation(const char* locationName, LockType type, int slot)
 {
 	for (SyncLocationInfo *loc = locations[slot]; loc; loc = loc->collision)
 		{
-		if (loc->name == locationName)
+		if ((loc->name == locationName) && (loc->type == type))
 			return loc;
 		}
 
 	return NULL;
 }
-SyncLocationInfo *SyncHandler::addLocation(const char* locationName, SyncObjectInfo *soi)
+
+SyncLocationInfo *SyncHandler::addLocation(const char* locationName, SyncObjectInfo *soi, LockType type)
 {
 	ASSERT(locationName != NULL);
 	ASSERT(strlen(locationName) != 0);
 
 	int slot = JString::hash(locationName, locationHashSize);
-	SyncLocationInfo *loc = findLocation(locationName, slot);
+	SyncLocationInfo *loc = findLocation(locationName, type, slot);
 
 	if (!loc)
 		{
 		loc = new SyncLocationInfo;
 		loc->name = locationName;
 		loc->soi = soi;
+		loc->type = type;
 		loc->collision = locations[slot];
 		locations[slot] = loc;
 		if ((++locationCount % 100) == 0)
@@ -339,10 +341,9 @@ void SyncHandler::showLocations(void)
 
 	for (int slot = 0; slot < locationHashSize; slot++)
 		for (SyncLocationInfo *loc = locations[slot]; loc; loc = loc->collision)
-			Log::debug("  %s\t%s\n", loc->name, loc->soi->name);
+			Log::debug("  %s\t%s\t%s\n", loc->name, loc->soi->name, (loc->type == Exclusive ? "Exclusive" : "Shared"));
 }
 
-
 void SyncHandler::addToThread(SyncThreadInfo* thd, SyncLocationInfo *loc)
 {
 	// Be sure this soi is only recorded once.
@@ -476,19 +477,34 @@ void SyncHandler::showLocationStacks(voi
 
 	for (int slot = 0; slot < stackHashSize; slot++)
 		for (LocationStackInfo *lsi = locationStacks[slot]; lsi; lsi = lsi->collision)
-			{
-			int stackHeight = 0;
-			stackCount++;
-			for (int n = 0; n < lsi->height - 1; n++)
-				Log::debug("  %4d-%03d; %s (%s) ->\n", 
-				           stackCount, ++stackHeight, 
-				           lsi->loc[n]->name, lsi->loc[n]->soi->name);
-
-			Log::debug("  %4d-%03d; %s (%s)\n\n", 
-			           stackCount, ++stackHeight, 
-			           lsi->loc[lsi->height - 1]->name, 
-			           lsi->loc[lsi->height - 1]->soi->name);
-			}
+			showLocationStack(lsi);
+}
+
+void SyncHandler::showLocationStack(int stackNum)
+{
+	for (int slot = 0; slot < stackHashSize; slot++)
+		for (LocationStackInfo *lsi = locationStacks[slot]; lsi; lsi = lsi->collision)
+			if (lsi->count == stackNum)
+				{
+				showLocationStack(lsi);
+				return;
+				}
+}
+
+void SyncHandler::showLocationStack(LocationStackInfo *lsi)
+{
+	int stackHeight = 0;
+	for (int n = 0; n < lsi->height - 1; n++)
+		Log::debug("  %4d-%03d; %s (%s) - %s ->\n", 
+		           lsi->count, ++stackHeight, 
+		           lsi->loc[n]->name, lsi->loc[n]->soi->name,
+		          (lsi->loc[n]->type == Exclusive ? "Exclusive" : "Shared"));
+
+	Log::debug("  %4d-%03d; %s (%s) - %s\n\n", 
+	           lsi->count, ++stackHeight, 
+	           lsi->loc[lsi->height - 1]->name, 
+	           lsi->loc[lsi->height - 1]->soi->name,
+	          (lsi->loc[lsi->height - 1]->type == Exclusive ? "Exclusive" : "Shared"));
 }
 
 DeadlockInfo* SyncHandler::findDeadlock(DeadlockInfo* dli, int slot)
@@ -527,12 +543,10 @@ void SyncHandler::validate(void)
 			{
 			// Make a list of all SyncObjects that must occur before and after and this.
 
-			SyncObjectInfo *before[1000];
-			memset(before, 0, sizeof(before));
+			memset(soi->beforeList, 0, sizeof(soi->beforeList));
 			int beforeCount = 0;
 
-			SyncObjectInfo *after[1000];
-			memset(after, 0, sizeof(after));
+			memset(soi->afterList, 0, sizeof(soi->afterList));
 			int afterCount = 0;
 
 			// search each location stack for this soi, make a list of
@@ -544,29 +558,35 @@ void SyncHandler::validate(void)
 					for (c = 0; c < lsi->height; c++)
 						if (soi == lsi->loc[c]->soi)
 							{
+
+							// Record the SyncObjects that occur before this
+
 							for (d = 0; d < c; d++) 
 								{
 								for (e = 0; e < beforeCount; e++)
-									if (before[e] == lsi->loc[d]->soi)
+									if (soi->beforeList[e] == lsi->loc[d]->soi)
 										break;
 
 								if (e == beforeCount)
-									before[beforeCount++] = lsi->loc[d]->soi;
+									soi->beforeList[beforeCount++] = lsi->loc[d]->soi;
 
 								ASSERT(lsi->loc[d]->soi);
-								ASSERT(beforeCount < 1000);
+								ASSERT(beforeCount < beforeAfterSize);
 								}
+
+							// Record the SyncObjects that occur after this
+
 							for (d = c + 1; d < lsi->height; d++)
 								{
 								for (e = 0; e < afterCount; e++)
-									if (after[e] == lsi->loc[d]->soi)
+									if (soi->afterList[e] == lsi->loc[d]->soi)
 										break;
 
 								if (e == afterCount)
-									after[afterCount++] = lsi->loc[d]->soi;
+									soi->afterList[afterCount++] = lsi->loc[d]->soi;
 
 								ASSERT(lsi->loc[d]->soi);
-								ASSERT(afterCount < 1000);
+								ASSERT(afterCount < beforeAfterSize);
 								}
 							}
 					}
@@ -574,10 +594,85 @@ void SyncHandler::validate(void)
 			// Make sure none of the SyncObjects in before are also in after.
 
 			for (b = 0; b < beforeCount; b++)
-				if (soi != before[b])
+				if (soi != soi->beforeList[b])
 					for (c = 0; c < afterCount; c++)
-						if (before[b] == after[c])
-							addPossibleDeadlock(soi, after[c]);
+						if (soi->beforeList[b] == soi->afterList[c])
+							addPossibleDeadlock(soi, soi->afterList[c]);
+			}
+
+	// Refine the list of possible deadlocks
+	// The second SOI  was found before and after the first.
+	// But if that happened on the same stack,  it is OK as long as
+	// the two calls do not go from shared up to exclusive.
+	for (a = 0; a < deadlockHashSize; a++)
+		for (DeadlockInfo *dli = possibleDeadlocks[a]; dli; dli = dli->collision)
+			{
+			bool foundBothInOneStack = false;
+			bool foundOneBeforeTwo = false;
+			bool foundTwoBeforeOne = false;
+			bool foundRisingLock = false;
+
+			for (b = 0; b < stackHashSize; b++)
+				for (LocationStackInfo *lsi = locationStacks[b]; lsi; lsi = lsi->collision)
+					{
+					int firstOneNum = 0;
+					int lastOneNum = 0;
+					int firstTwoNum = 0;
+					int lastTwoNum = 0;
+					
+					for (c = 0; c < lsi->height; c++)
+						{
+						if (dli->soi[0] == lsi->loc[c]->soi)
+							if (firstOneNum)
+								{
+								lastOneNum = c + 1;
+								if (   (lsi->loc[firstOneNum - 1]->type == Shared) 
+									&& (lsi->loc[c]->type == Exclusive))
+									{
+									foundRisingLock = true;
+									lsi->hasRisingLockTypes = true;
+									}
+								}
+							else
+								firstOneNum = c + 1;
+
+						else if (dli->soi[1] == lsi->loc[c]->soi)
+							if (firstTwoNum)
+								{
+								lastTwoNum = c + 1;
+								if (   (lsi->loc[firstTwoNum - 1]->type == Shared) 
+									&& (lsi->loc[c]->type == Exclusive))
+									{
+									foundRisingLock = true;
+									lsi->hasRisingLockTypes = true;
+									}
+								}
+							else
+								firstTwoNum = c + 1;
+						}
+
+					if (firstOneNum && firstTwoNum)
+						{
+						if (firstOneNum < lastTwoNum && lastTwoNum < lastOneNum)
+							foundBothInOneStack = true;
+						else if (firstTwoNum < lastOneNum && lastOneNum < lastTwoNum)
+							foundBothInOneStack = true;
+						else if (firstOneNum < firstTwoNum)
+							foundOneBeforeTwo = true;
+						else if (firstTwoNum < firstOneNum)
+							foundTwoBeforeOne = true;
+
+						}
+					}
+
+			// Is this still a possible deadlock?
+			if (   foundBothInOneStack 
+				&& !(foundOneBeforeTwo && foundTwoBeforeOne) 
+				&& !foundRisingLock)
+				{
+				// Take this possible deadlock out of the list.
+				removePossibleDeadlock(dli);
+				}
 			}
 }
 
@@ -591,6 +686,7 @@ void SyncHandler::addPossibleDeadlock(Sy
 
 	dli->soi[0] = soi1;
 	dli->soi[1] = soi2;
+	dli->isPossible = true;
 
 	// Now calulate the hash number and slot.  
 	// This hash algorithm must return the same slot for two SyncObjectInfo *
@@ -614,50 +710,98 @@ void SyncHandler::addPossibleDeadlock(Sy
 	delete dli;
 }
 
+void SyncHandler::removePossibleDeadlock(DeadlockInfo* dli)
+{
+	int slot = dli->hash % deadlockHashSize;
+
+	for (DeadlockInfo* stack = possibleDeadlocks[slot]; stack; stack = stack->collision)
+		{
+		if (stack == dli)
+			dli->isPossible = false;
+		}
+}
+
 #define FOUND_FIRST 1
 #define FOUND_SECOND 2
 #define FOUND_BOTH 3
+#define ONE_TWO 1
+#define TWO_ONE 2
 void SyncHandler::showPossibleDeadlockStacks(void)
 {
-	int a,b,c;
+	int a;
 	int possibleDeadlockCount = 0;
 	for (a = 0; a < deadlockHashSize; a++)
 		for (DeadlockInfo *dli = possibleDeadlocks[a]; dli; dli = dli->collision)
-			possibleDeadlockCount++;
+			if (dli->isPossible)
+				possibleDeadlockCount++;
 
 	Log::debug("\n== SyncHandler has found %d possible deadlocks ==\n", possibleDeadlockCount);
 
 	for (a = 0; a < deadlockHashSize; a++)
 		for (DeadlockInfo *dli = possibleDeadlocks[a]; dli; dli = dli->collision)
-			{
-			int stackCount = 0;
-			Log::debug("\n=== Possible Deadlock;  %s and %s ===\n    Stacks =", dli->soi[0]->name, dli->soi[1]->name);
+			if (dli->isPossible)
+				{
+				Log::debug("\n=== Possible Deadlock===\n");
+				showPossibleDeadlockStack(dli, ONE_TWO);
+				showPossibleDeadlockStack(dli, TWO_ONE);
+				}
+}
+
+void SyncHandler::showPossibleDeadlockStack(DeadlockInfo *dli, int showOrder)
+{
+	LocationStackInfo *sampleLsi1 = NULL;
+	LocationStackInfo *sampleLsi2 = NULL;
+	int stackCount = 0;
+	if (showOrder == ONE_TWO)
+		Log::debug("  %s before %s\n", dli->soi[0]->name, dli->soi[1]->name);
+	else
+		Log::debug("  %s before %s\n", dli->soi[1]->name, dli->soi[0]->name);
 
-			// Reference all call stacks with these two SyncObjects.
+	// Find call stacks containing these two SyncObjects.
 
-			for (b = 0; b < stackHashSize; b++)
-				for (LocationStackInfo *lsi = locationStacks[b]; lsi; lsi = lsi->collision)
-					{
-					// Does this location stack have both SyncObjects?
+	for (int b = 0; b < stackHashSize; b++)
+		for (LocationStackInfo *lsi = locationStacks[b]; lsi; lsi = lsi->collision)
+			{
+			// Does this location stack have both SyncObjects?
 
-					int numFound = 0;
-					for (c = 0; c < lsi->height; c++)
-						{
-						if (lsi->loc[c]->soi == dli->soi[0])
-							numFound |= FOUND_FIRST;
-						else if (lsi->loc[c]->soi == dli->soi[1])
-							numFound |= FOUND_SECOND;
-						}
+			int numFound = 0;
+			int order = 0;
+			for (int c = 0; c < lsi->height; c++)
+				{
+				if (lsi->loc[c]->soi == dli->soi[0])
+					{
+					numFound |= FOUND_FIRST;
+					if (!order)
+						order = ONE_TWO;
+					}
+				else if (lsi->loc[c]->soi == dli->soi[1])
+					{
+					numFound |= FOUND_SECOND;
+					if (!order)
+						order = TWO_ONE;
+					}
+				}
 
-					if (numFound == FOUND_BOTH)
-						{
-						if (stackCount && ((stackCount % 10) == 0))
-							Log::debug("\n   ");
-						stackCount++;
-						Log::debug(" %d", lsi->count);
-						}
+			if ( (numFound == FOUND_BOTH) && (order == showOrder) )
+				{
+				if (stackCount == 0)
+					{
+					sampleLsi1 = lsi;
+					Log::debug("  Stacks =", dli->soi[0]->name, dli->soi[1]->name);
 					}
-			Log::debug("\n");
+				else if ((stackCount % 10) == 0)
+					Log::debug("\n   ");
+
+				stackCount++;
+				Log::debug(" %d", lsi->count);
+				sampleLsi2 = lsi;
+				}
 			}
+
+	Log::debug("\n");
+	if (sampleLsi1)
+		showLocationStack(sampleLsi1);
+	if (sampleLsi2)
+		showLocationStack(sampleLsi2);
 }
 #endif

=== modified file 'storage/falcon/SyncHandler.h'
--- a/storage/falcon/SyncHandler.h	2008-09-03 21:49:18 +0000
+++ b/storage/falcon/SyncHandler.h	2008-10-16 02:59:09 +0000
@@ -28,6 +28,7 @@ static const int locationHashSize = 503;
 static const int threadHashSize = 100;
 static const int stackHashSize = 1000;
 static const int deadlockHashSize = 100;
+static const int beforeAfterSize = 60;
 static const int syncStackSize = 20;
 
 struct SyncObjectInfo
@@ -36,6 +37,10 @@ struct SyncObjectInfo
 	SyncObjectInfo *prev;
 	SyncObjectInfo *next;
 	SyncObjectInfo *collision;
+	SyncObjectInfo *beforeList[beforeAfterSize];
+	SyncObjectInfo *afterList[beforeAfterSize];
+	SyncObjectInfo *before;
+	SyncObjectInfo *after;
 	bool multiple;
 };
 
@@ -43,6 +48,7 @@ struct SyncLocationInfo
 {
 	JString name;
 	SyncObjectInfo *soi;
+	LockType type;
 	SyncLocationInfo *collision;
 };
 
@@ -61,6 +67,7 @@ struct LocationStackInfo
 	int height;
 	int hash;
 	int count;
+	bool hasRisingLockTypes;
 	LocationStackInfo *collision;
 };
 
@@ -68,6 +75,7 @@ struct DeadlockInfo
 {
 	SyncObjectInfo *soi[2];
 	int hash;
+	bool isPossible;
 	DeadlockInfo *collision;
 };
 
@@ -84,7 +92,7 @@ public:
 	SyncHandler(void);
 	virtual ~SyncHandler(void);
 
-	void	addLock(SyncObject *syncObj, const char *locationName);
+	void	addLock(SyncObject *syncObj, const char *locationName, LockType type);
 	void	delLock(SyncObject *syncObj);
 	void	dump(void);
 
@@ -98,12 +106,14 @@ private:
 	SyncObjectInfo *	findSyncObject(const char* syncObjectName, int slot);
 	SyncObjectInfo *	addSyncObject(const char* syncObjectName);
 	void				showSyncObjects(void);
-	SyncLocationInfo *	findLocation(const char* locationName, int slot);
-	SyncLocationInfo *	addLocation(const char* locationName, SyncObjectInfo *soi);
+	SyncLocationInfo *	findLocation(const char* locationName, LockType type, int slot);
+	SyncLocationInfo *	addLocation(const char* locationName, SyncObjectInfo *soi, LockType type);
 	void				showLocations(void);
 	LocationStackInfo *	findStack(LocationStackInfo* stk, int slot);
 	void				addStack(SyncThreadInfo* thd);
 	void				showLocationStacks(void);
+	void				showLocationStack(int stackNum);
+	void				showLocationStack(LocationStackInfo *lsi);
 	void				countLocationStacks(void);
 
 	DeadlockInfo *		findDeadlock(DeadlockInfo* dli, int slot);
@@ -113,7 +123,9 @@ private:
 
 	void				validate(void);
 	void				addPossibleDeadlock(SyncObjectInfo *soi1, SyncObjectInfo *soi2);
+	void				removePossibleDeadlock(DeadlockInfo* dli);
 	void				showPossibleDeadlockStacks(void);
+	void				showPossibleDeadlockStack(DeadlockInfo *dli, int showOrder);
 
 	SyncObject			syncObject;
 

=== modified file 'storage/falcon/SyncObject.cpp'
--- a/storage/falcon/SyncObject.cpp	2008-09-03 21:49:18 +0000
+++ b/storage/falcon/SyncObject.cpp	2008-10-16 02:59:09 +0000
@@ -148,7 +148,7 @@ void SyncObject::lock(Sync *sync, LockTy
 #ifdef USE_FALCON_SYNC_HANDLER
 	SyncHandler *syncHandler = getFalconSyncHandler();
 	if (sync && syncHandler)
-		syncHandler->addLock(this, location);
+		syncHandler->addLock(this, location, type);
 #endif
 #endif
 
@@ -320,7 +320,7 @@ void SyncObject::lock(Sync *sync, LockTy
 #ifdef USE_FALCON_SYNC_HANDLER
 	SyncHandler *syncHandler = getFalconSyncHandler();
 	if (sync && syncHandler)
-		syncHandler->addLock(this, location);
+		syncHandler->addLock(this, location, type);
 #endif
 #endif
 

=== modified file 'storage/falcon/Table.cpp'
--- a/storage/falcon/Table.cpp	2008-10-03 23:56:24 +0000
+++ b/storage/falcon/Table.cpp	2008-10-16 02:53:35 +0000
@@ -162,6 +162,9 @@ Table::~Table()
 
 	if (recordBitmap)
 		recordBitmap->release();
+
+	if (emptySections)
+		emptySections->release();
 }
 
 Field* Table::findField(const char * fieldName)
@@ -1875,7 +1878,7 @@ int Table::retireRecords(RecordScavenge 
 		syncObj.lock(Exclusive);
 
 		// Confirm that tree is still empty
-		
+
 		count = records->countActiveRecords();
 
 		if (count == 0)
@@ -1888,16 +1891,17 @@ int Table::retireRecords(RecordScavenge 
 		{
 		// Get an exclusive lock only if there are empty leaf nodes. Find and
 		// delete the empty nodes using the stored record numbers as identifiers.
-		
+
 		if (emptySections->count > 0)
 			{
 			syncObj.unlock();
 			syncObj.lock(Exclusive);
 
-			for (int recordNumber = 0; (recordNumber = emptySections->nextSet(recordNumber)) >= 0;)
+			for (int sectionNumber = 0; (sectionNumber = emptySections->nextSet(0)) >= 0;)
 				{
+				int recordNumber = sectionNumber * RECORD_SLOTS;
 				records->retireSections(this, recordNumber);
-				emptySections->clear(recordNumber);
+				emptySections->clear(sectionNumber);
 				}
 				
 			}
@@ -2117,10 +2121,10 @@ void Table::garbageCollect(Record *leavi
 	if (!leaving && !staying)
 		return;
 
-	Sync sync (&syncObject, "Table::garbageCollect(1)");
+	Sync sync (&syncObject, "Table::garbageCollect(Obj)");
 	sync.lock(Shared);
 	
-	Sync syncPrior(getSyncPrior(leaving ? leaving : staying), "Table::garbageCollect(2)");
+	Sync syncPrior(getSyncPrior(leaving ? leaving : staying), "Table::garbageCollect(prior)");
 	syncPrior.lock(Shared);
 	
 	// Clean up field indexes
@@ -2770,6 +2774,17 @@ int Table::countActiveRecords()
 	return records->countActiveRecords();
 }
 
+int Table::chartActiveRecords(int *chart)
+{
+	Sync sync(&syncObject, "Table::countActiveRecords");
+	sync.lock(Shared);
+
+	if (!records)
+		return 0;
+
+	return records->chartActiveRecords(chart);
+}
+
 void Table::rebuildIndex(Index *index, Transaction *transaction)
 {
 	index->rebuildIndex(transaction);
@@ -3364,7 +3379,7 @@ void Table::waitForWriteComplete()
 {
 	database->waitForWriteComplete(this);
 }
-
+/*
 RecordVersion* Table::lockRecord(Record* record, Transaction* transaction)
 {
 	Record *current = fetch(record->recordNumber);
@@ -3411,7 +3426,7 @@ RecordVersion* Table::lockRecord(Record*
 		}
 	
 	return recordVersion;	
-}
+}   */
 
 void Table::unlockRecord(int recordNumber)
 {

=== modified file 'storage/falcon/Table.h'
--- a/storage/falcon/Table.h	2008-08-18 05:45:29 +0000
+++ b/storage/falcon/Table.h	2008-10-16 02:53:35 +0000
@@ -99,6 +99,7 @@ public:
 	void		rebuildIndex (Index *index, Transaction *transaction);
 	int			retireRecords (RecordScavenge *recordScavenge);
 	int			countActiveRecords();
+	int			chartActiveRecords(int *chart);
 	bool		foreignKeyMember (ForeignKey *key);
 	void		makeNotSearchable (Field *field, Transaction *transaction);
 	bool		dropForeignKey (int fieldCount, Field **fields, Table *references);
@@ -204,7 +205,7 @@ public:
 	void			inventoryRecords(RecordScavenge* recordScavenge);
 	Format*			getCurrentFormat(void);
 	Record*			fetchForUpdate(Transaction* transaction, Record* record, bool usingIndex);
-	RecordVersion*	lockRecord(Record* record, Transaction* transaction);
+//	RecordVersion*	lockRecord(Record* record, Transaction* transaction);
 	void			unlockRecord(int recordNumber);
 	void			unlockRecord(RecordVersion* record, bool remove);
 

=== modified file 'storage/falcon/Transaction.cpp'
--- a/storage/falcon/Transaction.cpp	2008-10-10 18:42:44 +0000
+++ b/storage/falcon/Transaction.cpp	2008-10-16 02:53:35 +0000
@@ -397,7 +397,7 @@ void Transaction::rollback()
 	// Rollback pending record versions from newest to oldest in case
 	// there are multiple record versions on a prior record chain
 
-	Sync syncRec(&syncRecords, "Transaction::rollback(1.5)");
+	Sync syncRec(&syncRecords, "Transaction::rollback(records)");
 	syncRec.lock(Exclusive);
 
 	while (firstRecord)
@@ -451,7 +451,7 @@ void Transaction::rollback()
 		xidLength = 0;
 		}
 	
-	Sync syncActiveTransactions (&transactionManager->activeTransactions.syncObject, "Transaction::rollback(2)");
+	Sync syncActiveTransactions (&transactionManager->activeTransactions.syncObject, "Transaction::rollback(active)");
 	syncActiveTransactions.lock (Exclusive);
 	++transactionManager->rolledBack;
 	
@@ -1494,7 +1494,7 @@ void Transaction::releaseDeferredIndexes
 		ASSERT(deferredIndex->transaction == this);
 		deferredIndexes = deferredIndex->nextInTransaction;
 		deferredIndex->detachTransaction();
-		deferredIndex->releaseRef();
+		deferredIndex->release();
 		deferredIndexCount--;
 		}
 }
@@ -1510,7 +1510,7 @@ void Transaction::releaseDeferredIndexes
 			{
 			*ptr = deferredIndex->nextInTransaction;
 			deferredIndex->detachTransaction();
-			deferredIndex->releaseRef();
+			deferredIndex->release();
 			--deferredIndexCount;
 			}
 		else

=== modified file 'storage/falcon/TransactionManager.cpp'
--- a/storage/falcon/TransactionManager.cpp	2008-08-25 21:51:46 +0000
+++ b/storage/falcon/TransactionManager.cpp	2008-10-16 02:53:35 +0000
@@ -291,7 +291,7 @@ void TransactionManager::purgeTransactio
 	Sync syncCommitted(&committedTransactions.syncObject, "Transaction::purgeTransactions");
 	syncCommitted.lock(Exclusive);
 	
-	// And, while we're at it, check for any fully mature transactions to ditch
+	// Check for any fully mature transactions to ditch
 	
 	for (Transaction *transaction, *next = committedTransactions.first; (transaction = next);)
 		{

=== modified file 'storage/falcon/WalkDeferred.cpp'
--- a/storage/falcon/WalkDeferred.cpp	2008-07-25 18:07:24 +0000
+++ b/storage/falcon/WalkDeferred.cpp	2008-10-16 02:53:35 +0000
@@ -26,7 +26,7 @@ WalkDeferred::WalkDeferred(DeferredIndex
 
 WalkDeferred::~WalkDeferred(void)
 {
-	deferredIndex->releaseRef();
+	deferredIndex->release();
 }
 
 Record* WalkDeferred::getNext(bool lockForUpdate)

=== modified file 'storage/falcon/ha_falcon.cpp'
--- a/storage/falcon/ha_falcon.cpp	2008-10-14 13:00:31 +0000
+++ b/storage/falcon/ha_falcon.cpp	2008-10-16 02:53:35 +0000
@@ -1277,7 +1277,7 @@ int StorageInterface::start_consistent_s
 {
 	DBUG_ENTER("StorageInterface::start_consistent_snapshot");
 	int ret = storageHandler->startTransaction(thd, TRANSACTION_CONSISTENT_READ);
- 	if (!ret)
+	if (!ret)
 		trans_register_ha(thd, true, hton);
 	DBUG_RETURN(ret);
 

=== modified file 'storage/falcon/ha_falcon.h'
--- a/storage/falcon/ha_falcon.h	2008-09-16 17:58:49 +0000
+++ b/storage/falcon/ha_falcon.h	2008-10-16 02:53:35 +0000
@@ -176,12 +176,12 @@ public:
 	StorageConnection*	storageConnection;
 	StorageTable*		storageTable;
 	StorageTableShare*	storageShare;
-	Field				**fieldMap;
+	Field					**fieldMap;
 	const char*			errorText;
 	THR_LOCK_DATA		lockData;			// MySQL lock
 	THD					*mySqlThread;
-	TABLE_SHARE *share;
-	uint				recordLength;
+	TABLE_SHARE			*share;
+	uint					recordLength;
 	int					lastRecord;
 	int					nextRecord;
 	int					indexErrorId;
@@ -189,12 +189,12 @@ public:
 	int					maxFields;
 	StorageBlob			*activeBlobs;
 	StorageBlob			*freeBlobs;
-	bool				haveStartKey;
-	bool				haveEndKey;
-	bool				tableLocked;
-	bool				tempTable;
-	bool				lockForUpdate;
-	bool				indexOrder;
+	bool					haveStartKey;
+	bool					haveEndKey;
+	bool					tableLocked;
+	bool					tempTable;
+	bool					lockForUpdate;
+	bool					indexOrder;
 	key_range			startKey;
 	key_range			endKey;
 	uint64				insertCount;

Thread
bzr push into mysql-6.0-falcon-team branch (klewis:2865 to 2869) Bug#39672Kevin Lewis16 Oct