Browse Source

Merge pull request #11244 from ghalliday/issue19080

HPCC-19080 Allow initial row size to be specified to avoid reallocation

Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 7 years ago
parent
commit
067bc5072f
4 changed files with 41 additions and 21 deletions
  1. 35 16
      common/thorhelper/roxierow.cpp
  2. 1 0
      ecl/hqlcpp/hqlcppds.cpp
  3. 2 3
      rtl/eclrtl/rtlds.cpp
  4. 3 2
      rtl/include/eclhelper.hpp

+ 35 - 16
common/thorhelper/roxierow.cpp

@@ -280,24 +280,32 @@ public:
         heap.setown(rowManager.createFixedRowHeap(meta.getFixedSize()+CHECKER::extraSize, allocatorId | ACTIVITY_FLAG_ISREGISTERED | CHECKER::allocatorCheckFlag, (roxiemem::RoxieHeapFlags)flags));
     }
 
-    virtual void * createRow()
+    virtual void * createRow() override
     {
         return heap->allocate();
     }
 
-    virtual void * createRow(size32_t & allocatedSize)
+    virtual void * createRow(size32_t & allocatedSize) override
     {
         allocatedSize = meta.getFixedSize();
         return heap->allocate();
     }
 
-    virtual void * resizeRow(size32_t newSize, void * row, size32_t & size)
+    virtual void * createRow(size32_t initialSize, size32_t & allocatedSize) override
+    {
+        size32_t fixedSize = meta.getFixedSize();
+        assertex(initialSize == fixedSize);
+        allocatedSize = fixedSize;
+        return heap->allocate();
+    }
+
+    virtual void * resizeRow(size32_t newSize, void * row, size32_t & size) override
     {
         throwUnexpected();
         return NULL;
     }
 
-    virtual void * finalizeRow(size32_t finalSize, void * row, size32_t oldSize)
+    virtual void * finalizeRow(size32_t finalSize, void * row, size32_t oldSize) override
     {
         if (!meta.needsDestruct() && !CHECKER::allocatorCheckFlag)
             return row;
@@ -332,26 +340,24 @@ public:
         heap.setown(rowManager.createVariableRowHeap(allocatorId | ACTIVITY_FLAG_ISREGISTERED | CHECKER::allocatorCheckFlag, (roxiemem::RoxieHeapFlags)flags));
     }
 
-    virtual void * createRow()
+    virtual void * createRow() override
     {
         memsize_t allocSize = meta.getInitialSize();
         memsize_t capacity;
         return heap->allocate(allocSize+CHECKER::extraSize, capacity);
     }
 
-    virtual void * createRow(size32_t & allocatedSize)
+    virtual void * createRow(size32_t & allocatedSize) override
     {
-        const memsize_t allocSize = meta.getInitialSize();
-        memsize_t newCapacity; // always initialised by allocate
-        void * row = heap->allocate(allocSize+CHECKER::extraSize, newCapacity);
-        //This test should get constant folded to avoid the decrement when not checked.
-        if (CHECKER::extraSize)
-            newCapacity -= CHECKER::extraSize;
-        allocatedSize = (size32_t)newCapacity;
-        return row;
+        return doCreateRow(meta.getInitialSize(), allocatedSize);
+    }
+
+    virtual void * createRow(size32_t initialSize, size32_t & allocatedSize) override
+    {
+        return doCreateRow(initialSize, allocatedSize);
     }
 
-    virtual void * resizeRow(size32_t newSize, void * row, size32_t & size)
+    virtual void * resizeRow(size32_t newSize, void * row, size32_t & size) override
     {
         const size32_t oldsize = size;  // don't need to include the extra checking bytes
         memsize_t newCapacity; // always initialised by resizeRow
@@ -362,7 +368,7 @@ public:
         return newrow;
     }
 
-    virtual void * finalizeRow(size32_t finalSize, void * row, size32_t oldSize)
+    virtual void * finalizeRow(size32_t finalSize, void * row, size32_t oldSize) override
     {
         if (!meta.needsDestruct() && !CHECKER::allocatorCheckFlag)
             return row;
@@ -383,6 +389,19 @@ public:
     }
 
 protected:
+    void * doCreateRow(size32_t initialSize, size32_t & allocatedSize)
+    {
+        memsize_t newCapacity; // always initialised by allocate
+        void * row = heap->allocate(initialSize + CHECKER::extraSize, newCapacity);
+        //This test should get constant folded to avoid the decrement when not checked.
+        if (CHECKER::extraSize)
+            newCapacity -= CHECKER::extraSize;
+        allocatedSize = (size32_t)newCapacity;
+        return row;
+    }
+
+
+protected:
     Owned<roxiemem::IVariableRowHeap> heap;
 };
 

+ 1 - 0
ecl/hqlcpp/hqlcppds.cpp

@@ -3022,6 +3022,7 @@ public:
 
 //Used for dynamically sizing rows.
     virtual void * createRow(size32_t & allocatedSize) override { throwUnexpected(); }
+    virtual void * createRow(size32_t initialSize, size32_t & allocatedSize) override { throwUnexpected(); }
     virtual void * resizeRow(size32_t newSize, void * row, size32_t & size) override { throwUnexpected(); }
     virtual void * finalizeRow(size32_t newSize, void * row, size32_t oldSize) override { throwUnexpected(); }
 

+ 2 - 3
rtl/eclrtl/rtlds.cpp

@@ -275,9 +275,8 @@ byte * RtlDynamicRowBuilder::ensureCapacity(size32_t required, const char * fiel
     if (required > maxLength)
     {
         if (!self)
-            create();
-
-        if (required > maxLength)
+            self = (byte *)rowAllocator->createRow(required, maxLength);
+        else if (required > maxLength)
         {
             void * next = rowAllocator->resizeRow(required, self, maxLength);
             if (!next)

+ 3 - 2
rtl/include/eclhelper.hpp

@@ -44,8 +44,8 @@ typedef unsigned short UChar;
 
 //Should be incremented whenever the virtuals in the context or a helper are changed, so
 //that a work unit can't be rerun.  Try as hard as possible to retain compatibility.
-#define ACTIVITY_INTERFACE_VERSION      699
-#define MIN_ACTIVITY_INTERFACE_VERSION  699             //minimum value that is compatible with current interface
+#define ACTIVITY_INTERFACE_VERSION      650
+#define MIN_ACTIVITY_INTERFACE_VERSION  650             //minimum value that is compatible with current interface
 
 typedef unsigned char byte;
 
@@ -263,6 +263,7 @@ interface IEngineRowAllocator : extends IInterface
 
 //Used for dynamically sizing rows.
     virtual void * createRow(size32_t & allocatedSize) = 0;
+    virtual void * createRow(size32_t initialSize, size32_t & allocatedSize) = 0;
     virtual void * resizeRow(size32_t newSize, void * row, size32_t & size) = 0;            //NB: size is updated with the new size
     virtual void * finalizeRow(size32_t newSize, void * row, size32_t oldSize) = 0;