+/* Create an entry.
+ The memory region passed by the caller must of indefinite extent. It is
+ *not* copied here. */
+static struct entry *
+entry_create (char *string, size_t length)
+{
+ struct entry *result = XMALLOC (struct entry);
+ result->string = string;
+ result->length = length;
+ result->hashcode_cached = false;
+ return result;
+}
+
/* Compare two entries for equality. */
static bool
entry_equals (const void *elt1, const void *elt2)
/* Compare two entries for equality. */
static bool
entry_equals (const void *elt1, const void *elt2)
- const struct entry *entry = (const struct entry *) elt;
- /* See http://www.haible.de/bruno/hashfunc.html. */
- const char *s;
- size_t n;
- size_t h = 0;
+ struct entry *entry = (struct entry *) elt;
+ if (!entry->hashcode_cached)
+ {
+ /* See http://www.haible.de/bruno/hashfunc.html. */
+ const char *s;
+ size_t n;
+ size_t h = 0;
- for (s = entry->string, n = entry->length; n > 0; s++, n--)
- h = (unsigned char) *s + ((h << 9) | (h >> (sizeof (size_t) * CHAR_BIT - 9)));
+ for (s = entry->string, n = entry->length; n > 0; s++, n--)
+ h = (unsigned char) *s + ((h << 9) | (h >> (sizeof (size_t) * CHAR_BIT - 9)));
gl_list_create_empty (GL_LINKEDHASH_LIST, entry_equals, entry_hashcode,
NULL, true);
result->entries_reversed =
gl_list_create_empty (GL_LINKEDHASH_LIST, entry_equals, entry_hashcode,
NULL, true);
result->entries_reversed =
- gl_list_create_empty (GL_LINKEDHASH_LIST, entry_equals, entry_hashcode,
+ gl_list_create_empty (GL_RBTREEHASH_LIST, entry_equals, entry_hashcode,
NULL, true);
/* A ChangeLog file consists of ChangeLog entries. A ChangeLog entry starts
at a line following a blank line and that starts with a non-whitespace
NULL, true);
/* A ChangeLog file consists of ChangeLog entries. A ChangeLog entry starts
at a line following a blank line and that starts with a non-whitespace
gl_list_add_last (result->entries_list, curr);
gl_list_add_first (result->entries_reversed, curr);
gl_list_add_last (result->entries_list, curr);
gl_list_add_first (result->entries_reversed, curr);
- new_split[0] = XMALLOC (struct entry);
- new_split[0]->string = new_entry->string;
- new_split[0]->length = best_split_offset + 1;
+ new_split[0] = entry_create (new_entry->string, best_split_offset + 1);
{
size_t len1 = new_title_len;
size_t len2 = new_entry->length - best_split_offset;
char *combined = XNMALLOC (len1 + len2, char);
memcpy (combined, new_entry->string, len1);
memcpy (combined + len1, new_entry->string + best_split_offset, len2);
{
size_t len1 = new_title_len;
size_t len2 = new_entry->length - best_split_offset;
char *combined = XNMALLOC (len1 + len2, char);
memcpy (combined, new_entry->string, len1);
memcpy (combined + len1, new_entry->string + best_split_offset, len2);
- size_t n = gl_list_size (result_entries);
- size_t i;
- for (i = 0; i < n; i++)
- entry_write (fp, (struct entry *) gl_list_get_at (result_entries, i));
+ gl_list_iterator_t iter = gl_list_iterator (result_entries);
+ const void *elt;
+ gl_list_node_t node;
+ while (gl_list_iterator_next (&iter, &elt, &node))
+ entry_write (fp, (struct entry *) elt);
+ gl_list_iterator_free (&iter);