Written by Fred Fish <fnf@cygnus.com>
Rewritten by Jim Blandy <jimb@cygnus.com>
- Copyright (C) 1999-2019 Free Software Foundation, Inc.
+ Copyright (C) 1999-2022 Free Software Foundation, Inc.
This file is part of GDB.
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
-#include "gdb_obstack.h"
+#include "gdbsupport/gdb_obstack.h"
#include "bcache.h"
#include <algorithm>
+namespace gdb {
+
/* The type used to hold a single bcache string. The user data is
stored in d.data. Since it can be any type, it needs to have the
same alignment as the most strict alignment of any type on the host
d;
};
-/* The old hash function was stolen from SDBM. This is what DB 3.0
- uses now, and is better than the old one. */
-\f
-unsigned long
-hash(const void *addr, int length)
-{
- return hash_continue (addr, length, 0);
-}
-
-/* Continue the calculation of the hash H at the given address. */
-
-unsigned long
-hash_continue (const void *addr, int length, unsigned long h)
-{
- const unsigned char *k, *e;
-
- k = (const unsigned char *)addr;
- e = k+length;
- for (; k< e;++k)
- {
- h *=16777619;
- h ^= *k;
- }
- return (h);
-}
\f
/* Growing the bcache's hash table. */
so we roughly double the table size each time. After we fall off
the end of this table, we just double. Don't laugh --- there have
been executables sighted with a gigabyte of debug info. */
- static unsigned long sizes[] = {
+ static const unsigned long sizes[] = {
1021, 2053, 4099, 8191, 16381, 32771,
65537, 131071, 262144, 524287, 1048573, 2097143,
4194301, 8388617, 16777213, 33554467, 67108859, 134217757,
/* Find the next size. */
new_num_buckets = m_num_buckets * 2;
- for (i = 0; i < (sizeof (sizes) / sizeof (sizes[0])); i++)
- if (sizes[i] > m_num_buckets)
+ for (unsigned long a_size : sizes)
+ if (a_size > m_num_buckets)
{
- new_num_buckets = sizes[i];
+ new_num_buckets = a_size;
break;
}
struct bstring **new_bucket;
next = s->next;
- new_bucket = &new_buckets[(m_hash_function (&s->d.data, s->length)
+ new_bucket = &new_buckets[(this->hash (&s->d.data, s->length)
% new_num_buckets)];
s->next = *new_bucket;
*new_bucket = s;
returning an old entry. */
const void *
-bcache::insert (const void *addr, int length, int *added)
+bcache::insert (const void *addr, int length, bool *added)
{
unsigned long full_hash;
unsigned short half_hash;
int hash_index;
struct bstring *s;
- if (added)
- *added = 0;
+ if (added != nullptr)
+ *added = false;
/* Lazily initialize the obstack. This can save quite a bit of
memory in some cases. */
m_total_count++;
m_total_size += length;
- full_hash = m_hash_function (addr, length);
+ full_hash = this->hash (addr, length);
half_hash = (full_hash >> 16);
hash_index = full_hash % m_num_buckets;
if (s->half_hash == half_hash)
{
if (s->length == length
- && m_compare_function (&s->d.data, addr, length))
+ && this->compare (&s->d.data, addr, length))
return &s->d.data;
else
m_half_hash_miss_count++;
m_unique_size += length;
m_structure_size += BSTRING_SIZE (length);
- if (added)
- *added = 1;
+ if (added != nullptr)
+ *added = true;
return &newobj->d.data;
}
}
\f
-/* Compare the byte string at ADDR1 of lenght LENGHT to the
- string at ADDR2. Return 1 if they are equal. */
+/* See bcache.h. */
+
+unsigned long
+bcache::hash (const void *addr, int length)
+{
+ return fast_hash (addr, length, 0);
+}
+
+/* See bcache.h. */
int
-bcache::compare (const void *addr1, const void *addr2, int length)
+bcache::compare (const void *left, const void *right, int length)
{
- return memcmp (addr1, addr2, length) == 0;
+ return memcmp (left, right, length) == 0;
}
/* Free all the storage associated with BCACHE. */
{
if (total == 0)
/* i18n: Like "Percentage of duplicates, by count: (not applicable)". */
- printf_filtered (_("(not applicable)\n"));
+ gdb_printf (_("(not applicable)\n"));
else
- printf_filtered ("%3d%%\n", (int) (portion * 100.0 / total));
+ gdb_printf ("%3d%%\n", (int) (portion * 100.0 / total));
}
/* Print statistics on BCACHE's memory usage and efficacity at
eliminating duplication. NAME should describe the kind of data
- BCACHE holds. Statistics are printed using `printf_filtered' and
+ BCACHE holds. Statistics are printed using `gdb_printf' and
its ilk. */
void
bcache::print_statistics (const char *type)
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: "));
+ gdb_printf (_(" M_Cached '%s' statistics:\n"), type);
+ gdb_printf (_(" Total object count: %ld\n"), m_total_count);
+ gdb_printf (_(" Unique object count: %lu\n"), m_unique_count);
+ gdb_printf (_(" Percentage of duplicates, by count: "));
print_percentage (m_total_count - m_unique_count, m_total_count);
- printf_filtered ("\n");
+ gdb_printf ("\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: "));
+ gdb_printf (_(" Total object size: %ld\n"), m_total_size);
+ gdb_printf (_(" Unique object size: %ld\n"), m_unique_size);
+ gdb_printf (_(" Percentage of duplicates, by size: "));
print_percentage (m_total_size - m_unique_size, m_total_size);
- printf_filtered ("\n");
+ gdb_printf ("\n");
- printf_filtered (_(" Max entry size: %d\n"), max_entry_size);
- printf_filtered (_(" Average entry size: "));
+ gdb_printf (_(" Max entry size: %d\n"), max_entry_size);
+ gdb_printf (_(" Average entry size: "));
if (m_unique_count > 0)
- printf_filtered ("%ld\n", m_unique_size / m_unique_count);
+ gdb_printf ("%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");
+ gdb_printf (_("(not applicable)\n"));
+ gdb_printf (_(" Median entry size: %d\n"), median_entry_size);
+ gdb_printf ("\n");
- printf_filtered (_(" \
+ gdb_printf (_(" \
Total memory used by bcache, including overhead: %ld\n"),
- m_structure_size);
- printf_filtered (_(" Percentage memory overhead: "));
+ m_structure_size);
+ gdb_printf (_(" Percentage memory overhead: "));
print_percentage (m_structure_size - m_unique_size, m_unique_size);
- printf_filtered (_(" Net memory savings: "));
+ gdb_printf (_(" 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: "));
+ gdb_printf ("\n");
+
+ gdb_printf (_(" Hash table size: %3d\n"),
+ m_num_buckets);
+ gdb_printf (_(" Hash table expands: %lu\n"),
+ m_expand_count);
+ gdb_printf (_(" Hash table hashes: %lu\n"),
+ m_total_count + m_expand_hash_count);
+ gdb_printf (_(" Half hash misses: %lu\n"),
+ m_half_hash_miss_count);
+ gdb_printf (_(" 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: "));
+ gdb_printf (_(" Median hash chain length: %3d\n"),
+ median_chain_length);
+ gdb_printf (_(" Average hash chain length: "));
if (m_num_buckets > 0)
- printf_filtered ("%3lu\n", m_unique_count / m_num_buckets);
+ gdb_printf ("%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");
+ gdb_printf (_("(not applicable)\n"));
+ gdb_printf (_(" Maximum hash chain length: %3d\n"),
+ max_chain_length);
+ gdb_printf ("\n");
}
int
return 0;
return obstack_memory_used (&m_cache);
}
+
+} /* namespace gdb */