VirtualBox

Changeset 2848 in kBuild


Ignore:
Timestamp:
Aug 30, 2016 2:23:59 PM (9 years ago)
Author:
bird
Message:

nt_fullepath: cache results.

Location:
trunk/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/w32/pathstuff.c

    r2592 r2848  
    9494
    9595#if 1 /* bird */
    96 extern void nt_fullpath(const char *pszPath, char *pszFull, size_t cchFull);
     96extern void nt_fullpath_cached(const char *pszPath, char *pszFull, size_t cchFull);
    9797#endif
    9898
     
    108108#if 1 /* bird */
    109109    if (resolve) {
    110         nt_fullpath(filename, w32_path, sizeof(w32_path));
     110        nt_fullpath_cached(filename, w32_path, sizeof(w32_path));
    111111    } else {
    112112        w32_path[0] = '\0';
  • trunk/src/lib/nt_fullpath.c

    r2455 r2848  
    3333#include <ctype.h>
    3434#include <direct.h>
     35#include <assert.h>
     36
     37
     38/*********************************************************************************************************************************
     39*   Structures and Typedefs                                                                                                      *
     40*********************************************************************************************************************************/
     41typedef 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;
     56typedef NTFULLPATHENTRY *PNTFULLPATHENTRY;
     57
     58
     59/*********************************************************************************************************************************
     60*   Global Variables                                                                                                             *
     61*********************************************************************************************************************************/
     62/** Number of result in the nt_fullpath cache.  */
     63size_t              g_cNtFullPathHashEntries = 0;
     64/** Number of bytes used for nt_fullpath cache result entries. */
     65size_t              g_cbNtFullPathHashEntries = 0;
     66/** Number of hash table collsioins in the nt_fullpath cache.  */
     67size_t              g_cNtFullPathHashCollisions = 0;
     68/** Hash table. */
     69PNTFULLPATHENTRY    g_apNtFullPathHashTab[16381];
     70
    3571
    3672/*
     
    566602}
    567603
     604
     605
     606/**
     607 * A nt_fullpath frontend which caches the result of previous calls.
     608 */
     609void
     610nt_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.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette