Good work Hung,

Nicely use of qsort and bsearch to improve immcfg performance.

Reviewed and tested the patch.
Ack from me.

Thanks,
Zoran

-----Original Message-----
From: Hung Nguyen [mailto:hung.d.ngu...@dektech.com.au] 
Sent: Thursday, April 07, 2016 12:14 PM
To: Zoran Milinkovic; reddy.neelaka...@oracle.com
Cc: opensaf-devel@lists.sourceforge.net
Subject: [PATCH 1 of 1] immtools: Improve object info list handling in immcfg 
[#1726]

 osaf/tools/safimm/immcfg/imm_cfg.c |  138 ++++++++++++++++++++++--------------
 1 files changed, 85 insertions(+), 53 deletions(-)


Improve object info list handling in immcfg.
Don't search for existing object in objectInfoList when adding new object to 
the list.
Use qsort() and bsearch() to sort and search.

diff --git a/osaf/tools/safimm/immcfg/imm_cfg.c 
b/osaf/tools/safimm/immcfg/imm_cfg.c
--- a/osaf/tools/safimm/immcfg/imm_cfg.c
+++ b/osaf/tools/safimm/immcfg/imm_cfg.c
@@ -37,6 +37,7 @@
 #include <sys/stat.h>
 #include <dlfcn.h>
 #include <wordexp.h>
+#include <assert.h>
 
 #include <saAis.h>
 #include <saImmOm.h>
@@ -49,7 +50,6 @@
 typedef struct ObjectInfo {
        char *objectName;
        char *className;
-       struct ObjectInfo *next;
 } ObjectInfoT;
 
 static SaVersionT immVersion = { 'A', 2, 16 };
@@ -62,7 +62,11 @@ SaImmAdminOwnerNameT adminOwnerName = NU
 SaImmAdminOwnerHandleT ownerHandle = 0;
 SaImmCcbHandleT ccbHandle = -1;
 
-static ObjectInfoT *objectInfo = NULL;
+static ObjectInfoT **objectInfoList = NULL;
+static bool objectInfoListSorted = false;
+static unsigned int objectInfoListSize = 0;
+static unsigned int objectInfoListCount = 0;
+static unsigned int objectInfoListBatchSize = 100;
 
 extern struct ImmutilWrapperProfile immutilWrapperProfile;
 typedef enum {
@@ -190,72 +194,100 @@ void sigalarmh(int sig)
         exit(EXIT_FAILURE);
 }
 
-void object_info_add(const char *objectName, const char *className) {
-       ObjectInfoT *oi;
-       ObjectInfoT *prev;
-       int rc;
-
-       prev = NULL;
-       oi = objectInfo;
-       while(oi) {
-               if((rc = strcmp(oi->objectName, objectName)) >= 0) {
-                       if(!rc) {
-                               // Object is already in the list
-                               return;
-                       }
-
-                       break;
-               }
-
-               prev = oi;
-               oi = oi->next;
+static void resize_object_info_list() {
+       /* Initialize objectInfoList */
+       if (!objectInfoList) {
+               objectInfoList = calloc(objectInfoListBatchSize, 
sizeof(ObjectInfoT *));
+               assert(objectInfoList);
+               assert(objectInfoListCount == 0);
+               objectInfoListSize = objectInfoListBatchSize;
+               return;
        }
 
-       if(prev) {
-               oi = (ObjectInfoT *)calloc(1, sizeof(ObjectInfoT));
-               oi->objectName = strdup(objectName);
-               oi->className = strdup(className);
-               oi->next = prev->next;
-               prev->next = oi;
-       } else {
-               objectInfo = (ObjectInfoT *)calloc(1, sizeof(ObjectInfoT));
-               objectInfo->objectName = strdup(objectName);
-               objectInfo->className = strdup(className);
-               objectInfo->next = oi;
+       /* No need to resize objectInfoList */
+       if (objectInfoListCount < objectInfoListSize) {
+               return;
        }
+
+       /* Reallocate objectInfoList */
+       objectInfoListSize += objectInfoListBatchSize;
+       objectInfoList = realloc(objectInfoList, sizeof(ObjectInfoT *) * 
objectInfoListSize);
+       assert(objectInfoList);
+}
+
+int compare_object_info(const void *v1, const void *v2) {
+       ObjectInfoT *o1 = *((ObjectInfoT **) v1);
+       ObjectInfoT *o2 = *((ObjectInfoT **) v2);
+       return strcmp(o1->objectName, o2->objectName);
+}
+
+void object_info_add(const char *objectName, const char *className) {
+       int pos = 0;
+
+       /* Initialize or reallocate objectInfoList if needed */
+       resize_object_info_list();
+
+       /**
+        * No need to check for existing object in the list.
+        * If the same object is created more than once,
+        * the operation will fail anyway (rejected by IMM server).
+        **/
+
+       /* Insert to the end of the list.
+        * The list will be sorted when needed (chained modify operation) */
+       pos = objectInfoListCount;
+       objectInfoList[pos] = calloc(1, sizeof(ObjectInfoT));
+       assert(objectInfoList[pos]);
+       objectInfoList[pos]->objectName = strdup(objectName);
+       objectInfoList[pos]->className = strdup(className);
+
+       objectInfoListCount++;
+       assert(objectInfoListCount <= objectInfoListSize);
+
+       /* Mark as unsorted since we just add a new item to the list */
+       objectInfoListSorted = false;
 }
 
 void object_info_clear() {
-       ObjectInfoT *oi = objectInfo;
-       ObjectInfoT *next;
+       int i = 0;
 
-       while(oi) {
-               next = oi->next;
-               free(oi->objectName);
-               free(oi->className);
-               free(oi);
-               oi = next;
+       /* objectInfoList is not initialized */
+       if (!objectInfoList) {
+               return;
        }
 
-       objectInfo = NULL;
+       for (i = 0; i < objectInfoListCount; i++) {
+               free(objectInfoList[i]->objectName);
+               free(objectInfoList[i]->className);
+               free(objectInfoList[i]);
+       }
+
+       free(objectInfoList);
+       objectInfoList = NULL;
+       objectInfoListCount = 0;
+       objectInfoListSize = 0;
 }
 
 char *object_info_get_class(const char *objectName) {
-       ObjectInfoT *oi;
-       int rc;
+       ObjectInfoT dummy;
+       ObjectInfoT *dummyPointer = &dummy;
+       ObjectInfoT **result;
 
-       oi = objectInfo;
-       while(oi) {
-               if((rc = strcmp(oi->objectName, objectName)) >= 0) {
-                       if(!rc) {
-                               return strdup(oi->className);
-                       }
+       if (!objectInfoList) {
+               return NULL;
+       }
 
-                       break;
-               }
+       if (!objectInfoListSorted) {
+               qsort(objectInfoList, objectInfoListCount, sizeof(ObjectInfoT 
*), compare_object_info);
+               objectInfoListSorted = true;
+       }
 
-               oi = oi->next;
-       }
+       dummyPointer->objectName = (char *) objectName;
+       result = bsearch(&dummyPointer, objectInfoList, objectInfoListCount, 
sizeof(ObjectInfoT *), compare_object_info);
+
+       if (result) {
+               return (*result)->className;
+       } /* else return NULL */
 
        return NULL;
 }

------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial! http://pubads.g.doubleclick.net/
gampad/clk?id=1444514301&iu=/ca-pub-7940484522588532
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to