Changeset 2848 in kBuild
- Timestamp:
- Aug 30, 2016 2:23:59 PM (9 years ago)
- Location:
- trunk/src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/w32/pathstuff.c
r2592 r2848 94 94 95 95 #if 1 /* bird */ 96 extern void nt_fullpath (const char *pszPath, char *pszFull, size_t cchFull);96 extern void nt_fullpath_cached(const char *pszPath, char *pszFull, size_t cchFull); 97 97 #endif 98 98 … … 108 108 #if 1 /* bird */ 109 109 if (resolve) { 110 nt_fullpath (filename, w32_path, sizeof(w32_path));110 nt_fullpath_cached(filename, w32_path, sizeof(w32_path)); 111 111 } else { 112 112 w32_path[0] = '\0'; -
trunk/src/lib/nt_fullpath.c
r2455 r2848 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]; 70 35 71 36 72 /* … … 566 602 } 567 603 604 605 606 /** 607 * A nt_fullpath frontend which caches the result of previous calls. 608 */ 609 void 610 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 == uHash 630 && pEntry->cchInput == cchInput 631 && memcmp(pEntry->szInput, pszPath, cchInput) == 0) 632 { 633 if (cchFull > pEntry->cchResult) 634 memcpy(pszFull, pEntry->pszResult, pEntry->cchResult + 1); 635 else 636 { 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.