List:Commits« Previous MessageNext Message »
From:vvaintroub Date:March 28 2008 7:40am
Subject:bk commit into 6.0 tree (vvaintroub:1.2608) WL#3763
View as plain text  
Below is the list of changes that have just been committed into a local
6.0 repository of vvaintroub.  When vvaintroub 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, 2008-03-28 07:40:07+01:00, vvaintroub@wva. +2 -0
  WL#3763: Supernodes
  - If insert is done in decreasing order of values, no supernodes were 
  created. Now fixed - if index node is inserted at the start 
  of the page, next node can become supernode, if the gap between the 
  start of the page and first supernode is too large.
  - Allow supernode on duplicate keys.
  - Do not always delete supernode if previous node is deleted, but check
    whether saving it makes sense.

  storage/falcon/IndexPage.cpp@stripped, 2008-03-28 07:40:03+01:00, vvaintroub@wva. +76 -40
    - If insert is done in decreasing order of values, no supernodes were 
    created. Now fixed - if index node is inserted at the start 
    of the page, next node can become supernode, if the gap between the 
    start of the page and first supernode is too large.
    - Allow supernode on duplicate keys.
    - Do not always delete supernode if previous node is deleted, but check
      whether saving it makes sense.

  storage/falcon/IndexPage.h@stripped, 2008-03-28 07:40:03+01:00, vvaintroub@wva. +1 -1
    checkAddSuperNode got an additional parameter, to indicate that node 
    *after* insertion point shall be made supernode. 

diff -Nrup a/storage/falcon/IndexPage.cpp b/storage/falcon/IndexPage.cpp
--- a/storage/falcon/IndexPage.cpp	2008-03-22 15:52:15 +01:00
+++ b/storage/falcon/IndexPage.cpp	2008-03-28 07:40:03 +01:00
@@ -41,6 +41,9 @@
 static const char THIS_FILE[]=__FILE__;
 #endif
 
+// Do not make supernode, if there is too much loss for prefix compression
+#define SUPERNODE_COMPRESSION_LOSS_LIMIT(pageSize) (pageSize)/(SUPERNODES+1)/2
+
 //////////////////////////////////////////////////////////////////////
 // Construction/Destruction
 //////////////////////////////////////////////////////////////////////
@@ -87,8 +90,9 @@ AddNodeResult IndexPage::addNode (Dbb *d
 	int offset1 = computePrefix (priorKey, indexKey);
 
 	// Check whether inserted node shall be supernode. If yes, does not compress the prefix.
-	bool addSuper = checkAddSuperNode(dbb->pageSize, node, indexKey, recordNumber, offset1);
-	if (addSuper)
+	bool makeNextSuper;
+	bool makeSuper = checkAddSuperNode(dbb->pageSize, node, indexKey, recordNumber, offset1, &makeNextSuper);
+	if (makeSuper)
 		offset1 = 0;
 
 	int length1 = indexKey->keyLength - offset1;
@@ -105,6 +109,12 @@ AddNodeResult IndexPage::addNode (Dbb *d
 		{
 		node->expandKey (nextKey);
 		offset2 = computePrefix(indexKey, nextKey);
+
+		if (offset2 > SUPERNODE_COMPRESSION_LOSS_LIMIT(dbb->pageSize))
+			makeNextSuper = false; // compresses well, no supenode
+		else if (makeNextSuper)
+			offset2 = 0; // we'll make supernode, so don't prefix compress
+
 		int deltaOffset = offset2 - node->offset;
 		
 		if (node->length >= 128 && (node->length - deltaOffset) < 128)
@@ -138,10 +148,9 @@ AddNodeResult IndexPage::addNode (Dbb *d
 			index, recordNumber, (CHAR*) node - (CHAR*) page);
 	***/
 
-	// Check whether there was a supernode at the insertion point
-	// If yes, delete it fow now. Supernode will be reinstalled at another position later,
-	// unless it gets prefix-compressed.
-	bool wasSuper = deleteSupernode(node->node);
+	// Delete supernode at the insertion point, if there was one
+	// It might be reinstalled later
+	deleteSupernode(node->node);
 
 	// Slide tail of bucket forward to make room
 
@@ -158,17 +167,19 @@ AddNodeResult IndexPage::addNode (Dbb *d
 	// Insert new node
 
 	IndexNode newNode;
+
+	if (makeSuper)
+		addSupernode(node->node);
+
 	newNode.insert (node->node, offset1, length1, key, recordNumber);
 
 	// If necessary, rebuild next node
-	if (wasSuper && (offset2 == 0))
+	if (makeNextSuper)
 		addSupernode(newNode.nextNode);
 
 	if (offset2 >= 0)
 		newNode.insert (newNode.nextNode, offset2, nextKey->keyLength - offset2, nextKey->key, nextNumber);
 
-	if (addSuper)
-		addSupernode(node->node);
 
 
 
@@ -585,14 +596,10 @@ void IndexPage::validate(void *before)
 			FATAL ("Index validate:  record numbers out of order");
 
 
-		bool equalKeys = (priorKeyLength == keyLength);
 		for (UCHAR *p = node.key, *q = key + node.offset, *end = key + l; q < end; p++, q++)
 			{
 			if (*p > *q)		// current > previous, good
-				{
-				equalKeys = false;
 				break;
-				}
 			else if (*p == *q)	// current == previous, good so far
 				continue;
 			else if (*p < *q)	// current < previous, bad
@@ -604,10 +611,7 @@ void IndexPage::validate(void *before)
 				FATAL("Mal-formed index page");
 				}
 			}
-#ifndef SUPERNODES_ON_DUPLICATE_KEYS
-			if( isSuper && equalKeys)
-				FATAL("supernode key equal to previous node");
-#endif
+
 			node.expandKey(key);
 			priorKeyLength = keyLength;
 			priorRecordNumber = recordNumber;
@@ -754,12 +758,19 @@ int IndexPage::deleteNode(Dbb * dbb, Ind
 				int prefix = computePrefix(&priorKey, &nextKey);
 				
 				// Check whether next node is a supernode.
-				// If yes, delete it for now. Supernode will be reinstalled later,
-				// if it does not get prefix-compressed.
+				// If yes, delete it for now. Supernode will be reinstalled
+				// at current position, if it makes sense.
+
+				Btn *supernodePosition = 0;
 
-				Btn *nextSuper = 0;
-				if(deleteSupernode(node.nextNode) && (prefix == 0) && node.node != nodes)
-					nextSuper = node.node;
+				if(deleteSupernode(node.nextNode))
+					{
+					if (checkAddSuperNode(dbb->pageSize, &node, &nextKey, next.getNumber(), prefix, 0))
+						{
+						prefix = 0;
+						supernodePosition = node.node;
+						}
+					}
 
 				int32 num = next.getNumber();
 				node.insert(node.node, prefix, nextKey.keyLength - prefix, nextKey.key, num);
@@ -771,8 +782,8 @@ int IndexPage::deleteNode(Dbb * dbb, Ind
 				if (tailLength > 0)
 					moveMemory(newTail, tail);
 
-				if (nextSuper)
-					addSupernode(nextSuper);
+				if (supernodePosition)
+					addSupernode(supernodePosition);
 
 				length = (int) ((char*) newTail + tailLength - (char*) this);
 				//validate(NULL);
@@ -809,11 +820,24 @@ void IndexPage::printPage(IndexPage * pa
 	Btn *end = (Btn*) ((UCHAR*) page + page->length);
 	IndexNode node (page);
 
+	Log::debug("Supernodes:");
+	for (int i=0; i < SUPERNODES && page->superNodes[i]; i++)
+		Log::debug("%d ",page->superNodes[i]);
+	Log::debug("\n");
+
+	int superIdx = 0;
+
 	for (; node.node < end; node.getNext(end))
 		{
-		Log::debug ("   %d. offset %d, length %d, %d: ",
-				(char*) node.node - (char*) page, 
-				node.offset, node.length, node.getNumber());
+		bool isSuper = false;
+		if (superIdx < SUPERNODES && (node.node - page->nodes == page->superNodes[superIdx]) )
+				{
+				superIdx++;
+				isSuper = true;
+				}
+		Log::debug ("   %d%s. offset %d, length %d, %d: ",
+			(char*) node.node - (char*) page, (isSuper ? "(super)" : ""),
+			node.offset, node.length, node.getNumber());
 		node.expandKey (key);
 		node.printKey ("", key, inversion);
 		}
@@ -1172,9 +1196,7 @@ Bdb* IndexPage::splitIndexPageEnd(Dbb *d
 	split->appendNode(insertKey, recordNumber, dbb->pageSize);
 	split->appendNode(&rolloverKey, rolloverNumber, dbb->pageSize);
 	//split->validate(NULL);
-	//printf ("splitIndexPage: level %d, %d -> %d\n", level, bdb->pageNumber, nextPage);
-	//validate( splitBdb->buffer);
-
+	
 	if (dbb->debug & (DEBUG_PAGES | DEBUG_SPLIT_PAGE))
 		{
 		printPage (this, 0, false);
@@ -1411,14 +1433,28 @@ Btn* IndexPage::getEnd(void)
 
 
 /* During node insertion, check whether supernode should be added at insertion point */
-bool IndexPage::checkAddSuperNode(int pageSize, IndexNode* node, IndexKey *indexKey, int recordNumber, int offset)
+bool IndexPage::checkAddSuperNode(int pageSize, IndexNode* node, IndexKey *indexKey,
+				int recordNumber, int offset, bool *makeNextSuper)
 {
+
+
 	Btn *insertionPoint = node->node;
 
-	if (insertionPoint == nodes) // no supernode at the start of the page
-		return false;
+	if (makeNextSuper)
+		*makeNextSuper = false;
 
-	if (offset >= pageSize/SUPERNODES/2) //compression is too good, no super
+	if (insertionPoint == nodes) 
+		{
+
+		// Make supernode at the following node, if the
+		// gap from the start of the page to the first supernode is too large.
+		if (makeNextSuper && superNodes[0] > pageSize/(SUPERNODES+1) && !superNodes[SUPERNODES-1])
+			*makeNextSuper = true;
+
+		return false; // no supernode at the start of the page
+		}
+
+	if (offset >= SUPERNODE_COMPRESSION_LOSS_LIMIT(pageSize)) //compression is too good, no super
 		return false;
 
 	if (superNodes[SUPERNODES-1]) // supernode array is full
@@ -1432,11 +1468,6 @@ bool IndexPage::checkAddSuperNode(int pa
 	if (keyLen == 0)
 		return false;
 
-#ifndef SUPERNODES_ON_DUPLICATE_KEYS
-	if (keyLen == offset) // no supernode on duplicate entry (yet)
-		return false;
-#endif
-
 	int position = (int)(insertionPoint - nodes);
 
 	int i;
@@ -1451,12 +1482,17 @@ bool IndexPage::checkAddSuperNode(int pa
 
 	// Avoid 2 superNodes adjacent to each other
 	if (nodes + superNodes[i] == insertionPoint)
+		{
+		// Retain existing supernode
+		if (makeNextSuper)
+			*makeNextSuper = true;
 		return false;
+		}
 
 	int nodeLen =
 		IndexNode::nodeLength(offset, indexKey->keyLength - offset, recordNumber);
 	
-	/* Ideal distance between supernodes , assume page will get 90% full*/
+	/* Ideal distance between supernodes*/
 	int idealDistance = pageSize/(SUPERNODES+1);
 
 	
diff -Nrup a/storage/falcon/IndexPage.h b/storage/falcon/IndexPage.h
--- a/storage/falcon/IndexPage.h	2008-03-20 21:56:50 +01:00
+++ b/storage/falcon/IndexPage.h	2008-03-28 07:40:03 +01:00
@@ -57,7 +57,7 @@ public:
 	void		validateNodes (Dbb *dbb, Validation *validation, Bitmap *children, int32 parentPageNumber);
 	void		validate (Dbb *dbb, Validation *validation, Bitmap *pages, int32 parentPageNumber);
 	void		validate(void *before);
-	bool		checkAddSuperNode(int pageSize, IndexNode* node, IndexKey *indexKey, int recordNumber, int offset);
+	bool		checkAddSuperNode(int pageSize, IndexNode* node, IndexKey *indexKey, int recordNumber, int offset,  bool *makeNextSuper);
 	void		moveMemory(void *dst,void *src);
 	void		addSupernode(Btn *where);
 	bool		deleteSupernode(Btn *where);
Thread
bk commit into 6.0 tree (vvaintroub:1.2608) WL#3763vvaintroub28 Mar