浏览代码

Merge pull request #10521 from richardkchapman/rtlrecord-getrecordsize

HPCC-18423 RtlRecord could have a new recordSize(row) method

Reviewed-by: Gavin Halliday <ghalliday@hpccsystems.com>
Gavin Halliday 7 年之前
父节点
当前提交
57c915ab37
共有 2 个文件被更改,包括 26 次插入14 次删除
  1. 25 14
      rtl/eclrtl/rtlrecord.cpp
  2. 1 0
      rtl/eclrtl/rtlrecord.hpp

+ 25 - 14
rtl/eclrtl/rtlrecord.cpp

@@ -276,12 +276,14 @@ void RtlRecord::calcRowOffsets(size_t * variableOffsets, const void * _row, unsi
 {
     const byte * row = static_cast<const byte *>(_row);
     unsigned maxVarField = (numFieldsUsed>=numFields) ? numVarFields : whichVariableOffset[numFieldsUsed];
+    size32_t varoffset = 0;
     for (unsigned i = 0; i < maxVarField; i++)
     {
         unsigned fieldIndex = variableFieldIds[i];
-        size_t offset = getOffset(variableOffsets, fieldIndex);
-        size_t fieldSize = queryType(fieldIndex)->size(row + offset, row);
-        variableOffsets[i+1] = offset+fieldSize;
+        size32_t offset = fixedOffsets[fieldIndex] + varoffset;
+        size32_t fieldSize = queryType(fieldIndex)->size(row + offset, row);
+        varoffset = offset+fieldSize;
+        variableOffsets[i+1] = varoffset;
     }
 #ifdef _DEBUG
     for (unsigned i = maxVarField; i < numVarFields; i++)
@@ -373,6 +375,25 @@ const RtlRecord *RtlRecord::queryNested(unsigned fieldId) const
     return nullptr;
 }
 
+size32_t RtlRecord::getRecordSize(const void *_row) const
+{
+    size32_t size = getFixedSize();
+    if (!size)
+    {
+        const byte * row = static_cast<const byte *>(_row);
+        size32_t varoffset = 0;
+        for (unsigned i = 0; i < numVarFields; i++)
+        {
+            unsigned fieldIndex = variableFieldIds[i];
+            size32_t offset = fixedOffsets[fieldIndex] + varoffset;
+            size32_t fieldSize = queryType(fieldIndex)->size(row + offset, row);
+            varoffset = offset + fieldSize;
+        }
+        size = fixedOffsets[numFields] + varoffset;
+    }
+    return size;
+}
+
 //---------------------------------------------------------------------------------------------------------------------
 
 RtlRow::RtlRow(const RtlRecord & _info, const void * optRow, unsigned numOffsets, size_t * _variableOffsets) : info(_info), variableOffsets(_variableOffsets)
@@ -505,17 +526,7 @@ const RtlRecord &COutputMetaData::queryRecordAccessor(bool expand) const
 
 size32_t COutputMetaData::getRecordSize(const void * data)
 {
-    //Allocate a temporary offset array on the stack to avoid runtime overhead.
-    const RtlRecord &r = queryRecordAccessor(true);
-    size32_t size = r.getFixedSize();
-    if (!size)
-    {
-        unsigned numOffsets = r.getNumVarFields() + 1;
-        size_t * variableOffsets = (size_t *)alloca(numOffsets * sizeof(size_t));
-        RtlRow offsetCalculator(r, data, numOffsets, variableOffsets);
-        size = offsetCalculator.getRecordSize();
-    }
-    return size;
+    return queryRecordAccessor(true).getRecordSize(data);
 }
 
 class CVariableOutputRowSerializer : public COutputRowSerializer

+ 1 - 0
rtl/eclrtl/rtlrecord.hpp

@@ -217,6 +217,7 @@ public:
     {
         return getOffset(variableOffsets, numFields);
     }
+    size32_t getRecordSize(const void *data) const;
 
     size32_t getMinRecordSize() const;
     size32_t deserialize(ARowBuilder & rowBuilder, IRowDeserializerSource & in) const;