Browse Source

removing init from the decodeBinary -> brings up to 10% of performance increase
the cleanup needs to trace the position of the last allocation + calloc in array decoding
no valgrind varnings or memleaks, tests do pass

pushing max asset to recursive calls of UA_init

changing from pointer to membernumber

Stasik0 9 years ago
parent
commit
a5df3d9589
3 changed files with 20 additions and 5 deletions
  1. 2 0
      include/ua_types.h
  2. 12 1
      src/ua_types.c
  3. 6 4
      src/ua_types_encoding_binary.c

+ 2 - 0
include/ua_types.h

@@ -579,6 +579,8 @@ UA_StatusCode UA_EXPORT UA_copy(const void *src, void *dst, const UA_DataType *d
  */
 void UA_EXPORT UA_deleteMembers(void *p, const UA_DataType *dataType);
 
+void UA_EXPORT UA_deleteMembersUntil(void *p, const UA_DataType *dataType, UA_Int32 lastMember);
+
 /**
  * Deletes (frees) a variable and all of its content.
  *

+ 12 - 1
src/ua_types.c

@@ -1117,11 +1117,18 @@ UA_StatusCode UA_copy(const void *src, void *dst, const UA_DataType *dataType) {
 }
 
 void UA_deleteMembers(void *p, const UA_DataType *dataType) {
+    UA_deleteMembersUntil(p, dataType, -1);
+}
+
+void UA_deleteMembersUntil(void *p, const UA_DataType *dataType, UA_Int32 lastMember) {
     uintptr_t ptr = (uintptr_t)p;
     if(dataType->fixedSize)
         return;
     UA_Byte membersSize = dataType->membersSize;
     for(size_t i=0;i<membersSize; i++) {
+        if(lastMember > -1 && (UA_Int32)i > lastMember){
+            return;
+        }
         const UA_DataTypeMember *member = &dataType->members[i];
         const UA_DataType *memberType;
         if(member->namespaceZero)
@@ -1185,7 +1192,11 @@ void UA_deleteMembers(void *p, const UA_DataType *dataType) {
             break;
         default:
             // QualifiedName, LocalizedText and strings are treated as structures, also
-            UA_deleteMembers((void*)ptr, memberType);
+            if(lastMember > -1){
+                UA_deleteMembersUntil((void*)ptr, memberType, lastMember-i);
+            }
+            else
+                UA_deleteMembers((void*)ptr, memberType);
         }
         ptr += memberType->memSize;
     }

+ 6 - 4
src/ua_types_encoding_binary.c

@@ -65,7 +65,7 @@ static UA_StatusCode UA_Array_decodeBinary(const UA_ByteString *src, size_t *UA_
     if(*offset + ((dataType->memSize * noElements)/32) > (UA_UInt32)src->length)
         return UA_STATUSCODE_BADDECODINGERROR;
 
-    *dst = UA_malloc(dataType->memSize * noElements);
+    *dst = UA_calloc(1, dataType->memSize * noElements);
     if(!*dst)
         return UA_STATUSCODE_BADOUTOFMEMORY;
 
@@ -1175,11 +1175,13 @@ UA_StatusCode UA_encodeBinary(const void *src, const UA_DataType *dataType, UA_B
 
 UA_StatusCode UA_decodeBinary(const UA_ByteString *src, size_t *UA_RESTRICT offset, void *dst,
                               const UA_DataType *dataType) {
-    UA_init(dst, dataType);
+    /* skipping init seems to bring about 10% of performance and no valgrind warning*/
+    //UA_init(dst, dataType);
     uintptr_t ptr = (uintptr_t)dst;
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     UA_Byte membersSize = dataType->membersSize;
-    for(size_t i = 0; i < membersSize && retval == UA_STATUSCODE_GOOD; i++) {
+    size_t i = 0;
+    for(i = 0; i < membersSize && retval == UA_STATUSCODE_GOOD; i++) {
         const UA_DataTypeMember *member = &dataType->members[i];
         const UA_DataType *memberType;
         if(member->namespaceZero)
@@ -1262,6 +1264,6 @@ UA_StatusCode UA_decodeBinary(const UA_ByteString *src, size_t *UA_RESTRICT offs
         ptr += memberType->memSize;
     }
     if(retval != UA_STATUSCODE_GOOD)
-        UA_deleteMembers(dst, dataType);
+        UA_deleteMembersUntil(dst, dataType, i);
     return retval;
 }