[haiku-commits] haiku: hrev43470 - src/system/libroot/posix/glibc/misc

  • From: korli@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 11 Dec 2011 10:53:01 +0100 (CET)

hrev43470 adds 2 changesets to branch 'master'
old head: 2a8373704a3a028df23daa12063928ba3383ed25
new head: 04fccd250fe3bb28f5f0010b1a60ad22f1cd64dc

----------------------------------------------------------------------------

7cd683b: fix typo

04fccd2: added hcreate, hdestroy, hsearch from glibc

                                   [ Jérôme Duval <jerome.duval@xxxxxxxxx> ]

----------------------------------------------------------------------------

4 files changed, 291 insertions(+), 2 deletions(-)
src/bin/addattr/addAttr.cpp                     |    4 +-
src/system/libroot/posix/glibc/misc/Jamfile     |    2 +
src/system/libroot/posix/glibc/misc/hsearch.c   |   57 +++++
src/system/libroot/posix/glibc/misc/hsearch_r.c |  230 +++++++++++++++++++

############################################################################

Commit:      7cd683ba12f74771eb851c29df10b8e8192039b2
URL:         http://cgit.haiku-os.org/haiku/commit/?id=7cd683b
Author:      Jérôme Duval <jerome.duval@xxxxxxxxx>
Date:        Sun Dec 11 09:36:16 2011 UTC

fix typo

----------------------------------------------------------------------------

diff --git a/src/bin/addattr/addAttr.cpp b/src/bin/addattr/addAttr.cpp
index 8af3251..a404413 100644
--- a/src/bin/addattr/addAttr.cpp
+++ b/src/bin/addattr/addAttr.cpp
@@ -33,9 +33,9 @@ writeAttrValue(int fd, const char *name, type_code type, Type 
value)
 
 
 /**    Writes an attribute to a node, taking the type into account and
- *     convertig the value accordingly
+ *     converting the value accordingly
  *
- *     On success it will return the amount of bytes writen
+ *     On success it will return the amount of bytes written
  *     On failure it returns an error code (negative number)
  */
 

############################################################################

Revision:    hrev43470
Commit:      04fccd250fe3bb28f5f0010b1a60ad22f1cd64dc
URL:         http://cgit.haiku-os.org/haiku/commit/?id=04fccd2
Author:      Jérôme Duval <jerome.duval@xxxxxxxxx>
Date:        Sun Dec 11 09:42:38 2011 UTC

added hcreate, hdestroy, hsearch from glibc

----------------------------------------------------------------------------

diff --git a/src/system/libroot/posix/glibc/misc/Jamfile 
b/src/system/libroot/posix/glibc/misc/Jamfile
index 52767e5..937e164 100644
--- a/src/system/libroot/posix/glibc/misc/Jamfile
+++ b/src/system/libroot/posix/glibc/misc/Jamfile
@@ -16,6 +16,8 @@ UsePrivateHeaders libroot ;
 SubDirCcFlags -D_GNU_SOURCE -DUSE_IN_LIBIO ;
 
 MergeObject posix_gnu_misc.o :
+       hsearch.c
+       hsearch_r.c
        insremque.c
        lsearch.c
        tsearch.c
diff --git a/src/system/libroot/posix/glibc/misc/hsearch.c 
b/src/system/libroot/posix/glibc/misc/hsearch.c
new file mode 100644
index 0000000..79d38f5
--- /dev/null
+++ b/src/system/libroot/posix/glibc/misc/hsearch.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   Contributed by Ulrich Drepper <drepper@xxxxxxxxxxxxxx>
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <search.h>
+
+/* The non-reentrant version use a global space for storing the table.  */
+static struct hsearch_data htab;
+
+
+/* Define the non-reentrant function using the reentrant counterparts.  */
+ENTRY *
+hsearch (item, action)
+     ENTRY item;
+     ACTION action;
+{
+  ENTRY *result;
+
+  (void) hsearch_r (item, action, &result, &htab);
+
+  return result;
+}
+
+
+int
+hcreate (nel)
+     size_t nel;
+{
+  return hcreate_r (nel, &htab);
+}
+
+
+void
+__hdestroy ()
+{
+  hdestroy_r (&htab);
+}
+weak_alias (__hdestroy, hdestroy)
+
+/* Make sure the table is freed if we want to free everything before
+   exiting.  */
+text_set_element (__libc_subfreeres, __hdestroy);
diff --git a/src/system/libroot/posix/glibc/misc/hsearch_r.c 
b/src/system/libroot/posix/glibc/misc/hsearch_r.c
new file mode 100644
index 0000000..0dec896
--- /dev/null
+++ b/src/system/libroot/posix/glibc/misc/hsearch_r.c
@@ -0,0 +1,230 @@
+/* Copyright (C) 1993,1995-1997,2002,2005,2007,2008,2009
+   Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@xxxxxxxxxxxxxx>, 1993.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <malloc.h>
+#include <string.h>
+
+#include <search.h>
+
+/* [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
+   [Knuth]            The Art of Computer Programming, part 3 (6.4)  */
+
+
+/* The reentrant version has no static variables to maintain the state.
+   Instead the interface of all functions is extended to take an argument
+   which describes the current status.  */
+typedef struct _ENTRY
+{
+  unsigned int used;
+  ENTRY entry;
+}
+_ENTRY;
+
+
+/* For the used double hash method the table size has to be a prime. To
+   correct the user given table size we need a prime test.  This trivial
+   algorithm is adequate because
+   a)  the code is (most probably) called a few times per program run and
+   b)  the number is small because the table must fit in the core  */
+static int
+isprime (unsigned int number)
+{
+  /* no even number will be passed */
+  unsigned int div = 3;
+
+  while (div * div < number && number % div != 0)
+    div += 2;
+
+  return number % div != 0;
+}
+
+
+/* Before using the hash table we must allocate memory for it.
+   Test for an existing table are done. We allocate one element
+   more as the found prime number says. This is done for more effective
+   indexing as explained in the comment for the hsearch function.
+   The contents of the table is zeroed, especially the field used
+   becomes zero.  */
+int
+hcreate_r (nel, htab)
+     size_t nel;
+     struct hsearch_data *htab;
+{
+  /* Test for correct arguments.  */
+  if (htab == NULL)
+    {
+      __set_errno (EINVAL);
+      return 0;
+    }
+
+  /* There is still another table active. Return with error. */
+  if (htab->table != NULL)
+    return 0;
+
+  /* We need a size of at least 3.  Otherwise the hash functions we
+     use will not work.  */
+  if (nel < 3)
+    nel = 3;
+  /* Change nel to the first prime number not smaller as nel. */
+  nel |= 1;      /* make odd */
+  while (!isprime (nel))
+    nel += 2;
+
+  htab->size = nel;
+  htab->filled = 0;
+
+  /* allocate memory and zero out */
+  htab->table = (_ENTRY *) calloc (htab->size + 1, sizeof (_ENTRY));
+  if (htab->table == NULL)
+    return 0;
+
+  /* everything went alright */
+  return 1;
+}
+libc_hidden_def (hcreate_r)
+
+
+/* After using the hash table it has to be destroyed. The used memory can
+   be freed and the local static variable can be marked as not used.  */
+void
+hdestroy_r (htab)
+     struct hsearch_data *htab;
+{
+  /* Test for correct arguments.  */
+  if (htab == NULL)
+    {
+      __set_errno (EINVAL);
+      return;
+    }
+
+  /* Free used memory.  */
+  free (htab->table);
+
+  /* the sign for an existing table is an value != NULL in htable */
+  htab->table = NULL;
+}
+libc_hidden_def (hdestroy_r)
+
+
+/* This is the search function. It uses double hashing with open addressing.
+   The argument item.key has to be a pointer to an zero terminated, most
+   probably strings of chars. The function for generating a number of the
+   strings is simple but fast. It can be replaced by a more complex function
+   like ajw (see [Aho,Sethi,Ullman]) if the needs are shown.
+
+   We use an trick to speed up the lookup. The table is created by hcreate
+   with one more element available. This enables us to use the index zero
+   special. This index will never be used because we store the first hash
+   index in the field used where zero means not used. Every other value
+   means used. The used field can be used as a first fast comparison for
+   equality of the stored and the parameter value. This helps to prevent
+   unnecessary expensive calls of strcmp.  */
+int
+hsearch_r (item, action, retval, htab)
+     ENTRY item;
+     ACTION action;
+     ENTRY **retval;
+     struct hsearch_data *htab;
+{
+  unsigned int hval;
+  unsigned int count;
+  unsigned int len = strlen (item.key);
+  unsigned int idx;
+
+  /* Compute an value for the given string. Perhaps use a better method. */
+  hval = len;
+  count = len;
+  while (count-- > 0)
+    {
+      hval <<= 4;
+      hval += item.key[count];
+    }
+  if (hval == 0)
+    ++hval;
+
+  /* First hash function: simply take the modul but prevent zero. */
+  idx = hval % htab->size + 1;
+
+  if (htab->table[idx].used)
+    {
+      /* Further action might be required according to the action value. */
+      if (htab->table[idx].used == hval
+         && strcmp (item.key, htab->table[idx].entry.key) == 0)
+       {
+         *retval = &htab->table[idx].entry;
+         return 1;
+       }
+       {
+      /* Second hash function, as suggested in [Knuth] */
+      unsigned int hval2 = 1 + hval % (htab->size - 2);
+      unsigned int first_idx = idx;
+
+      do
+       {
+         /* Because SIZE is prime this guarantees to step through all
+             available indeces.  */
+          if (idx <= hval2)
+           idx = htab->size + idx - hval2;
+         else
+           idx -= hval2;
+
+         /* If we visited all entries leave the loop unsuccessfully.  */
+         if (idx == first_idx)
+           break;
+
+            /* If entry is found use it. */
+          if (htab->table[idx].used == hval
+             && strcmp (item.key, htab->table[idx].entry.key) == 0)
+           {
+             *retval = &htab->table[idx].entry;
+             return 1;
+           }
+       }
+      while (htab->table[idx].used);
+       }
+    }
+
+  /* An empty bucket has been found. */
+  if (action == ENTER)
+    {
+      /* If table is full and another entry should be entered return
+        with error.  */
+      if (htab->filled == htab->size)
+       {
+         __set_errno (ENOMEM);
+         *retval = NULL;
+         return 0;
+       }
+
+      htab->table[idx].used  = hval;
+      htab->table[idx].entry = item;
+
+      ++htab->filled;
+
+      *retval = &htab->table[idx].entry;
+      return 1;
+    }
+
+  __set_errno (ESRCH);
+  *retval = NULL;
+  return 0;
+}
+libc_hidden_def (hsearch_r)


Other related posts:

  • » [haiku-commits] haiku: hrev43470 - src/system/libroot/posix/glibc/misc - korli