Re: [strongSwan] Remove all elements from a hashtable_t

2010-06-09 Thread Tobias Brunner
Hi Graham,

> If I get a chance, I'll try out your patch, this may take some weeks  
> to getting around to though.

Unfortunately, the patch contained a small bug.  But I commited a  
proper version to master on Monday (see [1]).

Regards,
Tobias

[1]http://git.strongswan.org/?p=strongswan.git;a=commit;h=b2ddaf07755176eab43bc8c58aa632eb915f4786

___
Users mailing list
Users@lists.strongswan.org
https://lists.strongswan.org/mailman/listinfo/users


Re: [strongSwan] Remove all elements from a hashtable_t

2010-06-09 Thread Graham Hudspith
Martin, Tobias,

Thanks for the info. I'm glad you confirmed there was no "secret" method of
emptying the hashtable that I'd missed. Also that my suspicions about
invalidating the enumerator if I enumerated-and-removed were correct.

In the end (a Friday afternoon deadline approaching) I decided to simply
free all of the memory consumed by the elements in the hashtable followed by
deleting the hashtable and creating a new one. I would only do this once, on
startup, if a particular sort of error occurred. Not too expensive.

If I get a chance, I'll try out your patch, this may take some weeks to
getting around to though.

Cheers,

Graham.
___
Users mailing list
Users@lists.strongswan.org
https://lists.strongswan.org/mailman/listinfo/users

Re: [strongSwan] Remove all elements from a hashtable_t

2010-06-05 Thread Tobias Brunner
>> Does the hashtable_t+enumerator_t support this mode of operation ?
>
> I think so. The hashtable is based on many linked_lists, and the
> remove function from list can handle this.
>
> @Tobias: Please correct me if I'm wrong.

That wouldn't work.  For the linked list you also can't just call
remove, but have to call remove_at, otherwise the enumerator's internal
state would get invalid.  I've added such a function to the hash table,
see the attached patch (I hope it compiles, did this on a Windows machine).

>> Or, is there a better way of doing this ?
>
> Our list has handy destroy_offset/destroy_function helpers for cleanup
> purposes, but the hashtable is currently missing these functions. So:
> No.

We could add such functions to the hash table too, but we would probably
need two parameters, in order to free the keys and the values (since you
could use the same object as key and as value one of these would be
optional).

Alternatively, we could also add a new constructor, which would take two
new function parameters to free the keys and the values.  If they were
set, destroy/remove/remove_at would automatically free the memory of the
key and value.  We could then also easily add a remove_all method to
clear the whole hash table.

>> If all else fails, it may be better to free all the memory that the
>> elements point to and to then destroy the hashtable_t and create a
>> new one.
>
> Might be a little more efficient for large tables (?), but shouldn't
> really matter.

It probably depends on how often you have to clear the whole hash table,
how large it gets and how fast it grows.  If it grows fast to about the
same significant size, it might be better to remove all elements to
avoid the hash table getting resized all the time (you can avoid this if
you set the initial capacity to an appropriate value).

Regards,
Tobias
>From 3339a7e974eaa581678d3e57f1cc9c94924acecd Mon Sep 17 00:00:00 2001
From: Tobias Brunner 
Date: Sat, 5 Jun 2010 09:50:07 +0200
Subject: [PATCH] Adding a remove_at method to the hash table in order to remove 
items while enumerating them.

---
 src/libstrongswan/utils/hashtable.c |   33 -
 src/libstrongswan/utils/hashtable.h |7 +++
 2 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/src/libstrongswan/utils/hashtable.c 
b/src/libstrongswan/utils/hashtable.c
index 02c2258..1813d42 100644
--- a/src/libstrongswan/utils/hashtable.c
+++ b/src/libstrongswan/utils/hashtable.c
@@ -127,6 +127,11 @@ struct private_enumerator_t {
u_int row;
 
/**
+* current pair
+*/
+   pair_t *pair;
+
+   /**
 * enumerator for the current row
 */
enumerator_t *current;
@@ -318,6 +323,25 @@ static void *remove_(private_hashtable_t *this, void *key)
 }
 
 /**
+ * Implementation of hashtable_t.remove_at
+ */
+static void remove_at(private_hashtable_t *this,
+ private_enumerator_t *enumerator)
+{
+   if (enumerator->current)
+   {
+   linked_list_t *list;
+   list = this->table->table[enumerator->row];
+   if (list)
+   {
+   list->remove_at(list, enumerator->current);
+   free(enumerator->pair);
+   this->count--;
+   }
+   }
+}
+
+/**
  * Implementation of hashtable_t.get_count
  */
 static u_int get_count(private_hashtable_t *this)
@@ -334,17 +358,15 @@ static bool enumerate(private_enumerator_t *this, void 
**key, void **value)
{
if (this->current)
{
-   pair_t *pair;
-
-   if (this->current->enumerate(this->current, &pair))
+   if (this->current->enumerate(this->current, 
&this->pair))
{
if (key)
{
-   *key = pair->key;
+   *key = this->pair->key;
}
if (value)
{
-   *value = pair->value;
+   *value = this->pair->value;
}
return TRUE;
}
@@ -426,6 +448,7 @@ hashtable_t *hashtable_create(hashtable_hash_t hash, 
hashtable_equals_t equals,
this->public.put = (void*(*)(hashtable_t*,void*,void*))put;
this->public.get = (void*(*)(hashtable_t*,void*))get;
this->public.remove = (void*(*)(hashtable_t*,void*))remove_;
+   this->public.remove_at = (void(*)(hashtable_t*,enumerator_t*))remove_at;
this->public.get_count = (u_int(*)(hashtable_t*))get_count;
this->public.create_enumerator = 
(enumerator_t*(*)(hashtable_t*))create_enumerator;
this->public.destroy = (void(*)(hashtable_t

Re: [strongSwan] Remove all elements from a hashtable_t

2010-06-05 Thread Martin Willi
Hi Graham,

> It seems to me that the only way to delete all elements in the
> hashtable_t is to create an enumerator, enumerate over the elements
> and call remove for each element found.

Yes.

> Does the hashtable_t+enumerator_t support this mode of operation ?

I think so. The hashtable is based on many linked_lists, and the remove
function from list can handle this.

@Tobias: Please correct me if I'm wrong.

> Or, is there a better way of doing this ?

Our list has handy destroy_offset/destroy_function helpers for cleanup
purposes, but the hashtable is currently missing these functions. So:
No.

> If all else fails, it may be better to free all the memory that the
> elements point to and to then destroy the hashtable_t and create a new
> one.

Might be a little more efficient for large tables (?), but shouldn't
really matter.

Regards
Martin



___
Users mailing list
Users@lists.strongswan.org
https://lists.strongswan.org/mailman/listinfo/users