VirtualBox

source: kBuild/trunk/src/lib/nt_fullpath_cached.c@ 3184

Last change on this file since 3184 was 2849, checked in by bird, 9 years ago

split nt_fullpath_cached out into its own file.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.1 KB
Line 
1/* $Id: nt_fullpath_cached.c 2849 2016-08-30 14:28:46Z bird $ */
2/** @file
3 * fixcase - fixes the case of paths, windows specific.
4 */
5
6/*
7 * Copyright (c) 2004-2010 knut st. osmundsen <[email protected]>
8 *
9 * This file is part of kBuild.
10 *
11 * kBuild is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * kBuild is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with kBuild. If not, see <http://www.gnu.org/licenses/>
23 *
24 */
25
26/*******************************************************************************
27* Header Files *
28*******************************************************************************/
29#include <Windows.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33#include <ctype.h>
34#include <direct.h>
35#include <assert.h>
36
37#include "nt_fullpath.h"
38
39
40/*********************************************************************************************************************************
41* Structures and Typedefs *
42*********************************************************************************************************************************/
43typedef struct NTFULLPATHENTRY
44{
45 /** Pointer to the next entry with the same hash table index. */
46 struct NTFULLPATHENTRY *pNext;
47 /** The input hash. */
48 unsigned uHash;
49 /** The input length. */
50 unsigned cchInput;
51 /** Length of the result. */
52 unsigned cchResult;
53 /** The result string (stored immediately after this structure). */
54 const char *pszResult;
55 /** The input string (variable length). */
56 char szInput[1];
57} NTFULLPATHENTRY;
58typedef NTFULLPATHENTRY *PNTFULLPATHENTRY;
59
60
61/*********************************************************************************************************************************
62* Global Variables *
63*********************************************************************************************************************************/
64/** Number of result in the nt_fullpath cache. */
65size_t g_cNtFullPathHashEntries = 0;
66/** Number of bytes used for nt_fullpath cache result entries. */
67size_t g_cbNtFullPathHashEntries = 0;
68/** Number of hash table collsioins in the nt_fullpath cache. */
69size_t g_cNtFullPathHashCollisions = 0;
70/** Hash table. */
71PNTFULLPATHENTRY g_apNtFullPathHashTab[16381];
72
73
74/**
75 * A nt_fullpath frontend which caches the result of previous calls.
76 */
77void
78nt_fullpath_cached(const char *pszPath, char *pszFull, size_t cchFull)
79{
80 PNTFULLPATHENTRY pEntry;
81 unsigned cchInput;
82 unsigned idx;
83 unsigned cchResult;
84
85 /* We use the sdbm hash algorithm here (see kDep.c for full details). */
86 unsigned const char *puch = (unsigned const char *)pszPath;
87 unsigned uHash = 0;
88 unsigned uChar;
89 while ((uChar = *puch++) != 0)
90 uHash = uChar + (uHash << 6) + (uHash << 16) - uHash;
91
92 cchInput = (unsigned)((uintptr_t)&puch[-1] - (uintptr_t)pszPath);
93
94 /* Do the cache lookup. */
95 idx = uHash % (sizeof(g_apNtFullPathHashTab) / sizeof(g_apNtFullPathHashTab[0]));
96 for (pEntry = g_apNtFullPathHashTab[idx]; pEntry != NULL; pEntry = pEntry->pNext)
97 if ( pEntry->uHash == uHash
98 && pEntry->cchInput == cchInput
99 && memcmp(pEntry->szInput, pszPath, cchInput) == 0)
100 {
101 if (cchFull > pEntry->cchResult)
102 memcpy(pszFull, pEntry->pszResult, pEntry->cchResult + 1);
103 else
104 {
105 assert(0);
106 memcpy(pszFull, pEntry->pszResult, cchFull);
107 pszFull[cchFull - 1] = '\0';
108 }
109 return;
110 }
111
112 /* Make the call... */
113 nt_fullpath(pszPath, pszFull, cchFull);
114
115 /* ... and cache the result. */
116 cchResult = (unsigned)strlen(pszFull);
117 pEntry = malloc(sizeof(*pEntry) + cchInput + cchResult + 1);
118 if (pEntry)
119 {
120 g_cbNtFullPathHashEntries += sizeof(*pEntry) + cchInput + cchResult + 1;
121 pEntry->cchInput = cchInput;
122 pEntry->cchResult = cchResult;
123 pEntry->pszResult = &pEntry->szInput[cchInput + 1];
124 pEntry->uHash = uHash;
125 memcpy(pEntry->szInput, pszPath, cchInput + 1);
126 memcpy((char *)pEntry->pszResult, pszFull, cchResult + 1);
127
128 pEntry->pNext = g_apNtFullPathHashTab[idx];
129 if (pEntry->pNext)
130 g_cNtFullPathHashCollisions++;
131 g_apNtFullPathHashTab[idx] = pEntry;
132
133 g_cNtFullPathHashEntries++;
134 }
135}
136
Note: See TracBrowser for help on using the repository browser.

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