[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