Browse Source

HPCC-11044 Call a library function to copy link counted rows

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday 11 years ago
parent
commit
b73613e82b

+ 4 - 0
ecl/hqlcpp/hqlcatom.cpp

@@ -538,10 +538,12 @@ IIdAtom * roundId;
 IIdAtom * roundToId;
 IIdAtom * roundupId;
 IIdAtom * rowset2DatasetXId;
+IIdAtom * rtlCopyRowLinkChildrenId;
 IIdAtom * rtlDeserializeDictionaryId;
 IIdAtom * rtlDeserializeDictionaryFromDatasetId;
 IIdAtom * rtlDeserializeRowId;
 IIdAtom * rtlDeserializeToBuilderId;
+IIdAtom * rtlLinkChildrenId;
 IIdAtom * rtlMaxId;
 IIdAtom * rtlMinId;
 IIdAtom * rtlRandomId;
@@ -1211,10 +1213,12 @@ MODULE_INIT(INIT_PRIORITY_HQLATOM-1)
     MAKEID(roundTo);
     roundupId = createIdAtom("_roundup");
     MAKEID(rowset2DatasetX);
+    MAKEID(rtlCopyRowLinkChildren);
     MAKEID(rtlDeserializeDictionary);
     MAKEID(rtlDeserializeDictionaryFromDataset);
     MAKEID(rtlDeserializeRow);
     MAKEID(rtlDeserializeToBuilder);
+    MAKEID(rtlLinkChildren);
     MAKEID(rtlMax);
     MAKEID(rtlMin);
     MAKEID(rtlRandom);

+ 2 - 0
ecl/hqlcpp/hqlcatom.hpp

@@ -538,10 +538,12 @@ extern IIdAtom * roundId;
 extern IIdAtom * roundToId;
 extern IIdAtom * roundupId;
 extern IIdAtom * rowset2DatasetXId;
+extern IIdAtom * rtlCopyRowLinkChildrenId;
 extern IIdAtom * rtlDeserializeDictionaryId;
 extern IIdAtom * rtlDeserializeDictionaryFromDatasetId;
 extern IIdAtom * rtlDeserializeRowId;
 extern IIdAtom * rtlDeserializeToBuilderId;
+extern IIdAtom * rtlLinkChildrenId;
 extern IIdAtom * rtlMaxId;
 extern IIdAtom * rtlMinId;
 extern IIdAtom * rtlRandomId;

+ 1 - 2
ecl/hqlcpp/hqlcppds.cpp

@@ -4448,8 +4448,7 @@ void HqlCppTranslator::buildRowAssign(BuildCtx & ctx, IReferenceSelector * targe
     IHqlExpression * targetRecord = ::queryRecord(target->queryType());
 
     //if record structures are identical, then we must just be able to block copy the information across.
-    bool useMemcpy = (sourceRecord == targetRecord) && source->isBinary() && !source->isConditional() && 
-                     !recordRequiresLinkCount(sourceRecord);
+    bool useMemcpy = (sourceRecord == targetRecord) && source->isBinary() && !source->isConditional();
 
     if (useMemcpy)
     {

+ 4 - 0
ecl/hqlcpp/hqlcppsys.ecl

@@ -26,6 +26,7 @@ const char * cppSystemText[]  = {
     "shared IOutputRowSerializer := boolean;",
     "shared IOutputRowDeserializer := boolean;",
     "shared IHThorHashLookupInfo := boolean;",
+    "shared IOutputMetaData := boolean;",
     
     "export InternalCppService := SERVICE",
     //  searchTableStringN(unsigned4 num, string table, string search) : library='eclrtl';
@@ -426,6 +427,9 @@ const char * cppSystemText[]  = {
 
     "   _linkcounted_ dataset appendRowsToRowset(_array_ dataset _in) : pure,eclrtl,include,entrypoint='appendRowsToRowset';",
 
+    "   rtlCopyRowLinkChildren(row self, unsigned4 len, const row src, IOutputMetaData meta) : pure,eclrtl,include;",
+    "   rtlLinkChildren(row _self, IOutputMetaData _meta) : pure,eclrtl,include;",
+
     "   set of any deserializeSet(boolean o) :  eclrtl,include='eclrtl.hpp',library='eclrtl',entrypoint='deserializeSet',newSet;",
     "   set of any set2SetX(set of any i) : eclrtl,include='eclrtl.hpp',library='eclrtl',entrypoint='rtlSetToSetX',newSet;",
     "   set of any appendSetX(set of any l, set of any r) : eclrtl,include='eclrtl.hpp',library='eclrtl',entrypoint='rtlAppendSetX',newSet;",

+ 16 - 6
ecl/hqlcpp/hqltcppc.cpp

@@ -965,7 +965,6 @@ void CContainerInfo::setRow(HqlCppTranslator & translator, BuildCtx & ctx, IRefe
     if (!recordTypesMatch(selector->queryType(), source->queryType()))
         throwError(HQLERR_RecordNotCompatible);
 
-    assertex(!recordRequiresLinkCount(column->queryRecord()));
     CHqlBoundExpr targetAddress, sourceAddress, length;
     source->buildAddress(ctx, sourceAddress);
 
@@ -988,12 +987,23 @@ void CContainerInfo::setRow(HqlCppTranslator & translator, BuildCtx & ctx, IRefe
     buildAddress(translator, ctx, selector, targetAddress);
 
     HqlExprArray args;
-    args.append(*LINK(targetAddress.expr));
-    args.append(*LINK(sourceAddress.expr));
-    args.append(*LINK(length.expr));
-    translator.callProcedure(ctx, memcpyId, args);
+    if (recordRequiresLinkCount(column->queryRecord()))
+    {
+        args.append(*LINK(targetAddress.expr));
+        args.append(*LINK(length.expr));
+        args.append(*LINK(sourceAddress.expr));
+        args.append(*translator.buildMetaParameter(column));
+        translator.callProcedure(ctx, rtlCopyRowLinkChildrenId, args);
+    }
+    else
+    {
+        args.append(*LINK(targetAddress.expr));
+        args.append(*LINK(sourceAddress.expr));
+        args.append(*LINK(length.expr));
+        translator.callProcedure(ctx, memcpyId, args);
+    }
 
-    //Use the size just calulated for the field
+    //Use the size just calculated for the field
     associateSizeOf(ctx, selector, length.expr, 0);
 }
 

+ 13 - 0
rtl/eclrtl/rtlds.cpp

@@ -518,6 +518,19 @@ const void * rtlCloneRow(IEngineRowAllocator * rowAllocator, size32_t len, const
     return builder.finalizeRowClear(len);
 }
 
+void rtlLinkChildren(void * self, IOutputMetaData & meta)
+{
+    RtlChildRowLinkerWalker walker;
+    meta.walkIndirectMembers(static_cast<byte *>(self), walker);
+}
+
+void rtlCopyRowLinkChildren(void * self, size32_t len, const void * row, IOutputMetaData & meta)
+{
+    memcpy(self, row, len);
+
+    RtlChildRowLinkerWalker walker;
+    meta.walkIndirectMembers(static_cast<byte *>(self), walker);
+}
 
 
 //---------------------------------------------------------------------------

+ 2 - 0
rtl/eclrtl/rtlds_imp.hpp

@@ -339,6 +339,8 @@ protected:
 };
 
 extern ECLRTL_API const void * rtlCloneRow(IEngineRowAllocator * rowAllocator, size32_t len, const void * row);
+extern ECLRTL_API void rtlCopyRowLinkChildren(void * self, size32_t len, const void * row, IOutputMetaData & meta);
+extern ECLRTL_API void rtlLinkChildren(void * self, IOutputMetaData & meta);
 
 //---------------------------------------------------------------------------