- for (lmax = lcount = tcount = hcount = tidx = 0; tidx < BCACHE_MAXLENGTH; tidx++)
- {
- hashtablep = bcachep -> indextable[tidx];
- if (hashtablep != NULL)
- {
- tcount++;
- for (hidx = 0; hidx < BCACHE_HASHSIZE; hidx++)
- {
- linkp = hashtablep[hidx];
- if (linkp != NULL)
- {
- hcount++;
- for (temp = 0; linkp != NULL; linkp = linkp -> next)
- {
- lcount++;
- temp++;
- }
- if (temp > lmax)
- {
- lmax = temp;
- lmaxt = tidx;
- lmaxh = hidx;
- }
- }
- }
- }
- }
- printf_filtered (" Cached '%s' statistics:\n", id);
- printf_filtered (" Cache hits: %d\n", bcachep -> cache_hits);
- printf_filtered (" Cache misses: %d\n", bcachep -> cache_misses);
- printf_filtered (" Cache hit ratio: %d%%\n", ((bcachep -> cache_hits) * 100) / (bcachep -> cache_hits + bcachep -> cache_misses));
- printf_filtered (" Space used for caching: %d\n", bcachep -> cache_bytes);
- printf_filtered (" Space saved by cache hits: %d\n", bcachep -> cache_savings);
- printf_filtered (" Number of bcache overflows: %d\n", bcachep -> bcache_overflows);
- printf_filtered (" Number of index buckets used: %d\n", tcount);
- printf_filtered (" Number of hash table buckets used: %d\n", hcount);
- printf_filtered (" Number of chained items: %d\n", lcount);
- printf_filtered (" Average hash table population: %d%%\n",
- (hcount * 100) / (tcount * BCACHE_HASHSIZE));
- printf_filtered (" Average chain length %d\n", lcount / hcount);
- printf_filtered (" Maximum chain length %d at %d:%d\n", lmax, lmaxt, lmaxh);
+ /* Count the number of occupied buckets, tally the various string
+ lengths, and measure chain lengths. */
+ {
+ unsigned int b;
+ int *chain_length = XCNEWVEC (int, m_num_buckets + 1);
+ int *entry_size = XCNEWVEC (int, m_unique_count + 1);
+ int stringi = 0;
+
+ occupied_buckets = 0;
+
+ for (b = 0; b < m_num_buckets; b++)
+ {
+ struct bstring *s = m_bucket[b];
+
+ chain_length[b] = 0;
+
+ if (s)
+ {
+ occupied_buckets++;
+
+ while (s)
+ {
+ gdb_assert (b < m_num_buckets);
+ chain_length[b]++;
+ gdb_assert (stringi < m_unique_count);
+ entry_size[stringi++] = s->length;
+ s = s->next;
+ }
+ }
+ }
+
+ /* To compute the median, we need the set of chain lengths
+ sorted. */
+ std::sort (chain_length, chain_length + m_num_buckets);
+ std::sort (entry_size, entry_size + m_unique_count);
+
+ if (m_num_buckets > 0)
+ {
+ max_chain_length = chain_length[m_num_buckets - 1];
+ median_chain_length = chain_length[m_num_buckets / 2];
+ }
+ else
+ {
+ max_chain_length = 0;
+ median_chain_length = 0;
+ }
+ if (m_unique_count > 0)
+ {
+ max_entry_size = entry_size[m_unique_count - 1];
+ median_entry_size = entry_size[m_unique_count / 2];
+ }
+ else
+ {
+ max_entry_size = 0;
+ median_entry_size = 0;
+ }
+
+ xfree (chain_length);
+ xfree (entry_size);
+ }
+
+ printf_filtered (_(" M_Cached '%s' statistics:\n"), type);
+ printf_filtered (_(" Total object count: %ld\n"), m_total_count);
+ printf_filtered (_(" Unique object count: %lu\n"), m_unique_count);
+ printf_filtered (_(" Percentage of duplicates, by count: "));
+ print_percentage (m_total_count - m_unique_count, m_total_count);
+ printf_filtered ("\n");
+
+ printf_filtered (_(" Total object size: %ld\n"), m_total_size);
+ printf_filtered (_(" Unique object size: %ld\n"), m_unique_size);
+ printf_filtered (_(" Percentage of duplicates, by size: "));
+ print_percentage (m_total_size - m_unique_size, m_total_size);
+ printf_filtered ("\n");
+
+ printf_filtered (_(" Max entry size: %d\n"), max_entry_size);
+ printf_filtered (_(" Average entry size: "));
+ if (m_unique_count > 0)
+ printf_filtered ("%ld\n", m_unique_size / m_unique_count);
+ else
+ /* i18n: "Average entry size: (not applicable)". */
+ printf_filtered (_("(not applicable)\n"));
+ printf_filtered (_(" Median entry size: %d\n"), median_entry_size);
+ printf_filtered ("\n");
+
+ printf_filtered (_(" \
+Total memory used by bcache, including overhead: %ld\n"),
+ m_structure_size);
+ printf_filtered (_(" Percentage memory overhead: "));
+ print_percentage (m_structure_size - m_unique_size, m_unique_size);
+ printf_filtered (_(" Net memory savings: "));
+ print_percentage (m_total_size - m_structure_size, m_total_size);
+ printf_filtered ("\n");
+
+ printf_filtered (_(" Hash table size: %3d\n"),
+ m_num_buckets);
+ printf_filtered (_(" Hash table expands: %lu\n"),
+ m_expand_count);
+ printf_filtered (_(" Hash table hashes: %lu\n"),
+ m_total_count + m_expand_hash_count);
+ printf_filtered (_(" Half hash misses: %lu\n"),
+ m_half_hash_miss_count);
+ printf_filtered (_(" Hash table population: "));
+ print_percentage (occupied_buckets, m_num_buckets);
+ printf_filtered (_(" Median hash chain length: %3d\n"),
+ median_chain_length);
+ printf_filtered (_(" Average hash chain length: "));
+ if (m_num_buckets > 0)
+ printf_filtered ("%3lu\n", m_unique_count / m_num_buckets);
+ else
+ /* i18n: "Average hash chain length: (not applicable)". */
+ printf_filtered (_("(not applicable)\n"));
+ printf_filtered (_(" Maximum hash chain length: %3d\n"),
+ max_chain_length);
+ printf_filtered ("\n");
+}
+
+int
+bcache::memory_used ()
+{
+ if (m_total_count == 0)
+ return 0;
+ return obstack_memory_used (&m_cache);