[PATCH] Use libihash to store directory entries in ftpfs.

2016-02-13 Thread Flavio Cruz
* ftpfs/ftpfs.h: Add dir_locp for each directory entry and replace the
table with a libihash table.
* ftpfs/dir.c: Modify the code to use libihash. Remove several functions
such as rehash and insert.
---
 ftpfs/dir.c   | 146 --
 ftpfs/ftpfs.h |  17 ++-
 2 files changed, 44 insertions(+), 119 deletions(-)

diff --git a/ftpfs/dir.c b/ftpfs/dir.c
index be20b3d..733a2dc 100644
--- a/ftpfs/dir.c
+++ b/ftpfs/dir.c
@@ -30,72 +30,31 @@
 void
 free_entry (struct ftpfs_dir_entry *e)
 {
-  assert (! e->self_p);/* We should only free deleted nodes.  
*/
+  assert (e->deleted);
   free (e->name);
   if (e->symlink_target)
 free (e->symlink_target);
   free (e);
 }
 
-/* Put the directory entry E into the hash table HTABLE, of length HTABLE_LEN. 
 */
-static void
-insert (struct ftpfs_dir_entry *e,
-   struct ftpfs_dir_entry **htable, size_t htable_len)
+/* Calculate NAME_PTR's hash value.  */
+static hurd_ihash_key_t
+ihash_hash (const void *name_ptr)
 {
-  struct ftpfs_dir_entry **t = [e->hv % htable_len];
-  if (*t)
-(*t)->self_p = >next;
-  e->next = *t;
-  e->self_p = t;
-  *t = e;
+  const char *name = (const char *) name_ptr;
+  return (hurd_ihash_key_t) hurd_ihash_hash32 (name, strlen (name), 0);
 }
-
-/* Replace DIR's hashtable with a new one of length NEW_LEN, retaining all
-   existing entries.  */
-static error_t
-rehash (struct ftpfs_dir *dir, size_t new_len)
+
+/* Compare two names which are used as keys.  */
+static int
+ihash_compare (const void *key1, const void *key2)
 {
-  int i;
-  size_t old_len = dir->htable_len;
-  struct ftpfs_dir_entry **old_htable = dir->htable;
-  struct ftpfs_dir_entry **new_htable =
-malloc (new_len * sizeof (struct ftpfs_dir_entry *));
-
-  if (! new_htable)
-return ENOMEM;
-
-  memset (new_htable, 0, new_len * sizeof(struct ftpfs_dir_entry *));
-
-  for (i = 0; i < old_len; i++)
-while (old_htable[i])
-  {
-   struct ftpfs_dir_entry *e = old_htable[i];
+  const char *name1 = (const char *) key1;
+  const char *name2 = (const char *) key2;
 
-   /* Remove E from the old table (don't bother to fixup
-  e->next->self_p).  */
-   old_htable[i] = e->next;
-
-   insert (e, new_htable, new_len);
-  }
-
-  free (old_htable);
-
-  dir->htable = new_htable;
-  dir->htable_len = new_len;
-
-  return 0;
+  return strcmp (name1, name2) == 0;
 }
 
-/* Calculate NAME's hash value.  */
-static size_t
-hash (const char *name)
-{
-  size_t hv = 0;
-  while (*name)
-hv = ((hv << 5) + *name++) & 0xFF;
-  return hv;
-}
-
 /* Lookup NAME in DIR and return its entry.  If there is no such entry, and
ADD is true, then a new entry is allocated and returned, otherwise 0 is
returned (if ADD is true then 0 can be returned if a memory allocation
@@ -103,23 +62,14 @@ hash (const char *name)
 struct ftpfs_dir_entry *
 lookup (struct ftpfs_dir *dir, const char *name, int add)
 {
-  size_t hv = hash (name);
-  struct ftpfs_dir_entry *h = dir->htable[hv % dir->htable_len], *e = h;
-
-  while (e && strcmp (name, e->name) != 0)
-e = e->next;
+  struct ftpfs_dir_entry *e =
+hurd_ihash_find (>htable, (hurd_ihash_key_t) name);
 
   if (!e && add)
 {
-  if (dir->num_entries > dir->htable_len)
-   /* Grow the hash table.  */
-   if (rehash (dir, (dir->htable_len + 1) * 2 - 1) != 0)
- return 0;
-
   e = malloc (sizeof *e);
   if (e)
{
- e->hv = hv;
  e->name = strdup (name);
  e->node = 0;
  e->dir = dir;
@@ -128,13 +78,11 @@ lookup (struct ftpfs_dir *dir, const char *name, int add)
  e->symlink_target = 0;
  e->noent = 0;
  e->valid = 0;
+  e->deleted = 0;
  e->name_timestamp = e->stat_timestamp = 0;
  e->ordered_next = 0;
  e->ordered_self_p = 0;
- e->next = 0;
- e->self_p = 0;
- insert (e, dir->htable, dir->htable_len);
- dir->num_entries++;
+  hurd_ihash_add (>htable, (hurd_ihash_key_t) e->name, e);
}
 }
 
@@ -148,28 +96,21 @@ ordered_unlink (struct ftpfs_dir_entry *e)
   if (e->ordered_self_p)
 *e->ordered_self_p = e->ordered_next;
   if (e->ordered_next)
-e->ordered_next->self_p = e->ordered_self_p;
+e->ordered_next->ordered_self_p = e->ordered_self_p;
 }
-
+
 /* Delete E from its directory, freeing any resources it holds.  */
 static void
 delete (struct ftpfs_dir_entry *e, struct ftpfs_dir *dir)
 {
-  dir->num_entries--;
-
-  /* Take out of the hash chain.  */
-  if (e->self_p)
-*e->self_p = e->next;
-  if (e->next)
-e->next->self_p = e->self_p;
-
   /* This indicates a deleted entry.  */
-  e->self_p = 0;
-  e->next = 0;
+  e->deleted = 1;
 
   /* Take out of the directory ordered list.  */
   ordered_unlink (e);
 
+  hurd_ihash_locp_remove (>htable, e->dir_locp);
+
   /* If there's a node attached, we'll delete the entry whenever it goes
  away, 

Re: [PATCH] Use libihash to store directory entries in ftpfs.

2016-02-13 Thread Justus Winter
Quoting Flavio Cruz (2016-02-13 23:12:34)
> * ftpfs/ftpfs.h: Add dir_locp for each directory entry and replace the
> table with a libihash table.
> * ftpfs/dir.c: Modify the code to use libihash. Remove several functions
> such as rehash and insert.

Merged, thanks!

Justus



Re: [PATCH] Use libihash to store directory entries in ftpfs.

2016-02-11 Thread Justus Winter
Quoting Flavio Cruz (2016-02-07 21:53:53)
> * ftpfs/ftpfs.h: Add dir_locp for each directory entry and replace the table 
> with a libihash table.
> * ftpfs/dir.c: Modify the code to use libihash. Remove several functions such 
> as rehash and insert.

Your changelog entries are very long, please do reflow them to a
reasonable length.  I don't know what the reasonable length is, but I
always reflow them using meta-q in emacs.

> ---
> -
> 
> +
> [...]
> -
> 
> +
> [...]
> -
> 
> +
> [...]
> -
> 
> +
> [...]
> -
> 
> +
> [...]
> -
> 
> +
> [...]
> -
> 
> +
> [...]
> -
> 
> +

Your patch removes quite a lot of the form feed characters, is that on
purpose or an accident?  Fwiw, the coding conventions encourage their
use to break the source into logical segments.

Justus



Re: [PATCH] Use libihash to store directory entries in ftpfs.

2016-02-08 Thread Justus Winter
Quoting Flavio Cruz (2016-02-07 15:03:10)
> * ftpfs/ftpfs.h: Add dir_locp for each directory entry and replace the table 
> with a libihash table.
> * ftpfs/dir.c: Modify the code to use libihash. Remove several functions such 
> as rehash and insert.

Cool!

> -/* Calculate NAME's hash value.  */
> -static size_t
> -hash (const char *name)
> +/* Calculate NAME_PTR's hash value.  */
> +static hurd_ihash_key_t
> +ihash_hash (const void *name_ptr)
>  {
> +  const char *name = (const char *) name_ptr;
>size_t hv = 0;
>while (*name)
>  hv = ((hv << 5) + *name++) & 0xFF;
>return hv;
>  }

While you are at it, please replace this with hurd_ihash_hash32.

Justus



[PATCH] Use libihash to store directory entries in ftpfs.

2016-02-08 Thread Flavio Cruz
* ftpfs/ftpfs.h: Add dir_locp for each directory entry and replace the table 
with a libihash table.
* ftpfs/dir.c: Modify the code to use libihash. Remove several functions such 
as rehash and insert.
---
 ftpfs/dir.c   | 158 +-
 ftpfs/ftpfs.h |  17 ++-
 2 files changed, 50 insertions(+), 125 deletions(-)

diff --git a/ftpfs/dir.c b/ftpfs/dir.c
index be20b3d..96424c2 100644
--- a/ftpfs/dir.c
+++ b/ftpfs/dir.c
@@ -30,70 +30,29 @@
 void
 free_entry (struct ftpfs_dir_entry *e)
 {
-  assert (! e->self_p);/* We should only free deleted nodes.  
*/
+  assert (e->deleted);
   free (e->name);
   if (e->symlink_target)
 free (e->symlink_target);
   free (e);
 }
-
-/* Put the directory entry E into the hash table HTABLE, of length HTABLE_LEN. 
 */
-static void
-insert (struct ftpfs_dir_entry *e,
-   struct ftpfs_dir_entry **htable, size_t htable_len)
+
+/* Calculate NAME_PTR's hash value.  */
+static hurd_ihash_key_t
+ihash_hash (const void *name_ptr)
 {
-  struct ftpfs_dir_entry **t = [e->hv % htable_len];
-  if (*t)
-(*t)->self_p = >next;
-  e->next = *t;
-  e->self_p = t;
-  *t = e;
+  const char *name = (const char *) name_ptr;
+  return (hurd_ihash_key_t) hurd_ihash_hash32 (name, strlen (name), 0);
 }
 
-/* Replace DIR's hashtable with a new one of length NEW_LEN, retaining all
-   existing entries.  */
-static error_t
-rehash (struct ftpfs_dir *dir, size_t new_len)
+/* Compare two names which are used as keys.  */
+static int
+ihash_compare (const void *key1, const void *key2)
 {
-  int i;
-  size_t old_len = dir->htable_len;
-  struct ftpfs_dir_entry **old_htable = dir->htable;
-  struct ftpfs_dir_entry **new_htable =
-malloc (new_len * sizeof (struct ftpfs_dir_entry *));
-
-  if (! new_htable)
-return ENOMEM;
-
-  memset (new_htable, 0, new_len * sizeof(struct ftpfs_dir_entry *));
-
-  for (i = 0; i < old_len; i++)
-while (old_htable[i])
-  {
-   struct ftpfs_dir_entry *e = old_htable[i];
-
-   /* Remove E from the old table (don't bother to fixup
-  e->next->self_p).  */
-   old_htable[i] = e->next;
-
-   insert (e, new_htable, new_len);
-  }
-
-  free (old_htable);
+  const char *name1 = (const char *) key1;
+  const char *name2 = (const char *) key2;
 
-  dir->htable = new_htable;
-  dir->htable_len = new_len;
-
-  return 0;
-}
-
-/* Calculate NAME's hash value.  */
-static size_t
-hash (const char *name)
-{
-  size_t hv = 0;
-  while (*name)
-hv = ((hv << 5) + *name++) & 0xFF;
-  return hv;
+  return strcmp (name1, name2) == 0;
 }
 
 /* Lookup NAME in DIR and return its entry.  If there is no such entry, and
@@ -103,23 +62,14 @@ hash (const char *name)
 struct ftpfs_dir_entry *
 lookup (struct ftpfs_dir *dir, const char *name, int add)
 {
-  size_t hv = hash (name);
-  struct ftpfs_dir_entry *h = dir->htable[hv % dir->htable_len], *e = h;
-
-  while (e && strcmp (name, e->name) != 0)
-e = e->next;
+  struct ftpfs_dir_entry *e =
+hurd_ihash_find (>htable, (hurd_ihash_key_t) name);
 
   if (!e && add)
 {
-  if (dir->num_entries > dir->htable_len)
-   /* Grow the hash table.  */
-   if (rehash (dir, (dir->htable_len + 1) * 2 - 1) != 0)
- return 0;
-
   e = malloc (sizeof *e);
   if (e)
{
- e->hv = hv;
  e->name = strdup (name);
  e->node = 0;
  e->dir = dir;
@@ -128,19 +78,17 @@ lookup (struct ftpfs_dir *dir, const char *name, int add)
  e->symlink_target = 0;
  e->noent = 0;
  e->valid = 0;
+  e->deleted = 0;
  e->name_timestamp = e->stat_timestamp = 0;
  e->ordered_next = 0;
  e->ordered_self_p = 0;
- e->next = 0;
- e->self_p = 0;
- insert (e, dir->htable, dir->htable_len);
- dir->num_entries++;
+  hurd_ihash_add (>htable, (hurd_ihash_key_t) e->name, e);
}
 }
 
   return e;
 }
-
+
 /* Remove E from its position in the ordered_next chain.  */
 static void
 ordered_unlink (struct ftpfs_dir_entry *e)
@@ -148,59 +96,50 @@ ordered_unlink (struct ftpfs_dir_entry *e)
   if (e->ordered_self_p)
 *e->ordered_self_p = e->ordered_next;
   if (e->ordered_next)
-e->ordered_next->self_p = e->ordered_self_p;
+e->ordered_next->ordered_self_p = e->ordered_self_p;
 }
 
 /* Delete E from its directory, freeing any resources it holds.  */
 static void
 delete (struct ftpfs_dir_entry *e, struct ftpfs_dir *dir)
 {
-  dir->num_entries--;
-
-  /* Take out of the hash chain.  */
-  if (e->self_p)
-*e->self_p = e->next;
-  if (e->next)
-e->next->self_p = e->self_p;
-
   /* This indicates a deleted entry.  */
-  e->self_p = 0;
-  e->next = 0;
+  e->deleted = 1;
 
   /* Take out of the directory ordered list.  */
   ordered_unlink (e);
 
+  hurd_ihash_locp_remove (>htable, e->dir_locp);
+
   /* If there's a node attached, we'll delete the entry whenever it goes
  away, otherwise, 

[PATCH] Use libihash to store directory entries in ftpfs.

2016-02-07 Thread Flavio Cruz
* ftpfs/ftpfs.h: Add dir_locp for each directory entry and replace the table 
with a libihash table.
* ftpfs/dir.c: Modify the code to use libihash. Remove several functions such 
as rehash and insert.
---
 ftpfs/dir.c   | 142 --
 ftpfs/ftpfs.h |  17 +++
 2 files changed, 43 insertions(+), 116 deletions(-)

diff --git a/ftpfs/dir.c b/ftpfs/dir.c
index be20b3d..bd3b30c 100644
--- a/ftpfs/dir.c
+++ b/ftpfs/dir.c
@@ -30,72 +30,33 @@
 void
 free_entry (struct ftpfs_dir_entry *e)
 {
-  assert (! e->self_p);/* We should only free deleted nodes.  
*/
   free (e->name);
   if (e->symlink_target)
 free (e->symlink_target);
   free (e);
 }
-
-/* Put the directory entry E into the hash table HTABLE, of length HTABLE_LEN. 
 */
-static void
-insert (struct ftpfs_dir_entry *e,
-   struct ftpfs_dir_entry **htable, size_t htable_len)
-{
-  struct ftpfs_dir_entry **t = [e->hv % htable_len];
-  if (*t)
-(*t)->self_p = >next;
-  e->next = *t;
-  e->self_p = t;
-  *t = e;
-}
-
-/* Replace DIR's hashtable with a new one of length NEW_LEN, retaining all
-   existing entries.  */
-static error_t
-rehash (struct ftpfs_dir *dir, size_t new_len)
-{
-  int i;
-  size_t old_len = dir->htable_len;
-  struct ftpfs_dir_entry **old_htable = dir->htable;
-  struct ftpfs_dir_entry **new_htable =
-malloc (new_len * sizeof (struct ftpfs_dir_entry *));
-
-  if (! new_htable)
-return ENOMEM;
 
-  memset (new_htable, 0, new_len * sizeof(struct ftpfs_dir_entry *));
-
-  for (i = 0; i < old_len; i++)
-while (old_htable[i])
-  {
-   struct ftpfs_dir_entry *e = old_htable[i];
-
-   /* Remove E from the old table (don't bother to fixup
-  e->next->self_p).  */
-   old_htable[i] = e->next;
-
-   insert (e, new_htable, new_len);
-  }
-
-  free (old_htable);
-
-  dir->htable = new_htable;
-  dir->htable_len = new_len;
-
-  return 0;
-}
-
-/* Calculate NAME's hash value.  */
-static size_t
-hash (const char *name)
+/* Calculate NAME_PTR's hash value.  */
+static hurd_ihash_key_t
+ihash_hash (const void *name_ptr)
 {
+  const char *name = (const char *) name_ptr;
   size_t hv = 0;
   while (*name)
 hv = ((hv << 5) + *name++) & 0xFF;
   return hv;
 }
 
+/* Compare two names which are used as keys.  */
+static int
+ihash_compare (const void *key1, const void *key2)
+{
+  const char *name1 = (const char *) key1;
+  const char *name2 = (const char *) key2;
+
+  return strcmp (name1, name2) == 0;
+}
+
 /* Lookup NAME in DIR and return its entry.  If there is no such entry, and
ADD is true, then a new entry is allocated and returned, otherwise 0 is
returned (if ADD is true then 0 can be returned if a memory allocation
@@ -103,23 +64,14 @@ hash (const char *name)
 struct ftpfs_dir_entry *
 lookup (struct ftpfs_dir *dir, const char *name, int add)
 {
-  size_t hv = hash (name);
-  struct ftpfs_dir_entry *h = dir->htable[hv % dir->htable_len], *e = h;
-
-  while (e && strcmp (name, e->name) != 0)
-e = e->next;
+  struct ftpfs_dir_entry *e =
+hurd_ihash_find (>htable, (hurd_ihash_key_t) name);
 
   if (!e && add)
 {
-  if (dir->num_entries > dir->htable_len)
-   /* Grow the hash table.  */
-   if (rehash (dir, (dir->htable_len + 1) * 2 - 1) != 0)
- return 0;
-
   e = malloc (sizeof *e);
   if (e)
{
- e->hv = hv;
  e->name = strdup (name);
  e->node = 0;
  e->dir = dir;
@@ -128,13 +80,11 @@ lookup (struct ftpfs_dir *dir, const char *name, int add)
  e->symlink_target = 0;
  e->noent = 0;
  e->valid = 0;
+  e->deleted = 0;
  e->name_timestamp = e->stat_timestamp = 0;
  e->ordered_next = 0;
  e->ordered_self_p = 0;
- e->next = 0;
- e->self_p = 0;
- insert (e, dir->htable, dir->htable_len);
- dir->num_entries++;
+  hurd_ihash_add (>htable, (hurd_ihash_key_t) e->name, e);
}
 }
 
@@ -148,28 +98,21 @@ ordered_unlink (struct ftpfs_dir_entry *e)
   if (e->ordered_self_p)
 *e->ordered_self_p = e->ordered_next;
   if (e->ordered_next)
-e->ordered_next->self_p = e->ordered_self_p;
+e->ordered_next->ordered_self_p = e->ordered_self_p;
 }
 
 /* Delete E from its directory, freeing any resources it holds.  */
 static void
 delete (struct ftpfs_dir_entry *e, struct ftpfs_dir *dir)
 {
-  dir->num_entries--;
-
-  /* Take out of the hash chain.  */
-  if (e->self_p)
-*e->self_p = e->next;
-  if (e->next)
-e->next->self_p = e->self_p;
-
   /* This indicates a deleted entry.  */
-  e->self_p = 0;
-  e->next = 0;
+  e->deleted = 1;
 
   /* Take out of the directory ordered list.  */
   ordered_unlink (e);
 
+  hurd_ihash_locp_remove (>htable, e->dir_locp);
+
   /* If there's a node attached, we'll delete the entry whenever it goes
  away, otherwise, just delete it now.  */
   if (! e->node)
@@ -180,25 +123,23 @@ delete (struct