VirtualBox

source: kBuild/trunk/src/kmk/strcache2.h@ 1903

Last change on this file since 1903 was 1903, checked in by bird, 16 years ago

strcache2: some cleanup.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.0 KB
Line 
1/* $Id: strcache2.h 1903 2008-10-21 04:25:19Z bird $ */
2/** @file
3 * strcache - New string cache.
4 */
5
6/*
7 * Copyright (c) 2006-2008 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 2 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, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 */
26
27#ifndef ___strcache2_h
28#define ___strcache2_h
29
30#ifndef CHAR_BIT
31# error "include after make.h!"
32#endif
33
34/* string cache memory segment. */
35struct strcache2_seg
36{
37 struct strcache2_seg *next; /* The next cache segment. */
38 char *start; /* The first byte in the segment. */
39 size_t size; /* The size of the segment. */
40 size_t avail; /* The number of available bytes. */
41 char *cursor; /* Allocation cursor. */
42};
43
44/* string cache hash table entry. */
45struct strcache2_entry
46{
47 void *user;
48 unsigned int hash1;
49 unsigned int hash2;
50 unsigned int length;
51};
52
53/* The entry alignment, cacheline size if it's known & sensible.
54
55 On x86/AMD64 we assume a 64-byte cacheline size. As it is difficult to
56 guess other right now, these default 16 chars as that shouldn't cause
57 much trouble, even if it not the most optimial value. Override, or modify
58 for other platforms. */
59#ifndef STRCACHE2_ENTRY_ALIGN_SHIFT
60# if defined (__i386__) || defined(__x86_64__)
61# define STRCACHE2_ENTRY_ALIGN_SHIFT 6
62# else
63# define STRCACHE2_ENTRY_ALIGN_SHIFT 4
64# endif
65#endif
66#define STRCACHE2_ENTRY_ALIGNMENT (1 << STRCACHE2_ENTRY_ALIGN_SHIFT)
67
68
69struct strcache2
70{
71 struct strcache2_entry **hash_tab; /* The hash table. */
72 int case_insensitive; /* case insensitive or not. */
73 unsigned int hash_mask; /* The AND mask matching hash_size.*/
74 unsigned long lookup_count; /* The number of lookups. */
75 unsigned long collision_1st_count; /* The number of 1st level collisions. */
76 unsigned long collision_2nd_count; /* The number of 2nd level collisions. */
77 unsigned long collision_3rd_count; /* The number of 3rd level collisions. */
78 unsigned int count; /* Number entries in the cache. */
79 unsigned int rehash_count; /* When to rehash the table. */
80 unsigned int init_size; /* The initial hash table size. */
81 unsigned int hash_size; /* The hash table size. */
82 unsigned int def_seg_size; /* The default segment size. */
83 void *lock; /* The lock handle. */
84 struct strcache2_seg *seg_head; /* The memory segment list. */
85 struct strcache2 *next; /* The next string cache. */
86 const char *name; /* Cache name. */
87};
88
89
90void strcache2_init (struct strcache2 *cache, const char *name, unsigned int size,
91 unsigned int def_seg_size, int case_insensitive, int thread_safe);
92void strcache2_term (struct strcache2 *cache);
93void strcache2_print_stats (struct strcache2 *cache, const char *prefix);
94void strcache2_print_stats_all (const char *prefix);
95const char *strcache2_add (struct strcache2 *cache, const char *str, unsigned int length);
96const char *strcache2_iadd (struct strcache2 *cache, const char *str, unsigned int length);
97const char *strcache2_add_hashed (struct strcache2 *cache, const char *str, unsigned int length,
98 unsigned int hash1, unsigned int hash2);
99const char *strcache2_iadd_hashed (struct strcache2 *cache, const char *str, unsigned int length,
100 unsigned int hash1, unsigned int hash2);
101const char *strcache2_lookup (struct strcache2 *cache, const char *str, unsigned int length);
102const char *strcache2_ilookup (struct strcache2 *cache, const char *str, unsigned int length);
103#ifdef HAVE_CASE_INSENSITIVE_FS
104# define strcache2_add_file strcache2_iadd
105# define strcache2_add_hashed_file strcache2_iadd_hashed
106# define strcache2_lookup_file strcache2_ilookup
107#else
108# define strcache2_add_file strcache2_add
109# define strcache2_add_hashed_file strcache2_add_hashed
110# define strcache2_lookup_file strcache2_lookup
111#endif
112int strcache2_is_cached (struct strcache2 *cache, const char *str);
113int strcache2_verify_entry (struct strcache2 *cache, const char *str);
114unsigned int strcache2_get_hash2_fallback (struct strcache2 *cache, const char *str);
115unsigned int strcache2_hash_str (const char *str, unsigned int length, unsigned int *hash2p);
116unsigned int strcache2_hash_istr (const char *str, unsigned int length, unsigned int *hash2p);
117
118/* Get the hash table entry pointer. */
119MY_INLINE struct strcache2_entry const *
120strcache2_get_entry (struct strcache2 *cache, const char *str)
121{
122#ifndef NDEBUG
123 strcache2_verify_entry (cache, str);
124#endif
125 return (struct strcache2_entry const *)str - 1;
126}
127
128/* Get the string length. */
129MY_INLINE unsigned int
130strcache2_get_len (struct strcache2 *cache, const char *str)
131{
132 return strcache2_get_entry (cache, str)->length;
133}
134
135/* Get the first hash value for the string. */
136MY_INLINE unsigned int
137strcache2_get_hash1 (struct strcache2 *cache, const char *str)
138{
139 return strcache2_get_entry (cache, str)->hash1;
140}
141
142/* Get the second hash value for the string. */
143MY_INLINE unsigned int
144strcache2_get_hash2 (struct strcache2 *cache, const char *str)
145{
146 unsigned int hash2 = strcache2_get_entry (cache, str)->hash2;
147 if (!hash2)
148 hash2 = strcache2_get_hash2_fallback (cache, str);
149 return hash2;
150}
151
152/* Get the pointer hash value for the string.
153
154 This takes the string address, shift out the bits that are always zero
155 due to alignment, and then returns the unsigned integer value of it.
156
157 The results from using this is generally better than for any of the
158 other hash values. It is also sligtly faster code as it does not
159 involve any memory accesses, just a right SHIFT and an optional AND. */
160MY_INLINE unsigned int
161strcache2_get_ptr_hash (struct strcache2 *cache, const char *str)
162{
163 (void)cache;
164 return (size_t)str >> STRCACHE2_ENTRY_ALIGN_SHIFT;
165}
166
167/* Get the user value for the string. */
168MY_INLINE void *
169strcache2_get_user_val (struct strcache2 *cache, const char *str)
170{
171 return strcache2_get_entry (cache, str)->user;
172}
173
174/* Get the user value for the string. */
175MY_INLINE void
176strcache2_set_user_val (struct strcache2 *cache, const char *str, void *value)
177{
178 struct strcache2_entry *entry = (struct strcache2_entry *)str - 1;
179#ifndef NDEBUG
180 strcache2_verify_entry (cache, str);
181#endif
182 entry->user = value;
183}
184
185#endif
186
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