Prechádzať zdrojové kódy

Merge pull request #3883 from jakesmith/hpcc-8288

HPCC-8288 - Cache allocators

Reviewed-By: Gavin Halliday <gavin.halliday@lexisnexis.com>
Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 12 rokov pred
rodič
commit
b3909db25d

+ 3 - 2
ecl/eclagent/eclagent.cpp

@@ -2060,7 +2060,8 @@ void EclAgent::doProcess()
 void EclAgent::runProcess(IEclProcess *process)
 {
     assertex(rowManager==NULL);
-    rowManager.setown(roxiemem::createRowManager(0, NULL, queryDummyContextLogger(), this, false)); 
+    allocatorMetaCache.setown(createRowAllocatorCache(this));
+    rowManager.setown(roxiemem::createRowManager(0, NULL, queryDummyContextLogger(), allocatorMetaCache, false));
     setHThorRowManager(rowManager.get());
     rtlSetReleaseRowHook(queryHThorRtlRowCallback());
 
@@ -2098,7 +2099,7 @@ void EclAgent::runProcess(IEclProcess *process)
 #ifdef _DEBUG_LEAKS
     rowManager.clear();//Early release of rowManager, so activity IDs of leaked blocks are available
 #endif
-    allAllocators.kill();//release meta before libraries unloaded
+    allocatorMetaCache.clear(); //release meta before libraries unloaded
     queryLibraries.kill();
 
     if (debugContext)

+ 8 - 58
ecl/eclagent/eclagent.ipp

@@ -341,7 +341,7 @@ public:
 
 
 class CHThorDebugContext;
-class EclAgent : public CInterface, implements IAgentContext, implements ICodeContext, implements roxiemem::IRowAllocatorCache
+class EclAgent : public CInterface, implements IAgentContext, implements ICodeContext, implements IRowAllocatorMetaActIdCacheCallback
 {
 private:
     friend class EclAgentWorkflowMachine;
@@ -377,8 +377,7 @@ private:
     StringArray clusterNames;
     unsigned int clusterWidth;
     Owned<IDistributedFileTransaction> superfiletransaction;
-    mutable IArrayOf<IEngineRowAllocator> allAllocators;
-    mutable SpinLock allAllocatorsLock;                 
+    mutable Owned<IRowAllocatorMetaActIdCache> allocatorMetaCache;
     Owned<EclGraph> activeGraph;
     Owned<IRecordLayoutTranslatorCache> rltCache;
     Owned<CHThorDebugContext> debugContext;
@@ -613,66 +612,12 @@ public:
     }
     virtual IEngineRowAllocator * getRowAllocator(IOutputMetaData * meta, unsigned activityId) const
     {
-        // MORE - may need to do some caching/commoning up here otherwise GRAPH in a child query may use too many
-        SpinBlock b(allAllocatorsLock);
-        IEngineRowAllocator * ret = createHThorRowAllocator(*rowManager, meta, activityId, allAllocators.ordinality());
-        LINK(ret);
-        allAllocators.append(*ret);
-        return ret;
+        return allocatorMetaCache->ensure(meta, activityId);
     }
     virtual void getRowXML(size32_t & lenResult, char * & result, IOutputMetaData & info, const void * row, unsigned flags)
     {
         convertRowToXML(lenResult, result, info, row, flags);
     }
-
-    // interface IRowAllocatorCache
-    virtual unsigned getActivityId(unsigned cacheId) const
-    {
-        SpinBlock b(allAllocatorsLock);
-        unsigned allocatorIndex = (cacheId & ALLOCATORID_MASK);
-        if (allAllocators.isItem(allocatorIndex))
-            return allAllocators.item(allocatorIndex).queryActivityId();
-        else
-        {
-            //assert(false);
-            return 12345678; // Used for tracing, better than a crash...
-        }
-    }
-    virtual StringBuffer &getActivityDescriptor(unsigned cacheId, StringBuffer &out) const
-    {
-        SpinBlock b(allAllocatorsLock);
-        unsigned allocatorIndex = (cacheId & ALLOCATORID_MASK);
-        if (allAllocators.isItem(allocatorIndex))
-            return allAllocators.item(allocatorIndex).getId(out);
-        else
-        {
-            assert(false);
-            return out.append("unknown"); // Used for tracing, better than a crash...
-        }
-    }
-    virtual void onDestroy(unsigned cacheId, void *row) const 
-    {
-        IEngineRowAllocator *allocator;
-        unsigned allocatorIndex = (cacheId & ALLOCATORID_MASK);
-        {
-            SpinBlock b(allAllocatorsLock); // just protect the access to the array - don't keep locked for the call of destruct or may deadlock
-            if (allAllocators.isItem(allocatorIndex))
-                allocator = &allAllocators.item(allocatorIndex);
-            else
-            {
-                assert(false);
-                return;
-            }
-        }
-        allocator->queryOutputMeta()->destruct((byte *) row);
-    }
-    virtual void checkValid(unsigned cacheId, const void *row) const
-    {
-        if (!RoxieRowCheckValid(cacheId, row))
-        {
-            //MORE: Throw an exception?
-        }
-    }
     virtual const char *queryAllowedPipePrograms()
     {
         return allowedPipeProgs.get();
@@ -682,6 +627,11 @@ public:
     
     virtual void updateWULogfile();
 
+// roxiemem::IRowAllocatorMetaActIdCacheCallback
+    virtual IEngineRowAllocator *createAllocator(IOutputMetaData *meta, unsigned activityId, unsigned id) const
+    {
+        return createRoxieRowAllocator(*rowManager, meta, activityId, id, roxiemem::RHFnone);
+    }
 };
 
 //---------------------------------------------------------------------------

+ 0 - 41
thorlcr/thorutil/thmem.cpp

@@ -1705,48 +1705,7 @@ ILargeMemLimitNotify *createMultiThorResourceMutex(const char *grpname,CSDSServe
     return new cMultiThorResourceMutex(grpname,_status);
 }
 
-#pragma pack(push,1) // hashing on members, so ensure contiguous
-struct ThorAllocatorKey
-{
-    IOutputMetaData *meta;
-    unsigned activityId;
-    ThorAllocatorKey(IOutputMetaData *_meta, unsigned &_activityId) : meta(_meta), activityId(_activityId) { }
-    bool operator==(ThorAllocatorKey const &other) const
-    {
-        return (meta == other.meta) && (activityId == other.activityId);
-    }
-};
-#pragma pack(pop)
 
-class CThorAllocatorCacheItem : public OwningHTMapping<IEngineRowAllocator, ThorAllocatorKey>
-{
-    Linked<IOutputMetaData> meta;
-public:
-    CThorAllocatorCacheItem(IEngineRowAllocator *allocator, ThorAllocatorKey &key)
-        : OwningHTMapping<IEngineRowAllocator, ThorAllocatorKey>(*allocator, key)
-    {
-        meta.set(key.meta);
-    }
-};
-
-class CThorAllocatorCache : private OwningSimpleHashTableOf<CThorAllocatorCacheItem, ThorAllocatorKey>
-{
-public:
-    inline IEngineRowAllocator *find(IOutputMetaData *meta, unsigned activityId) const
-    {
-        ThorAllocatorKey key(meta, activityId);
-        CThorAllocatorCacheItem *container = OwningSimpleHashTableOf::find(key);
-        if (!container)
-            return NULL;
-        return &container->queryElement();
-    }
-    inline bool add(IEngineRowAllocator *allocator, IOutputMetaData *meta, unsigned activityId)
-    {
-        ThorAllocatorKey key(meta, activityId);
-        CThorAllocatorCacheItem *container = new CThorAllocatorCacheItem(allocator, key);
-        return replace(*container);
-    }
-};
 class CThorAllocator : public CSimpleInterface, implements IRtlRowCallback, implements IThorAllocator, implements IRowAllocatorMetaActIdCacheCallback
 {
 protected: