Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libintl - add hash table support.



details:   https://anonhg.NetBSD.org/src/rev/1cb865d29607
branches:  trunk
changeset: 570095:1cb865d29607
user:      tshiozak <tshiozak%NetBSD.org@localhost>
date:      Thu Sep 23 16:44:26 2004 +0000

description:
- add hash table support.
- make use of __UNCONST() instead of LINTED.

diffstat:

 lib/libintl/Makefile        |    4 +-
 lib/libintl/gettext.c       |  110 ++++++++++++++++++++++++++++++++++++-------
 lib/libintl/libintl_local.h |   24 ++++++++-
 lib/libintl/strhash.c       |   63 +++++++++++++++++++++++++
 lib/libintl/textdomain.c    |    6 +-
 5 files changed, 182 insertions(+), 25 deletions(-)

diffs (truncated from 385 to 300 lines):

diff -r bbb54538567a -r 1cb865d29607 lib/libintl/Makefile
--- a/lib/libintl/Makefile      Thu Sep 23 14:45:20 2004 +0000
+++ b/lib/libintl/Makefile      Thu Sep 23 16:44:26 2004 +0000
@@ -1,9 +1,9 @@
-#      $NetBSD: Makefile,v 1.3 2004/01/18 08:40:40 yamt Exp $
+#      $NetBSD: Makefile,v 1.4 2004/09/23 16:44:26 tshiozak Exp $
 
 .include <bsd.own.mk>
 
 LIB=   intl
-SRCS=  gettext.c textdomain.c gettext_iconv.c gettext_dummy.c
+SRCS=  gettext.c textdomain.c gettext_iconv.c gettext_dummy.c strhash.c
 INCS=  libintl.h
 INCSDIR=/usr/include
 
diff -r bbb54538567a -r 1cb865d29607 lib/libintl/gettext.c
--- a/lib/libintl/gettext.c     Thu Sep 23 14:45:20 2004 +0000
+++ b/lib/libintl/gettext.c     Thu Sep 23 16:44:26 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: gettext.c,v 1.18 2004/01/18 08:40:40 yamt Exp $        */
+/*     $NetBSD: gettext.c,v 1.19 2004/09/23 16:44:26 tshiozak Exp $    */
 
 /*-
  * Copyright (c) 2000, 2001 Citrus Project,
@@ -29,13 +29,14 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: gettext.c,v 1.18 2004/01/18 08:40:40 yamt Exp $");
+__RCSID("$NetBSD: gettext.c,v 1.19 2004/09/23 16:44:26 tshiozak Exp $");
 
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
 #include <sys/uio.h>
 
+#include <assert.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -189,25 +190,25 @@
                if (t) {
                        if (c) {
                                snprintf(tmp, sizeof(tmp), "%s_%s.%s@%s",
-                                   l, t, c, m); 
+                                   l, t, c, m);
                                strlcat(result, tmp, sizeof(result));
                                strlcat(result, ":", sizeof(result));
                        }
-                       snprintf(tmp, sizeof(tmp), "%s_%s@%s", l, t, m); 
+                       snprintf(tmp, sizeof(tmp), "%s_%s@%s", l, t, m);
                        strlcat(result, tmp, sizeof(result));
                        strlcat(result, ":", sizeof(result));
                }
-               snprintf(tmp, sizeof(tmp), "%s@%s", l, m); 
+               snprintf(tmp, sizeof(tmp), "%s@%s", l, m);
                strlcat(result, tmp, sizeof(result));
                strlcat(result, ":", sizeof(result));
        }
        if (t) {
                if (c) {
-                       snprintf(tmp, sizeof(tmp), "%s_%s.%s", l, t, c); 
+                       snprintf(tmp, sizeof(tmp), "%s_%s.%s", l, t, c);
                        strlcat(result, tmp, sizeof(result));
                        strlcat(result, ":", sizeof(result));
                }
-               snprintf(tmp, sizeof(tmp), "%s_%s", l, t); 
+               snprintf(tmp, sizeof(tmp), "%s_%s", l, t);
                strlcat(result, tmp, sizeof(result));
                strlcat(result, ":", sizeof(result));
        }
@@ -309,6 +310,7 @@
        char *base;
        u_int32_t magic, revision;
        struct moentry *otable, *ttable;
+       const u_int32_t *htable;
        struct moentry_h *p;
        struct mo *mo;
        size_t l;
@@ -338,8 +340,18 @@
                close(fd);
                goto fail;
        }
-       if (read(fd, &revision, sizeof(revision)) != sizeof(revision) ||
-           flip(revision, magic) != MO_REVISION) {
+       if (read(fd, &revision, sizeof(revision)) != sizeof(revision)) {
+               close(fd);
+               goto fail;
+       }
+       switch (flip(revision, magic)) {
+       case MO_MAKE_REV(0, 0):
+#if 0
+       case MO_MAKE_REV(0, 1):
+       case MO_MAKE_REV(1, 1):
+#endif
+               break;
+       default:
                close(fd);
                goto fail;
        }
@@ -359,9 +371,12 @@
        mohandle->mo.mo_magic = mo->mo_magic;
        mohandle->mo.mo_revision = flip(mo->mo_revision, magic);
        mohandle->mo.mo_nstring = flip(mo->mo_nstring, magic);
+       mohandle->mo.mo_hsize = flip(mo->mo_hsize, magic);
 
        /* validate otable/ttable */
+       /* LINTED: ignore the alignment problem. */
        otable = (struct moentry *)(base + flip(mo->mo_otable, magic));
+       /* LINTED: ignore the alignment problem. */
        ttable = (struct moentry *)(base + flip(mo->mo_ttable, magic));
        if (!validate(otable, mohandle) ||
            !validate(&otable[mohandle->mo.mo_nstring], mohandle)) {
@@ -408,7 +423,26 @@
                        goto fail;
                }
        }
-
+       /* allocate htable, and convert it to the host order. */
+       if (mohandle->mo.mo_hsize > 2) {
+               l = sizeof(u_int32_t) * mohandle->mo.mo_hsize;
+               mohandle->mo.mo_htable = (u_int32_t *)malloc(l);
+               if (!mohandle->mo.mo_htable) {
+                       unmapit(db);
+                       goto fail;
+               }
+               /* LINTED: ignore the alignment problem. */
+               htable = (const u_int32_t *)(base+flip(mo->mo_hoffset, magic));
+               for (i=0; i < mohandle->mo.mo_hsize; i++) {
+                       mohandle->mo.mo_htable[i] = flip(htable[i], magic);
+                       if (mohandle->mo.mo_htable[i] >=
+                           mohandle->mo.mo_nstring+1) {
+                               /* illegal string number. */
+                               unmapit(db);
+                               goto fail;
+                       }
+               }
+       }
        /* grab MIME-header and charset field */
        mohandle->mo.mo_header = lookup("", db);
        if (mohandle->mo.mo_header)
@@ -454,22 +488,63 @@
                free(mohandle->mo.mo_ttable);
        if (mohandle->mo.mo_charset)
                free(mohandle->mo.mo_charset);
+       if (mohandle->mo.mo_htable)
+               free(mohandle->mo.mo_htable);
        memset(&mohandle->mo, 0, sizeof(mohandle->mo));
        return 0;
 }
 
+/*
+ * calculate the step value if the hash value is conflicted.
+ */
+static __inline u_int32_t
+calc_collision_step(u_int32_t hashval, u_int32_t hashsize)
+{
+       _DIAGASSERT(hashsize>2);
+       return (hashval % (hashsize - 2)) + 1;
+}
+
+/*
+ * calculate the next index while conflicting.
+ */
+static __inline u_int32_t
+calc_next_index(u_int32_t curidx, u_int32_t hashsize, u_int32_t step)
+{
+       return curidx+step - (curidx >= hashsize-step ? hashsize : 0);
+}
+
 /* ARGSUSED */
 static const char *
 lookup_hash(msgid, db)
        const char *msgid;
        struct domainbinding *db;
 {
+       struct mohandle *mohandle = &db->mohandle;
+       u_int32_t idx, hashval, step, strno;
+       size_t len;
 
-       /*
-        * XXX should try a hashed lookup here, but to do so, we need to
-        * look inside the GPL'ed *.c and re-implement...
-        */
-       return NULL;
+       if (mohandle->mo.mo_hsize <= 2 || mohandle->mo.mo_htable == NULL)
+               return NULL;
+
+       hashval = __intl_string_hash(msgid);
+       step = calc_collision_step(hashval, mohandle->mo.mo_hsize);
+       idx = hashval % mohandle->mo.mo_hsize;
+       len = strlen(msgid);
+       while (/*CONSTCOND*/1) {
+               strno = mohandle->mo.mo_htable[idx];
+               if (strno == 0) {
+                       /* unexpected miss */
+                       return NULL;
+               }
+               strno--;
+               if (len <= mohandle->mo.mo_otable[strno].len &&
+                   !strcmp(msgid, mohandle->mo.mo_otable[strno].off)) {
+                       /* hit */
+                       return mohandle->mo.mo_ttable[strno].off;
+               }
+               idx = calc_next_index(idx, mohandle->mo.mo_hsize, step);
+       }
+       /*NOTREACHED*/
 }
 
 static const char *
@@ -576,7 +651,7 @@
        lpath = get_lang_env(cname);
        if (!lpath)
                goto fail;
-       
+
        for (db = __bindings; db; db = db->next)
                if (strcmp(db->domainname, domainname) == 0)
                        break;
@@ -650,6 +725,5 @@
        }
 
 fail:
-       /* LINTED const cast */
-       return (char *)msgid;
+       return (char *)__UNCONST(msgid);
 }
diff -r bbb54538567a -r 1cb865d29607 lib/libintl/libintl_local.h
--- a/lib/libintl/libintl_local.h       Thu Sep 23 14:45:20 2004 +0000
+++ b/lib/libintl/libintl_local.h       Thu Sep 23 16:44:26 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: libintl_local.h,v 1.7 2004/01/18 08:40:40 yamt Exp $   */
+/*     $NetBSD: libintl_local.h,v 1.8 2004/09/23 16:44:26 tshiozak Exp $       */
 
 /*-
  * Copyright (c) 2000, 2001 Citrus Project,
@@ -30,7 +30,9 @@
 
 #define MO_MAGIC               0x950412de
 #define MO_MAGIC_SWAPPED       0xde120495
-#define MO_REVISION            0
+#define MO_GET_REV_MAJOR(r)    (((r) >> 16) & 0xFFFF)
+#define MO_GET_REV_MINOR(r)    ((r) & 0xFFFF)
+#define MO_MAKE_REV(maj, min)  (((maj) << 16) | (min))
 
 #define GETTEXT_MMAP_MAX       (1024 * 1024)   /*XXX*/
 
@@ -45,6 +47,13 @@
        u_int32_t mo_ttable;    /* T: translated text table offset */
        u_int32_t mo_hsize;     /* S: size of hashing table */
        u_int32_t mo_hoffset;   /* H: offset of hashing table */
+       /* rev 0.1 / 1.1 */
+       /* system dependent string support */
+       u_int32_t mo_sysdep_nsegs;      /* number of sysdep segments */
+       u_int32_t mo_sysdep_segoff;     /* offset of sysdep segment table */
+       u_int32_t mo_sysdep_nstring;    /* number of strings */
+       u_int32_t mo_sysdep_otable;     /* offset of original text table */
+       u_int32_t mo_sysdep_ttable;     /* offset of translated text table */
 } __attribute__((__packed__));
 
 struct moentry {
@@ -52,6 +61,12 @@
        u_int32_t off;          /* offset of \0-terminated string */
 } __attribute__((__packed__));
 
+struct mosysdepstr
+{
+       u_int32_t off;          /* offset of seed text */
+       struct moentry segs[1]; /* text segments */
+} __attribute__((__packed__));
+
 /* libintl internal data format */
 struct moentry_h {
        size_t len;             /* strlen(str), so region will be len + 1 */
@@ -66,6 +81,8 @@
        struct moentry_h *mo_ttable;    /* T: translated text table offset */
        const char *mo_header;
        char *mo_charset;
+       u_int32_t mo_hsize;     /* S: size of hashing table */
+       u_int32_t *mo_htable;   /* H: hashing table */
 };
 
 struct mohandle {
@@ -85,4 +102,7 @@
 extern struct domainbinding *__bindings;
 extern char __current_domainname[PATH_MAX];
 
+__BEGIN_DECLS
 const char *__gettext_iconv __P((const char *, struct domainbinding *));
+u_int32_t __intl_string_hash __P((const char *));
+__END_DECLS
diff -r bbb54538567a -r 1cb865d29607 lib/libintl/strhash.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/libintl/strhash.c     Thu Sep 23 16:44:26 2004 +0000
@@ -0,0 +1,63 @@
+/*     $NetBSD: strhash.c,v 1.1 2004/09/23 16:44:26 tshiozak Exp $     */
+
+/*-
+ * Copyright (c)2003, 2004 Citrus Project,
+ * All rights reserved.



Home | Main Index | Thread Index | Old Index