[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: KDE/kdevplatform/language/duchain/repositories
From: David Nolden <david.nolden.kde () art-master ! de>
Date: 2008-08-06 22:57:16
Message-ID: 1218063436.684281.24857.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 843319 by zwabel:
Try more preventing loops in the itemrepository hash structure.
This hopefully fixes some crashes/endless loops in this area.
M +34 -6 itemrepository.h
--- trunk/KDE/kdevplatform/language/duchain/repositories/itemrepository.h \
#843318:843319 @@ -31,7 +31,7 @@
#include <kdebug.h>
#include "../../languageexport.h"
-#define DEBUG_ITEMREPOSITORY_LOADING
+//#define DEBUG_ITEMREPOSITORY_LOADING
namespace KDevelop {
@@ -585,7 +585,7 @@
typedef Locker<threadSafe> ThisLocker;
enum {
- ItemRepositoryVersion = 4,
+ ItemRepositoryVersion = 5,
BucketStartOffset = sizeof(uint) * 7 + sizeof(short unsigned int) * \
bucketHashSize //Position in the data where the bucket array starts };
@@ -625,6 +625,7 @@
short unsigned int* bucketHashPosition = m_firstBucketForHash + ((hash * \
1234271) % bucketHashSize); short unsigned int previousBucketNumber = \
*bucketHashPosition; + short unsigned int previousPreviousBucketNumber = 0;
short unsigned int size = request.itemSize();
@@ -655,9 +656,10 @@
//The item isn't in bucket previousBucketNumber, but maybe the bucket has a \
pointer to the next bucket that might contain the item //Should happen rarely
short unsigned int next = bucketPtr->nextBucketForHash(hash);
- if(next)
+ if(next) {
+ previousPreviousBucketNumber = previousBucketNumber;
previousBucketNumber = next;
- else
+ } else
break;
}
}
@@ -708,7 +710,31 @@
if(!pickedBucketInChain && previousBucketNumber && previousBucketNumber != \
useBucket) { //Should happen rarely
++m_statBucketHashClashes;
- m_buckets[previousBucketNumber]->setNextBucketForHash(request.hash(), \
useBucket); +
+ //If the used bucket already has previousBucketNumber as a follower, \
insert it instead of previousBucketNumber, + //so we don't create a loop
+ bool replacePreviousWithUsed = false;
+
+ {
+ uint checkBucket = useBucket;
+ while(checkBucket) {
+ if(checkBucket == previousBucketNumber) {
+ replacePreviousWithUsed = true;
+ break;
+ }
+ checkBucket = \
bucketForIndex(checkBucket)->nextBucketForHash(request.hash()); + }
+ }
+
+ if(!replacePreviousWithUsed)
+ m_buckets[previousBucketNumber]->setNextBucketForHash(request.hash(), \
useBucket); + else if(previousPreviousBucketNumber) {
+ bucketForIndex(previousPreviousBucketNumber)->setNextBucketForHash(request.hash(), \
useBucket); + } else {
+ //useBucket needs to be the first bucket in the global bucket hash for \
this hash-value + Q_ASSERT(*bucketHashPosition == previousBucketNumber);
+ *bucketHashPosition = useBucket;
+ }
}
if(reOrderFreeSpaceBucketIndex != -1)
@@ -858,8 +884,10 @@
}
}
}else{
- if(!bucketPtr->hasClashingItem(hash))
+ if(!bucketPtr->hasClashingItem(hash)) {
previousBucketPtr->setNextBucketForHash(hash, \
bucketPtr->nextBucketForHash(hash)); + \
Q_ASSERT(bucketPtr->nextBucketForHash(hash) != previousBucketNumber); + }
}
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic