Nikolay Sivov : oledb32: Use growing array to store error records.

Alexandre Julliard julliard at winehq.org
Tue Nov 15 17:56:15 CST 2016


Module: wine
Branch: master
Commit: 4a3054e445e86472a3e4b5d12a2718708c863df0
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=4a3054e445e86472a3e4b5d12a2718708c863df0

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Tue Nov 15 20:26:47 2016 +0300

oledb32: Use growing array to store error records.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/oledb32/errorinfo.c     | 65 ++++++++++++++++++++++++++++----------------
 dlls/oledb32/oledb_private.h |  5 ++++
 2 files changed, 47 insertions(+), 23 deletions(-)

diff --git a/dlls/oledb32/errorinfo.c b/dlls/oledb32/errorinfo.c
index 4a56b46..0875d82 100644
--- a/dlls/oledb32/errorinfo.c
+++ b/dlls/oledb32/errorinfo.c
@@ -40,7 +40,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(oledb);
 
 struct ErrorEntry
 {
-    struct list entry;
     ERRORINFO       info;
     DISPPARAMS      dispparams;
     IUnknown        *unknown;
@@ -53,7 +52,9 @@ typedef struct ErrorInfoImpl
     IErrorRecords  IErrorRecords_iface;
     LONG ref;
 
-    struct list errors;
+    struct ErrorEntry *records;
+    unsigned int allocated;
+    unsigned int count;
 } ErrorInfoImpl;
 
 static inline ErrorInfoImpl *impl_from_IErrorInfo( IErrorInfo *iface )
@@ -103,20 +104,19 @@ static ULONG WINAPI IErrorInfoImpl_Release(IErrorInfo* iface)
 {
     ErrorInfoImpl *This = impl_from_IErrorInfo(iface);
     ULONG ref = InterlockedDecrement(&This->ref);
-    struct ErrorEntry *cursor, *cursor2;
 
     TRACE("(%p)->%u\n",This,ref+1);
 
     if (!ref)
     {
-        LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->errors, struct ErrorEntry, entry)
-        {
-            list_remove(&cursor->entry);
-            if(cursor->unknown)
-                IUnknown_Release(cursor->unknown);
+        unsigned int i;
 
-            heap_free(cursor);
+        for (i = 0; i < This->count; i++)
+        {
+            if (This->records[i].unknown)
+                IUnknown_Release(This->records[i].unknown);
         }
+        heap_free(This->records);
         heap_free(This);
     }
     return ref;
@@ -233,10 +233,27 @@ static HRESULT WINAPI errorrec_AddErrorRecord(IErrorRecords *iface, ERRORINFO *p
     if(!pErrorInfo)
         return E_INVALIDARG;
 
-    entry = heap_alloc(sizeof(*entry));
-    if(!entry)
-        return E_OUTOFMEMORY;
+    if (!This->records)
+    {
+        const unsigned int initial_size = 16;
+        if (!(This->records = heap_alloc(initial_size * sizeof(*This->records))))
+            return E_OUTOFMEMORY;
+
+        This->allocated = initial_size;
+    }
+    else if (This->count == This->allocated)
+    {
+        struct ErrorEntry *new_ptr;
+
+        new_ptr = heap_realloc(This->records, 2 * This->allocated * sizeof(*This->records));
+        if (!new_ptr)
+            return E_OUTOFMEMORY;
+
+        This->records = new_ptr;
+        This->allocated *= 2;
+    }
 
+    entry = This->records + This->count;
     entry->info = *pErrorInfo;
     if(pdispparams)
         entry->dispparams = *pdispparams;
@@ -245,7 +262,7 @@ static HRESULT WINAPI errorrec_AddErrorRecord(IErrorRecords *iface, ERRORINFO *p
         IUnknown_AddRef(entry->unknown);
     entry->lookupID = dwDynamicErrorID;
 
-    list_add_head(&This->errors, &entry->entry);
+    This->count++;
 
     return S_OK;
 }
@@ -260,7 +277,7 @@ static HRESULT WINAPI errorrec_GetBasicErrorInfo(IErrorRecords *iface, ULONG ulR
     if(!pErrorInfo)
         return E_INVALIDARG;
 
-    if(ulRecordNum > list_count(&This->errors))
+    if(ulRecordNum > This->count)
         return DB_E_BADRECORDNUM;
 
     return E_NOTIMPL;
@@ -278,7 +295,7 @@ static HRESULT WINAPI errorrec_GetCustomErrorObject(IErrorRecords *iface, ULONG
 
     *ppObject = NULL;
 
-    if(ulRecordNum > list_count(&This->errors))
+    if(ulRecordNum > This->count)
         return DB_E_BADRECORDNUM;
 
     return E_NOTIMPL;
@@ -294,7 +311,7 @@ static HRESULT WINAPI errorrec_GetErrorInfo(IErrorRecords *iface, ULONG ulRecord
     if (!ppErrorInfo)
         return E_INVALIDARG;
 
-    if(ulRecordNum > list_count(&This->errors))
+    if(ulRecordNum > This->count)
         return DB_E_BADRECORDNUM;
 
     return E_NOTIMPL;
@@ -310,24 +327,24 @@ static HRESULT WINAPI errorrec_GetErrorParameters(IErrorRecords *iface, ULONG ul
     if (!pdispparams)
         return E_INVALIDARG;
 
-    if(ulRecordNum > list_count(&This->errors))
+    if(ulRecordNum > This->count)
         return DB_E_BADRECORDNUM;
 
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI errorrec_GetRecordCount(IErrorRecords *iface, ULONG *records)
+static HRESULT WINAPI errorrec_GetRecordCount(IErrorRecords *iface, ULONG *count)
 {
     ErrorInfoImpl *This = impl_from_IErrorRecords(iface);
 
-    TRACE("(%p)->(%p)\n", This, records);
+    TRACE("(%p)->(%p)\n", This, count);
 
-    if(!records)
+    if(!count)
         return E_INVALIDARG;
 
-    *records = list_count(&This->errors);
+    *count = This->count;
 
-    TRACE("<--(%d)\n", *records);
+    TRACE("<--(%u)\n", *count);
 
     return S_OK;
 }
@@ -362,7 +379,9 @@ HRESULT create_error_info(IUnknown *outer, void **obj)
     This->IErrorRecords_iface.lpVtbl = &ErrorRecordsVtbl;
     This->ref = 1;
 
-    list_init(&This->errors);
+    This->records = NULL;
+    This->allocated = 0;
+    This->count = 0;
 
     *obj = &This->IErrorInfo_iface;
 
diff --git a/dlls/oledb32/oledb_private.h b/dlls/oledb32/oledb_private.h
index 1422b0b..8b1a40f 100644
--- a/dlls/oledb32/oledb_private.h
+++ b/dlls/oledb32/oledb_private.h
@@ -33,6 +33,11 @@ static inline void *heap_alloc_zero(size_t len)
     return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
 }
 
+static inline void *heap_realloc(void *mem, size_t len)
+{
+    return HeapReAlloc(GetProcessHeap(), 0, mem, len);
+}
+
 static inline void *heap_realloc_zero(void *mem, size_t len)
 {
     return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mem, len);




More information about the wine-cvs mailing list