From 56105916271ff9a7c0bfa237b45b9b3fab9c570b Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Wed, 9 Jun 2021 11:30:46 -0500 Subject: Fix building and perf for bundles with 1000s of package and BA payloads Fixes other half of #5300 --- src/libs/dutil/WixToolset.DUtil/dictutil.cpp | 128 ++++++++++++--------------- 1 file changed, 58 insertions(+), 70 deletions(-) (limited to 'src/libs/dutil/WixToolset.DUtil/dictutil.cpp') diff --git a/src/libs/dutil/WixToolset.DUtil/dictutil.cpp b/src/libs/dutil/WixToolset.DUtil/dictutil.cpp index 0d0743eb..09b150df 100644 --- a/src/libs/dutil/WixToolset.DUtil/dictutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/dictutil.cpp @@ -72,6 +72,14 @@ struct STRINGDICT_STRUCT const int STRINGDICT_HANDLE_BYTES = sizeof(STRINGDICT_STRUCT); +static HRESULT CreateDict( + __out_bcount(STRINGDICT_HANDLE_BYTES) STRINGDICT_HANDLE* psdHandle, + __in DICT_TYPE dtType, + __in DWORD dwNumExpectedItems, + __in_opt void** ppvArray, + __in size_t cByteOffset, + __in DICT_FLAG dfFlags + ); static HRESULT StringHash( __in const STRINGDICT_STRUCT *psd, __in DWORD dwNumBuckets, @@ -135,41 +143,7 @@ extern "C" HRESULT DAPI DictCreateWithEmbeddedKey( __in DICT_FLAG dfFlags ) { - HRESULT hr = S_OK; - - DictExitOnNull(psdHandle, hr, E_INVALIDARG, "Handle not specified while creating dict"); - - // Allocate the handle - *psdHandle = static_cast(MemAlloc(sizeof(STRINGDICT_STRUCT), FALSE)); - DictExitOnNull(*psdHandle, hr, E_OUTOFMEMORY, "Failed to allocate dictionary object"); - - STRINGDICT_STRUCT *psd = static_cast(*psdHandle); - - // Fill out the new handle's values - psd->dtType = DICT_EMBEDDED_KEY; - psd->dfFlags = dfFlags; - psd->cByteOffset = cByteOffset; - psd->dwBucketSizeIndex = 0; - psd->dwNumItems = 0; - psd->ppvItemList = NULL; - psd->ppvValueArray = ppvArray; - - // Make psd->dwBucketSizeIndex point to the appropriate spot in the prime - // array based on expected number of items and items to buckets ratio - // Careful: the "-1" in "countof(MAX_BUCKET_SIZES)-1" ensures we don't end - // this loop past the end of the array! - while (psd->dwBucketSizeIndex < (countof(MAX_BUCKET_SIZES)-1) && - MAX_BUCKET_SIZES[psd->dwBucketSizeIndex] < dwNumExpectedItems * MAX_BUCKETS_TO_ITEMS_RATIO) - { - ++psd->dwBucketSizeIndex; - } - - // Finally, allocate our initial buckets - psd->ppvBuckets = static_cast(MemAlloc(sizeof(void *) * MAX_BUCKET_SIZES[psd->dwBucketSizeIndex], TRUE)); - DictExitOnNull(psd->ppvBuckets, hr, E_OUTOFMEMORY, "Failed to allocate buckets for dictionary"); - -LExit: - return hr; + return CreateDict(psdHandle, DICT_EMBEDDED_KEY, dwNumExpectedItems, ppvArray, cByteOffset, dfFlags); } // The dict will store a set of keys, with no values associated with them. Use DictAddKey() and DictKeyExists() with this dictionary type. @@ -179,41 +153,7 @@ extern "C" HRESULT DAPI DictCreateStringList( __in DICT_FLAG dfFlags ) { - HRESULT hr = S_OK; - - DictExitOnNull(psdHandle, hr, E_INVALIDARG, "Handle not specified while creating dict"); - - // Allocate the handle - *psdHandle = static_cast(MemAlloc(sizeof(STRINGDICT_STRUCT), FALSE)); - DictExitOnNull(*psdHandle, hr, E_OUTOFMEMORY, "Failed to allocate dictionary object"); - - STRINGDICT_STRUCT *psd = static_cast(*psdHandle); - - // Fill out the new handle's values - psd->dtType = DICT_STRING_LIST; - psd->dfFlags = dfFlags; - psd->cByteOffset = 0; - psd->dwBucketSizeIndex = 0; - psd->dwNumItems = 0; - psd->ppvItemList = NULL; - psd->ppvValueArray = NULL; - - // Make psd->dwBucketSizeIndex point to the appropriate spot in the prime - // array based on expected number of items and items to buckets ratio - // Careful: the "-1" in "countof(MAX_BUCKET_SIZES)-1" ensures we don't end - // this loop past the end of the array! - while (psd->dwBucketSizeIndex < (countof(MAX_BUCKET_SIZES)-1) && - MAX_BUCKET_SIZES[psd->dwBucketSizeIndex] < dwNumExpectedItems * MAX_BUCKETS_TO_ITEMS_RATIO) - { - ++psd->dwBucketSizeIndex; - } - - // Finally, allocate our initial buckets - psd->ppvBuckets = static_cast(MemAlloc(sizeof(void *) * MAX_BUCKET_SIZES[psd->dwBucketSizeIndex], TRUE)); - DictExitOnNull(psd->ppvBuckets, hr, E_OUTOFMEMORY, "Failed to allocate buckets for dictionary"); - -LExit: - return hr; + return CreateDict(psdHandle, DICT_STRING_LIST, dwNumExpectedItems, NULL, 0, dfFlags); } extern "C" HRESULT DAPI DictCreateStringListFromArray( @@ -467,6 +407,54 @@ extern "C" void DAPI DictDestroy( ReleaseMem(psd); } +static HRESULT CreateDict( + __out_bcount(STRINGDICT_HANDLE_BYTES) STRINGDICT_HANDLE* psdHandle, + __in DICT_TYPE dtType, + __in DWORD dwNumExpectedItems, + __in_opt void** ppvArray, + __in size_t cByteOffset, + __in DICT_FLAG dfFlags + ) +{ + HRESULT hr = S_OK; + + DictExitOnNull(psdHandle, hr, E_INVALIDARG, "Handle not specified while creating dict."); + + // Allocate the handle + *psdHandle = static_cast(MemAlloc(sizeof(STRINGDICT_STRUCT), TRUE)); + DictExitOnNull(*psdHandle, hr, E_OUTOFMEMORY, "Failed to allocate dictionary object."); + + STRINGDICT_STRUCT* psd = static_cast(*psdHandle); + + // Fill out the new handle's values + psd->dtType = dtType; + psd->dfFlags = dfFlags; + psd->cByteOffset = cByteOffset; + psd->ppvValueArray = ppvArray; + + // Make psd->dwBucketSizeIndex point to the appropriate spot in the prime + // array based on expected number of items and items to buckets ratio + // Careful: the "-1" in "countof(MAX_BUCKET_SIZES)-1" ensures we don't end + // this loop past the end of the array! + while (psd->dwBucketSizeIndex < (countof(MAX_BUCKET_SIZES) - 1) && + MAX_BUCKET_SIZES[psd->dwBucketSizeIndex] < dwNumExpectedItems * MAX_BUCKETS_TO_ITEMS_RATIO) + { + ++psd->dwBucketSizeIndex; + } + + hr = MemAllocArray(reinterpret_cast(&psd->ppvBuckets), sizeof(void*), MAX_BUCKET_SIZES[psd->dwBucketSizeIndex]); + DictExitOnFailure(hr, "Failed to allocate buckets for dictionary."); + + if (dwNumExpectedItems) + { + hr = MemAllocArray(reinterpret_cast(&psd->ppvItemList), sizeof(void*), dwNumExpectedItems); + DictExitOnFailure(hr, "Failed to pre-allocate item list for dictionary."); + } + +LExit: + return hr; +} + static HRESULT StringHash( __in const STRINGDICT_STRUCT *psd, __in DWORD dwNumBuckets, -- cgit v1.2.3-55-g6feb