Browse Source

HPCC-10651 Roxie dali cache ineffective on subfiles resolved via package

The cache was holding IResolvedFile objects, but the CResolvedFile for the
superfile was holding on to the IDistributedFile from the subfile, not the
IResolvedFile that contained it, so the subfiles kept getting added to the
cache then removed again as they were released.

Also adds some tracing.

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 11 years ago
parent
commit
a4ebc90717
3 changed files with 24 additions and 7 deletions
  1. 2 3
      roxie/ccd/ccddali.cpp
  2. 6 2
      roxie/ccd/ccdfile.cpp
  3. 16 2
      roxie/ccd/ccdstate.cpp

+ 2 - 3
roxie/ccd/ccddali.cpp

@@ -464,8 +464,7 @@ public:
     {
     {
         if (isConnected)
         if (isConnected)
         {
         {
-            if (traceLevel > 1)
-                DBGLOG("Dali lookup %s", logicalName);
+            unsigned start = msTick();
             CDfsLogicalFileName lfn;
             CDfsLogicalFileName lfn;
             lfn.set(logicalName);
             lfn.set(logicalName);
             Owned<IDistributedFile> dfsFile = queryDistributedFileDirectory().lookup(lfn, userdesc.get(), writeAccess, cacheIt);
             Owned<IDistributedFile> dfsFile = queryDistributedFileDirectory().lookup(lfn, userdesc.get(), writeAccess, cacheIt);
@@ -491,7 +490,7 @@ public:
                 writeCache(xpath.str(), xpath.str(), pt);
                 writeCache(xpath.str(), xpath.str(), pt);
             }
             }
             if (traceLevel > 1)
             if (traceLevel > 1)
-                DBGLOG("Dali lookup %s returned %d", logicalName, dfsFile != NULL);
+                DBGLOG("Dali lookup %s returned %s in %u ms", logicalName, dfsFile != NULL ? "match" : "NO match", msTick()-start);
             return dfsFile.getClear();
             return dfsFile.getClear();
         }
         }
         else
         else

+ 6 - 2
roxie/ccd/ccdfile.cpp

@@ -1613,6 +1613,7 @@ protected:
     PointerIArrayOf<IFileDescriptor> remoteSubFiles; // note - on slaves, the file descriptors may have incomplete info. On originating server is always complete
     PointerIArrayOf<IFileDescriptor> remoteSubFiles; // note - on slaves, the file descriptors may have incomplete info. On originating server is always complete
     PointerIArrayOf<IDefRecordMeta> diskMeta;
     PointerIArrayOf<IDefRecordMeta> diskMeta;
     IArrayOf<IDistributedFile> subDFiles;  // To make sure subfiles get locked too
     IArrayOf<IDistributedFile> subDFiles;  // To make sure subfiles get locked too
+    IArrayOf<IResolvedFile> subRFiles;  // To make sure subfiles get locked too
 
 
     Owned <IPropertyTree> properties;
     Owned <IPropertyTree> properties;
 
 
@@ -1697,7 +1698,9 @@ public:
     virtual void beforeDispose()
     virtual void beforeDispose()
     {
     {
         if (cached)
         if (cached)
+        {
             cached->removeCache(this);
             cached->removeCache(this);
+        }
     }
     }
     virtual unsigned numSubFiles() const
     virtual unsigned numSubFiles() const
     {
     {
@@ -2039,8 +2042,7 @@ public:
             assertex(sub->fileType==fileType);
             assertex(sub->fileType==fileType);
         else
         else
             fileType = sub->fileType;
             fileType = sub->fileType;
-        if (sub->dFile)
-            subDFiles.append(*LINK(sub->dFile));
+        subRFiles.append((IResolvedFile &) *LINK(_sub));
         ForEachItemIn(idx, sub->subFiles)
         ForEachItemIn(idx, sub->subFiles)
         {
         {
             addFile(sub->subNames.item(idx), LINK(sub->subFiles.item(idx)), LINK(sub->remoteSubFiles.item(idx)));
             addFile(sub->subNames.item(idx), LINK(sub->subFiles.item(idx)), LINK(sub->remoteSubFiles.item(idx)));
@@ -2067,6 +2069,8 @@ public:
     {
     {
         if (cached)
         if (cached)
         {
         {
+            if (traceLevel > 9)
+                DBGLOG("setCache removing from prior cache %s", queryFileName());
             if (cache==NULL)
             if (cache==NULL)
                 cached->removeCache(this);
                 cached->removeCache(this);
             else
             else

+ 16 - 2
roxie/ccd/ccdstate.cpp

@@ -206,6 +206,8 @@ public:
     virtual void removeCache(const IResolvedFile *file)
     virtual void removeCache(const IResolvedFile *file)
     {
     {
         CriticalBlock b(cacheLock);
         CriticalBlock b(cacheLock);
+        if (traceLevel > 9)
+            DBGLOG("removeCache %s", file->queryFileName());
         // NOTE: it's theoretically possible for the final release to happen after a replacement has been inserted into hash table. 
         // NOTE: it's theoretically possible for the final release to happen after a replacement has been inserted into hash table. 
         // So only remove from hash table if what we find there matches the item that is being deleted.
         // So only remove from hash table if what we find there matches the item that is being deleted.
         IResolvedFile *goer = files.getValue(file->queryFileName());
         IResolvedFile *goer = files.getValue(file->queryFileName());
@@ -223,6 +225,8 @@ public:
             LINK(cache);
             LINK(cache);
             if (cache->isAlive())
             if (cache->isAlive())
                 return cache;
                 return cache;
+            if (traceLevel)
+                DBGLOG("Not returning %s from cache as isAlive() returned false", filename);
         }
         }
         return NULL;
         return NULL;
     }
     }
@@ -239,7 +243,7 @@ static Owned<KeptLowerCaseAtomTable> daliMisses;
 static void noteDaliMiss(const char *filename)
 static void noteDaliMiss(const char *filename)
 {
 {
     CriticalBlock b(daliMissesCrit);
     CriticalBlock b(daliMissesCrit);
-    if (traceLevel > 4)
+    if (traceLevel > 9)
         DBGLOG("noteDaliMiss %s", filename);
         DBGLOG("noteDaliMiss %s", filename);
     daliMisses->addAtom(filename);
     daliMisses->addAtom(filename);
 }
 }
@@ -248,7 +252,7 @@ static bool checkCachedDaliMiss(const char *filename)
 {
 {
     CriticalBlock b(daliMissesCrit);
     CriticalBlock b(daliMissesCrit);
     bool ret = daliMisses->find(filename) != NULL;
     bool ret = daliMisses->find(filename) != NULL;
-    if (traceLevel > 4)
+    if (traceLevel > 9)
         DBGLOG("checkCachedDaliMiss %s returns %d", filename, ret);
         DBGLOG("checkCachedDaliMiss %s returns %d", filename, ret);
     return ret;
     return ret;
 }
 }
@@ -294,9 +298,15 @@ protected:
     static IResolvedFile *resolveLFNusingDaliOrLocal(const char *fileName, bool cacheIt, bool writeAccess, bool alwaysCreate)
     static IResolvedFile *resolveLFNusingDaliOrLocal(const char *fileName, bool cacheIt, bool writeAccess, bool alwaysCreate)
     {
     {
         // MORE - look at alwaysCreate... This may be useful to implement earlier locking semantics.
         // MORE - look at alwaysCreate... This may be useful to implement earlier locking semantics.
+        if (traceLevel > 9)
+            DBGLOG("resolveLFNusingDaliOrLocal %s %d %d %d", fileName, cacheIt, writeAccess, alwaysCreate);
         IResolvedFile* result = daliFiles.lookupCache(fileName);
         IResolvedFile* result = daliFiles.lookupCache(fileName);
         if (result)
         if (result)
+        {
+            if (traceLevel > 9)
+                DBGLOG("resolveLFNusingDaliOrLocal %s - cache hit", fileName);
             return result;
             return result;
+        }
         if (!checkCachedDaliMiss(fileName))
         if (!checkCachedDaliMiss(fileName))
         {
         {
             Owned<IRoxieDaliHelper> daliHelper = connectToDali();
             Owned<IRoxieDaliHelper> daliHelper = connectToDali();
@@ -343,6 +353,8 @@ protected:
         }
         }
         if (cacheIt)
         if (cacheIt)
         {
         {
+            if (traceLevel > 9)
+                DBGLOG("resolveLFNusingDaliOrLocal %s - cache add %d", fileName, result != NULL);
             if (result)
             if (result)
                 daliFiles.addCache(fileName, result);
                 daliFiles.addCache(fileName, result);
             else
             else
@@ -388,6 +400,8 @@ protected:
                         // implies that a package file had ~ in subfile names - shouldn;t really, but we allow it (and just strip the ~
                         // implies that a package file had ~ in subfile names - shouldn;t really, but we allow it (and just strip the ~
                         subFileName.remove(0,1);
                         subFileName.remove(0,1);
                     }
                     }
+                    if (traceLevel > 9)
+                        DBGLOG("Looking up subfile %s", subFileName.str());
                     Owned<const IResolvedFile> subFileInfo = lookupExpandedFileName(subFileName, cache, false, false);  // NOTE - overwriting a superfile does NOT require write access to subfiles
                     Owned<const IResolvedFile> subFileInfo = lookupExpandedFileName(subFileName, cache, false, false);  // NOTE - overwriting a superfile does NOT require write access to subfiles
                     if (subFileInfo)
                     if (subFileInfo)
                     {
                     {