1 /* Implement a cached obstack.
2 Written by Fred Fish (fnf@cygnus.com)
3 Copyright 1995 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24 #include "gdb_string.h" /* For memcpy declaration */
26 static unsigned int hash
PARAMS ((void *, int));
27 static void *lookup_cache
PARAMS ((void *, int, int, struct bcache
*));
29 /* FIXME: Incredibly simplistic hash generator. Probably way too expensive
30 (consider long strings) and unlikely to have good distribution across hash
31 values for typical input. */
39 unsigned long hashval
;
41 const unsigned char *data
= bytes
;
48 hashval
+= c
+ (c
<< 17);
49 hashval
^= hashval
>> 2;
52 hashval
+= len
+ (len
<< 17);
53 hashval
^= hashval
>> 2;
54 return (hashval
% BCACHE_HASHSIZE
);
58 lookup_cache (bytes
, count
, hashval
, bcachep
)
62 struct bcache
*bcachep
;
64 void *location
= NULL
;
65 struct hashlink
**hashtablep
;
66 struct hashlink
*linkp
;
68 hashtablep
= bcachep
-> indextable
[count
];
69 if (hashtablep
!= NULL
)
71 linkp
= hashtablep
[hashval
];
74 if (memcmp (BCACHE_DATA (linkp
), bytes
, count
) == 0)
76 location
= BCACHE_DATA (linkp
);
79 linkp
= linkp
-> next
;
86 bcache (bytes
, count
, bcachep
)
89 struct bcache
*bcachep
;
93 struct hashlink
*newlink
;
94 struct hashlink
**linkpp
;
95 struct hashlink
***hashtablepp
;
97 if (count
>= BCACHE_MAXLENGTH
)
99 /* Rare enough to just stash unique copies */
100 location
= (void *) obstack_alloc (&bcachep
->cache
, count
);
101 bcachep
-> cache_bytes
+= count
;
102 memcpy (location
, bytes
, count
);
103 bcachep
-> bcache_overflows
++;
107 hashval
= hash (bytes
, count
);
108 location
= lookup_cache (bytes
, count
, hashval
, bcachep
);
109 if (location
!= NULL
)
111 bcachep
-> cache_savings
+= count
;
112 bcachep
-> cache_hits
++;
116 bcachep
-> cache_misses
++;
117 hashtablepp
= &bcachep
-> indextable
[count
];
118 if (*hashtablepp
== NULL
)
120 *hashtablepp
= (struct hashlink
**)
121 obstack_alloc (&bcachep
->cache
, BCACHE_HASHSIZE
* sizeof (struct hashlink
*));
122 bcachep
-> cache_bytes
+= BCACHE_HASHSIZE
* sizeof (struct hashlink
*);
123 memset (*hashtablepp
, 0, BCACHE_HASHSIZE
* sizeof (struct hashlink
*));
125 linkpp
= &(*hashtablepp
)[hashval
];
126 newlink
= (struct hashlink
*)
127 obstack_alloc (&bcachep
->cache
, BCACHE_DATA_ALIGNMENT
+ count
);
128 bcachep
-> cache_bytes
+= BCACHE_DATA_ALIGNMENT
+ count
;
129 memcpy (BCACHE_DATA (newlink
), bytes
, count
);
130 newlink
-> next
= *linkpp
;
132 location
= BCACHE_DATA (newlink
);
141 print_bcache_statistics (bcachep
, id
)
142 struct bcache
*bcachep
;
145 struct hashlink
**hashtablep
;
146 struct hashlink
*linkp
;
147 int tidx
, tcount
, hidx
, hcount
, lcount
, lmax
, temp
, lmaxt
, lmaxh
;
149 for (lmax
= lcount
= tcount
= hcount
= tidx
= 0; tidx
< BCACHE_MAXLENGTH
; tidx
++)
151 hashtablep
= bcachep
-> indextable
[tidx
];
152 if (hashtablep
!= NULL
)
155 for (hidx
= 0; hidx
< BCACHE_HASHSIZE
; hidx
++)
157 linkp
= hashtablep
[hidx
];
161 for (temp
= 0; linkp
!= NULL
; linkp
= linkp
-> next
)
176 printf_filtered (" Cached '%s' statistics:\n", id
);
177 printf_filtered (" Cache hits: %d\n", bcachep
-> cache_hits
);
178 printf_filtered (" Cache misses: %d\n", bcachep
-> cache_misses
);
179 printf_filtered (" Cache hit ratio: ");
180 if (bcachep
-> cache_hits
+ bcachep
-> cache_misses
> 0)
182 printf_filtered ("%d%%\n", ((bcachep
-> cache_hits
) * 100) /
183 (bcachep
-> cache_hits
+ bcachep
-> cache_misses
));
187 printf_filtered ("(not applicable)\n");
189 printf_filtered (" Space used for caching: %d\n", bcachep
-> cache_bytes
);
190 printf_filtered (" Space saved by cache hits: %d\n", bcachep
-> cache_savings
);
191 printf_filtered (" Number of bcache overflows: %d\n", bcachep
-> bcache_overflows
);
192 printf_filtered (" Number of index buckets used: %d\n", tcount
);
193 printf_filtered (" Number of hash table buckets used: %d\n", hcount
);
194 printf_filtered (" Number of chained items: %d\n", lcount
);
195 printf_filtered (" Average hash table population: ");
198 printf_filtered ("%d%%\n", (hcount
* 100) / (tcount
* BCACHE_HASHSIZE
));
202 printf_filtered ("(not applicable)\n");
204 printf_filtered (" Average chain length ");
207 printf_filtered ("%d\n", lcount
/ hcount
);
211 printf_filtered ("(not applicable)\n");
213 printf_filtered (" Maximum chain length %d at %d:%d\n", lmax
, lmaxt
, lmaxh
);
216 #endif /* MAINTENANCE_CMDS */
This page took 0.033106 seconds and 4 git commands to generate.