+2001-11-17 Bruno Haible <haible@clisp.cons.org>
+
+ * message.h: Include hash.h.
+ (message_list_ty): Add use_hashtable, htable fields.
+ (message_list_alloc): Add 'use_hashtable' argument.
+ (msgdomain_alloc): Likewise.
+ (msgdomain_list_ty): Add use_hashtable field.
+ (msgdomain_list_alloc): Add 'use_hashtable' argument.
+ * message.c: Include hash.h.
+ (message_list_alloc): Add 'use_hashtable' argument.
+ (message_list_free): Delete the hash table if present.
+ (message_list_append): If a hash table is in use, verify no duplicates.
+ (message_list_prepend): Likewise.
+ (message_list_remove_if_not): Remove hash table after removal.
+ (message_list_search): Use hash table if present.
+ (msgdomain_alloc): Add 'use_hashtable' argument.
+ (msgdomain_list_alloc): Add 'use_hashtable' argument.
+ (msgdomain_list_sublist): Use 'use_hashtable'.
+ * msgcmp.c (compare): Update.
+ (compare_constructor): Allocate a message list with hash table.
+ * msgfmt.c (new_domain): Allocate a message list with hash table.
+ Remove impossible error message.
+ * msgl-cat.c (catenate_msgdomain_list): Allocate message lists with
+ hash table.
+ * msgmerge.c (merge): Update.
+ * msgunfmt.c (main): Update.
+ * read-po.c (readall_constructor): Allocate a message list with hash
+ table if and only if duplicates will lead to an error message.
+ * xgettext.c (main): Allocate a message list with hash table, to
+ speed up insertion.
+ (exclude_directive_message): Allocate a message list with hash table,
+ to speed up exclusion test.
+
2001-11-17 Bruno Haible <haible@clisp.cons.org>
* message.h (msgdomain_list_sublist): Change last argument to bool.
#include <string.h>
#include "fstrcmp.h"
+#include "hash.h"
#include "xmalloc.h"
#include "strstr.h"
#include "system.h"
message_list_ty *
-message_list_alloc ()
+message_list_alloc (use_hashtable)
+ bool use_hashtable;
{
message_list_ty *mlp;
mlp->nitems = 0;
mlp->nitems_max = 0;
mlp->item = NULL;
+ if ((mlp->use_hashtable = use_hashtable))
+ init_hash (&mlp->htable, 10);
return mlp;
}
message_free (mlp->item[j]);
if (mlp->item)
free (mlp->item);
+ if (mlp->use_hashtable)
+ delete_hash (&mlp->htable);
free (mlp);
}
mlp->item = xrealloc (mlp->item, nbytes);
}
mlp->item[mlp->nitems++] = mp;
+
+ if (mlp->use_hashtable)
+ if (insert_entry (&mlp->htable, mp->msgid, strlen (mp->msgid) + 1, mp))
+ /* A message list has duplicates, although it was allocated with the
+ assertion that it wouldn't have duplicates. It is a bug. */
+ abort ();
}
mlp->item[j] = mlp->item[j - 1];
mlp->item[0] = mp;
mlp->nitems++;
+
+ if (mlp->use_hashtable)
+ if (insert_entry (&mlp->htable, mp->msgid, strlen (mp->msgid) + 1, mp))
+ /* A message list has duplicates, although it was allocated with the
+ assertion that it wouldn't have duplicates. It is a bug. */
+ abort ();
}
for (j = n + 1; j < mlp->nitems; ++j)
mlp->item[j - 1] = mlp->item[j];
mlp->nitems--;
+
+ if (mlp->use_hashtable)
+ {
+ /* Our simple-minded hash tables don't support removal. */
+ delete_hash (&mlp->htable);
+ mlp->use_hashtable = false;
+ }
}
#endif
for (j = 0, i = 0; j < mlp->nitems; j++)
if (predicate (mlp->item[j]))
mlp->item[i++] = mlp->item[j];
+ if (mlp->use_hashtable && i < mlp->nitems)
+ {
+ /* Our simple-minded hash tables don't support removal. */
+ delete_hash (&mlp->htable);
+ mlp->use_hashtable = false;
+ }
mlp->nitems = i;
}
message_list_ty *mlp;
const char *msgid;
{
- size_t j;
-
- for (j = 0; j < mlp->nitems; ++j)
+ if (mlp->use_hashtable)
{
message_ty *mp;
- mp = mlp->item[j];
- if (strcmp (msgid, mp->msgid) == 0)
+ if (find_entry (&mlp->htable, msgid, strlen (msgid) + 1, (void **) &mp))
+ return NULL;
+ else
return mp;
}
- return NULL;
+ else
+ {
+ size_t j;
+
+ for (j = 0; j < mlp->nitems; ++j)
+ {
+ message_ty *mp;
+
+ mp = mlp->item[j];
+ if (strcmp (msgid, mp->msgid) == 0)
+ return mp;
+ }
+ return NULL;
+ }
}
msgdomain_ty*
-msgdomain_alloc (domain)
+msgdomain_alloc (domain, use_hashtable)
const char *domain;
+ bool use_hashtable;
{
msgdomain_ty *mdp;
mdp = (msgdomain_ty *) xmalloc (sizeof (msgdomain_ty));
mdp->domain = domain;
- mdp->messages = message_list_alloc ();
+ mdp->messages = message_list_alloc (use_hashtable);
return mdp;
}
msgdomain_list_ty *
-msgdomain_list_alloc ()
+msgdomain_list_alloc (use_hashtable)
+ bool use_hashtable;
{
msgdomain_list_ty *mdlp;
mdlp->nitems_max = 1;
mdlp->item =
(msgdomain_ty **) xmalloc (mdlp->nitems_max * sizeof (msgdomain_ty *));
- mdlp->item[0] = msgdomain_alloc (MESSAGE_DOMAIN_DEFAULT);
+ mdlp->item[0] = msgdomain_alloc (MESSAGE_DOMAIN_DEFAULT, use_hashtable);
+ mdlp->use_hashtable = use_hashtable;
return mdlp;
}
if (create)
{
- msgdomain_ty *mdp = msgdomain_alloc (domain);
+ msgdomain_ty *mdp = msgdomain_alloc (domain, mdlp->use_hashtable);
msgdomain_list_append (mdlp, mdp);
return mdp->messages;
}
#include "str-list.h"
#include "pos.h"
+#include "hash.h"
#include <stdbool.h>
message_ty **item;
size_t nitems;
size_t nitems_max;
+ bool use_hashtable;
+ hash_table htable; /* Table mapping msgid to 'message_ty *'. */
};
+/* Create a fresh message list.
+ If USE_HASHTABLE is true, a hash table will be used to speed up
+ message_list_search(). USE_HASHTABLE can only be set to true if it is
+ known that the message list will not contain duplicate msgids. */
extern message_list_ty *
- message_list_alloc PARAMS ((void));
+ message_list_alloc PARAMS ((bool use_hashtable));
extern void
message_list_free PARAMS ((message_list_ty *mlp));
extern void
};
extern msgdomain_ty *
- msgdomain_alloc PARAMS ((const char *domain));
+ msgdomain_alloc PARAMS ((const char *domain, bool use_hashtable));
extern void
msgdomain_free PARAMS ((msgdomain_ty *mdp));
msgdomain_ty **item;
size_t nitems;
size_t nitems_max;
+ bool use_hashtable;
};
extern msgdomain_list_ty *
- msgdomain_list_alloc PARAMS ((void));
+ msgdomain_list_alloc PARAMS ((bool use_hashtable));
extern void
msgdomain_list_free PARAMS ((msgdomain_list_ty *mdlp));
extern void
the xgettext program. */
ref = grammar (fn2);
- empty_list = message_list_alloc ();
+ empty_list = message_list_alloc (false);
/* Every entry in the xgettext generated file must be matched by a
(single) entry in the human created file. */
{
compare_class_ty *this = (compare_class_ty *) that;
- this->mdlp = msgdomain_list_alloc ();
+ this->mdlp = msgdomain_list_alloc (true);
this->domain = MESSAGE_DOMAIN_DEFAULT;
this->mlp = msgdomain_list_sublist (this->mdlp, this->domain, true);
}
struct msg_domain *domain;
domain = (struct msg_domain *) xmalloc (sizeof (struct msg_domain));
- domain->mlp = message_list_alloc ();
- if (init_hash (&domain->symbol_tab, 100) != 0)
- error (EXIT_FAILURE, errno, _("while creating hash table"));
+ domain->mlp = message_list_alloc (true);
+ init_hash (&domain->symbol_tab, 100);
domain->domain_name = name;
domain->file_name = file_name;
domain->next = NULL;
If for a message, there is at least one non-fuzzy, non-empty translation,
use only the non-fuzzy, non-empty translations. Otherwise use the
fuzzy or empty translations as well. */
- total_mdlp = msgdomain_list_alloc ();
+ total_mdlp = msgdomain_list_alloc (true);
for (n = 0; n < nfiles; n++)
{
msgdomain_list_ty *mdlp = mdlps[n];
message_list_list_append (definitions, NULL);
if (compendiums)
message_list_list_append_list (definitions, compendiums);
- empty_list = message_list_alloc ();
+ empty_list = message_list_alloc (false);
/* This is the references file, created by groping the sources with
the xgettext program. */
message_list_prepend (ref->item[k]->messages, refheader);
}
- result = msgdomain_list_alloc ();
+ result = msgdomain_list_alloc (false);
processed = 0;
/* Every reference must be matched with its definition. */
{
message_list_ty *mlp;
- mlp = message_list_alloc ();
+ mlp = message_list_alloc (false);
if (optind < argc)
{
do
else
read_mo_file (mlp, "-");
- result = msgdomain_list_alloc ();
+ result = msgdomain_list_alloc (false);
result->item[0]->messages = mlp;
}
readall_class_ty *this = (readall_class_ty *) that;
size_t i;
- this->mdlp = msgdomain_list_alloc ();
+ this->mdlp = msgdomain_list_alloc (!allow_duplicates);
this->domain = MESSAGE_DOMAIN_DEFAULT;
this->mlp = msgdomain_list_sublist (this->mdlp, this->domain, true);
this->comment = NULL;
string_list_append_unique (file_list, argv[cnt]);
/* Allocate a message list to remember all the messages. */
- mdlp = msgdomain_list_alloc ();
+ mdlp = msgdomain_list_alloc (true);
/* Generate a header, so that we know how and when this PO file was
created. */
/* See if this message ID has been seen before. */
if (exclude == NULL)
- exclude = message_list_alloc ();
+ exclude = message_list_alloc (true);
mp = message_list_search (exclude, msgid);
if (mp != NULL)
free (msgid);