Changeset 2849 in kBuild for trunk/src/lib/nt_fullpath.c
- Timestamp:
- Aug 30, 2016 2:28:46 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/nt_fullpath.c
r2848 r2849 33 33 #include <ctype.h> 34 34 #include <direct.h> 35 #include <assert.h> 36 37 38 /********************************************************************************************************************************* 39 * Structures and Typedefs * 40 *********************************************************************************************************************************/ 41 typedef struct NTFULLPATHENTRY 42 { 43 /** Pointer to the next entry with the same hash table index. */ 44 struct NTFULLPATHENTRY *pNext; 45 /** The input hash. */ 46 unsigned uHash; 47 /** The input length. */ 48 unsigned cchInput; 49 /** Length of the result. */ 50 unsigned cchResult; 51 /** The result string (stored immediately after this structure). */ 52 const char *pszResult; 53 /** The input string (variable length). */ 54 char szInput[1]; 55 } NTFULLPATHENTRY; 56 typedef NTFULLPATHENTRY *PNTFULLPATHENTRY; 57 58 59 /********************************************************************************************************************************* 60 * Global Variables * 61 *********************************************************************************************************************************/ 62 /** Number of result in the nt_fullpath cache. */ 63 size_t g_cNtFullPathHashEntries = 0; 64 /** Number of bytes used for nt_fullpath cache result entries. */ 65 size_t g_cbNtFullPathHashEntries = 0; 66 /** Number of hash table collsioins in the nt_fullpath cache. */ 67 size_t g_cNtFullPathHashCollisions = 0; 68 /** Hash table. */ 69 PNTFULLPATHENTRY g_apNtFullPathHashTab[16381]; 35 36 #include "nt_fullpath.h" 70 37 71 38 … … 602 569 } 603 570 604 605 606 /**607 * A nt_fullpath frontend which caches the result of previous calls.608 */609 void610 nt_fullpath_cached(const char *pszPath, char *pszFull, size_t cchFull)611 {612 PNTFULLPATHENTRY pEntry;613 unsigned cchInput;614 unsigned idx;615 unsigned cchResult;616 617 /* We use the sdbm hash algorithm here (see kDep.c for full details). */618 unsigned const char *puch = (unsigned const char *)pszPath;619 unsigned uHash = 0;620 unsigned uChar;621 while ((uChar = *puch++) != 0)622 uHash = uChar + (uHash << 6) + (uHash << 16) - uHash;623 624 cchInput = (unsigned)((uintptr_t)&puch[-1] - (uintptr_t)pszPath);625 626 /* Do the cache lookup. */627 idx = uHash % (sizeof(g_apNtFullPathHashTab) / sizeof(g_apNtFullPathHashTab[0]));628 for (pEntry = g_apNtFullPathHashTab[idx]; pEntry != NULL; pEntry = pEntry->pNext)629 if ( pEntry->uHash == uHash630 && pEntry->cchInput == cchInput631 && memcmp(pEntry->szInput, pszPath, cchInput) == 0)632 {633 if (cchFull > pEntry->cchResult)634 memcpy(pszFull, pEntry->pszResult, pEntry->cchResult + 1);635 else636 {637 assert(0);638 memcpy(pszFull, pEntry->pszResult, cchFull);639 pszFull[cchFull - 1] = '\0';640 }641 return;642 }643 644 /* Make the call... */645 nt_fullpath(pszPath, pszFull, cchFull);646 647 /* ... and cache the result. */648 cchResult = (unsigned)strlen(pszFull);649 pEntry = malloc(sizeof(*pEntry) + cchInput + cchResult + 1);650 if (pEntry)651 {652 g_cbNtFullPathHashEntries += sizeof(*pEntry) + cchInput + cchResult + 1;653 pEntry->cchInput = cchInput;654 pEntry->cchResult = cchResult;655 pEntry->pszResult = &pEntry->szInput[cchInput + 1];656 pEntry->uHash = uHash;657 memcpy(pEntry->szInput, pszPath, cchInput + 1);658 memcpy((char *)pEntry->pszResult, pszFull, cchResult + 1);659 660 pEntry->pNext = g_apNtFullPathHashTab[idx];661 if (pEntry->pNext)662 g_cNtFullPathHashCollisions++;663 g_apNtFullPathHashTab[idx] = pEntry;664 665 g_cNtFullPathHashEntries++;666 }667 }668
Note:
See TracChangeset
for help on using the changeset viewer.