473,799 Members | 2,837 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

hashlib package

I released this under GPL some time ago, (2003-May) and have been
advertising it occasionally here, where it seemed applicable. I
have received no bug reports.

I have just gotten around to writing a usage manual for it, which
follows. I would like some opinions on it. Please don't quote the
whole thing back at me, a short excerpt followed by your pithy
commentary will do nicely. I am off for an operation Monday,
so I won't be available for a while after that, and you might as
well hold things after Saturday.

HOW TO USE hashlib
=============== ===

<http://cbfalconer.home .att.net/download/hashlib.zip>

To use this easily you should also have a copy of hashlib.h
printed out, or easily available in another editor window. It
describes the complete interface to hashlib, and this is just an
explanation of the functions, why they exist, etc. hashlib.h
is extensively commented.

What is it for?
==============

You may be wondering "for what is hashlib useful". The answer
is that it is a storage facility. You can hand it things, and
it will tuck them away, and make it easy for you to find them
later.

A major point is that the time it takes to store, find, delete,
or retrieve an item is almost constant no matter how big the
table gets. Also, you don't have to worry about the table size,
because it will automatically adapt itself. It may hold 5 items
or millions. The limit is your memory.

What does it do?
===============

For a list of the things it will do, you should have the file
"hashlib.h" handy. This details all the things you can do, and
how to customize the system to your data. The interface
functions are:

hshinit, hshkill Make or destroy a hashtable
hshfind, hshinsert, hshdelete Insert, find, take out items
hshwalk For advanced usage, later
hshstatus Such things as how many stored

Customizing to your data:
=============== =========

In order to use a table, the first thing you have to do is to
create it with hshinit. At that time you tell hashlib how to
process your data. I will return to this later.

Your actual data takes some form, which is entirely up to you.
It must be possible to refer to a complete data item by a
single pointer. Your data also will have some sort of key, or
even multiple keys. It can have whatever auxiliary data you
like. This implies you must define a structure somewhere for
your own benefit:

typedef struct hashitem {
sometype yourkey;
otherstuff yourdata;
} item, *itemptr;

The field names, structure name, typedef'd names, etc are
entirely up to you. Somewhere in your program you will have
at least one of these things. hashlib will make more of them
in which to store copies of the data you insert.

Equality
========

Since hashlib works on all forms of data, it obviously can't
read your data description. So you have to tell it how to
find out that two data items have the identical key. This
introduces the type (defined in hashlib.h):

typedef int (*hshcmpfn)(voi d *litem, void *ritem);

which is a function you will design and program, and one of
the items you pass in the hshinit call is a pointer to that
function. Let us assume that in the item definition above
sometype is int (such as the typedef below under copying).
Then your comparison function could be:

mycmp(void *litem, void *ritem)
{
itemptr left = litem;
itemptr right = ritem;
int lvalue, rvalue;

lvalue = left->yourkey;
rvalue = right->yourkey;
return lvalue == rvalue;
}

NOTE: I have made this function more complex than it need
be, in order to emphasize how it goes about it.

The left and right pointers come from hashlib, and hashlib
doesn't know about your data type. Therefore it converts them
into the C universal pointer, a "void *". When you get them
back you have to convert them back into itemptr, so you can
access the fields of your data.

All hashlib cares about is "are they equal", so the above
returns only 0 or 1, for notequal and equal. The comparison
routine will be useful for other things if you make it return
-1, 0, or +1 for less, equal, greater. To do this you could
make the return statement say:

return (lvalue > rvalue) - (lvalue < rvalue);

which will turn out to be 1-0, 0-0, 0-1 for the three cases.
The point is not to return (lvalue - rvalue), because this
can run into overflow and give erroneous results.

Copying
=======

When you pass an item to hashlib you don't want to worry about
who owns the space it takes. Therefore the principle is
"hashlib owns all the items it stores". Thus hashlib makes a
copy of any data item it inserts into the table. Once more,
only you know how to do this, and you have to tell hashlib.

typedef void *(*hshdupfn)(vo id *item);

in hashlib.h specifies what this function must look like. For
the simple structure above, all it would have to do is malloc
space for a copy, and copy the fields. Remember it is dealing
with pointer to data, and the first thing you have to do is
make the item pointer into a pointer to your structure.

Lets make the simple data structure above more concrete:

typedef struct hashitem {
int yourkey;
int yourdata;
} item, *itemptr;

Then the hshdupefn (notice how the function is defined by
editing the typedef for hshdupfn) could be:

void *mydupe(void *item)
{
itemptr myitem = item;
itemptr newitem;

if (newitem = malloc(sizeof *newitem) {
newitem.yourkey = myitem.yourkey;
newitem.yourdat a = myitem.yourdata ;
/* or "*newitem = *myitem" in this case */
}
return newitem;
}

Notice again that only your code knows what is in the items to
be stored, and thus how to copy them. Your item can be as
complicated as you wish. So lets make it store strings:

typedef struct hashitem {
char *yourkey;
int yourdata;
} item, *itemptr;

and see how it affects the hshdupefn. Yourkey is now just a
pointer to a string somewhere, which may want to be modified
or used in some manner. So we have do what is called a deep
copy.

void *mydupe(void *item)
{
itemptr myitem = item;
itemptr newitem;

if (newitem = malloc(sizeof *newitem) {
if (newitem->yourkey =
malloc(1+strlen (myitem->yourkey) {
strcpy(newitem->yourkey, myitem->yourkey;
newitem.yourdat a = myitem.yourdata ;
}
else { /* we ran out of memory, release and fail */
free(newitem)
newitem = NULL
}
}
return newitem;
}

Notice how it returns NULL if malloc fails to secure the
necessary memory anywhere. This allows hashlib to do the
right things under nasty cases, such as exhausting memory.

The need for a deep copy is generally signalled by having
pointers in your data type description. All those pointers have
to be resolved to data that can belong to the hash table.
Letting Go
==========

Once you have thrown a whole mess of data at hashlib, and it is
keeping track, you may decide to release it all. While you
could often just abandon it, and let the operating system clean
up after you when your program ends, this is not a good
practice. Besides, your program may not end. So you have to
tell hashlib how to get rid of one item, which it will use to
get rid of all of them when you use the hshkill function
(described later).

typedef void (*hshfreefn)(vo id *item);

in hashlib.h describes that function. Now we will assume the
complex hshdupefn last described above, and the corresponding
type definition for an item. Again, we build the function
header by editing the typedef and converting the passed void*
pointer:

void myundupe(void *item)
{
itemptr myitem = item;

free(myitem->yourkey); /* First, because this won't */
free(myitem); /* exist after this one. */
}

thus returning all the allocated memory. Notice how it undoes
everything that mydupe did. The mydupe/myundupe pair could even
open and close files, but you will rarely want to handle
thousands of open files at once.

Hashing
=======

This is fundamental to the efficient operation of a hashtable,
although hashlib can put up with pretty rotten hashing and still
grind out answers (but it may take a long time). What we need
to do is calculate a single unsigned long value from the key.
What these functions are is basically black magic, therefore
hashlib contains a couple of utility functions usable for
hashing strings. There are also examples of hashing integers
in the hashtest.c program along with some references to the
subject of creating hash functions.

Because of the efficient way hashlib handles overflows (it
basically just corrects them) it is necessary to have two
hash functions. For the above item type with strings, they
would be:

typedef unsigned long (*hshfn)(void *item);

for reference, which we edit again and get:

unsigned long myhash(void *item)
{
itemptr myitem = item; /* getting used to this? */
return hshstrhash(myit em->yourkey);
}

and we need two such functions, so:

unsigned long myrehash(void *item)
{
itemptr myitem = item; /* getting used to this? */
return hshstrehash(myi tem->yourkey);
}

which basically differ only in their names and in the
convenience hash function they call.

Now we have finally customized the system to our own data
format. We will tell hashlib about these functions when
we create a hashtable with hshinit.

Using hashlib
=============

First, we need some way to refer to the table. So we must
have a data item of type hshtbl* to hold it. We will initialize
that by calling hshinit. This is much like opening a file. For
convenience here is the prototype for hshinit again:

/* initialize and return a pointer to the data base */
hshtbl *hshinit(hshfn hash, hshfn rehash,
hshcmpfn cmp,
hshdupfn dupe, hshfreefn undupe,
int hdebug);

Now this following is a fragment from your code:

hshtbl *mytable;

/* initialize and return a pointer to the data base */
mytable = hshinit(myhash, myrehash,
mycmp,
mydupe, myundupe,
0);

which tells hashlib all about the customizing functions you have
created. Note that all those functions can be static, unless
you have other uses for them outside your source file. You can
use those functions yourself as you please.

Don't forget the final 0 in the call to hshinit. That parameter
provides for future extensions and debugging abilities, and
passing a zero here will maintain compatibility.

You can create more than one hash table if you desire. If they
handle the same data format you can just do exactly the same
call as above, except you will need a new variable of type
hshtbl* to hold the table identification. If they don't hold
the same data type you can supply different functions to
hshinit. It is up to you.

hshtbl *mysecondtable;

mysecondtable = hshinit(....); /* as before */

These tables will live until you exterminate them. Meanwhile
you can store, find, delete, etc. items from the table. You
destroy the table by calling hshkill with the pointer that
hshinit returned.

hshkill(mytable ); /* all gone */

but until that is done, lets use the functions:

Inserting (storing) data:
=============== ==========
From here on I am assuming you have opened the hash table with

mytable = hshinit(...), and that you have defined your data
with:

typedef struct hashitem {
char *yourkey;
int yourdata;
} item, *itemptr;

Surprise, you store data by calling hshinsert. Here is the
prototype, for reference:

void * hshinsert(hshtb l *master, void *item);

and you call it with a pointer to the table in which to insert
the item, and a pointer to the item to insert.

You may have a variable of type item (after all, you know what
it is, even if hashlib does not). So the critical items are:

hshtable *mytable;
item myitem;
item *something;

You will put the data you want into myitem, filling its fields
as needed. Then you call:

something = hshinsert(mytab le, &myitem);

If, after this, 'something' is NULL, the insertion failed
(probably because you ran out of memory). Otherwise 'something'
points to the piece of memory owned by hshlib which stores a
copy of myitem. You can use something to modify the stored
copy, but you MUST NOT do anything that would change the value
of the key, and thus change what a hshfn such as myhash or
myrehash returns when passed that item. NEVER EVER do that.

One thing you might want to do is have a field in an item that
holds a count. You could have the dupe function zero this
field, so that you know how it is initialized. Then, when
hshinsert returns an itemptr you can use that to increment
that field. That way you can keep track of how many times a
given key has been inserted.

NOTE: If hshinsert finds an item already stored, it simply
returns a pointer to that storage. It does not use the dupe
function to make another copy.

Finding a data item by the key:
=============== ===============

Again we have the same variables as above for insertion. We
simply call:

something = hshfind(mytable , &item);

and if 'something' is NULL the item is not present, otherwise
it is a pointer to the memory holding it. The same cautions
as for hshinsert hold, i.e. you MUST NOT do anything that
affects the key and thus the hash functions. Being present
means only that 'something' and &item have identical keys, as
defined by mycmp() function.

Deleting stored items:
=============== ======

Again, we have the same variables. Surprise, the calling format
is the same:

something = hshdelete(mytab le, &item);

but now there is a significant difference. The hash table no
longer owns the memory that stored that item, you do. So you
have to do something with it, assuming it isn't NULL (meaning
that the value in item was never stored in the table). What
you do is up to you, but sooner or later you should release
it by:
myundupe(someth ing);

which you designed specifically for this purpose.

Other abilities
===============

I plan to add information about walking the entire contents of
the table, and performing operations on each stored item. There
are illustrations of these operations in the demonstration
applications (markov and wdfreq) in the hashlib package.

--
Chuck F (cb********@yah oo.com) (cb********@wor ldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net> USE worldnet address!

Nov 14 '05
21 3056
CBFalconer <cb********@yah oo.com> wrote in message news:<41******* ********@yahoo. com>...
I released this under GPL some time ago, (2003-May) and have been
advertising it occasionally here, where it seemed applicable. I
have received no bug reports.

I have just gotten around to writing a usage manual for it, which
follows. I would like some opinions on it. Please don't quote the
whole thing back at me, a short excerpt followed by your pithy
commentary will do nicely. I am off for an operation Monday,
so I won't be available for a while after that, and you might as
well hold things after Saturday.

HOW TO USE hashlib
=============== ===

<http://cbfalconer.home .att.net/download/hashlib.zip>

To use this easily you should also have a copy of hashlib.h
printed out, or easily available in another editor window. It
describes the complete interface to hashlib, and this is just an
explanation of the functions, why they exist, etc. hashlib.h
is extensively commented.

What is it for?
==============

You may be wondering "for what is hashlib useful". The answer
is that it is a storage facility. You can hand it things, and
it will tuck them away, and make it easy for you to find them
later.

A major point is that the time it takes to store, find, delete,
or retrieve an item is almost constant no matter how big the
table gets. Also, you don't have to worry about the table size,
because it will automatically adapt itself. It may hold 5 items
or millions. The limit is your memory.

What does it do?
===============

For a list of the things it will do, you should have the file
"hashlib.h" handy. This details all the things you can do, and
how to customize the system to your data. The interface
functions are:

hshinit, hshkill Make or destroy a hashtable
hshfind, hshinsert, hshdelete Insert, find, take out items
hshwalk For advanced usage, later
hshstatus Such things as how many stored

Customizing to your data:
=============== =========

In order to use a table, the first thing you have to do is to
create it with hshinit. At that time you tell hashlib how to
process your data. I will return to this later.

Your actual data takes some form, which is entirely up to you.
It must be possible to refer to a complete data item by a
single pointer. Your data also will have some sort of key, or
even multiple keys. It can have whatever auxiliary data you
like. This implies you must define a structure somewhere for
your own benefit:

typedef struct hashitem {
sometype yourkey;
otherstuff yourdata;
} item, *itemptr;

The field names, structure name, typedef'd names, etc are
entirely up to you. Somewhere in your program you will have
at least one of these things. hashlib will make more of them
in which to store copies of the data you insert.

Equality
========

Since hashlib works on all forms of data, it obviously can't
read your data description. So you have to tell it how to
find out that two data items have the identical key. This
introduces the type (defined in hashlib.h):

typedef int (*hshcmpfn)(voi d *litem, void *ritem);

which is a function you will design and program, and one of
the items you pass in the hshinit call is a pointer to that
function. Let us assume that in the item definition above
sometype is int (such as the typedef below under copying).
Then your comparison function could be:

mycmp(void *litem, void *ritem)
{
itemptr left = litem;
itemptr right = ritem;
int lvalue, rvalue;

lvalue = left->yourkey;
rvalue = right->yourkey;
return lvalue == rvalue;
}

NOTE: I have made this function more complex than it need
be, in order to emphasize how it goes about it.

The left and right pointers come from hashlib, and hashlib
doesn't know about your data type. Therefore it converts them
into the C universal pointer, a "void *". When you get them
back you have to convert them back into itemptr, so you can
access the fields of your data.

All hashlib cares about is "are they equal", so the above
returns only 0 or 1, for notequal and equal. The comparison
routine will be useful for other things if you make it return
-1, 0, or +1 for less, equal, greater. To do this you could
make the return statement say:

return (lvalue > rvalue) - (lvalue < rvalue);

which will turn out to be 1-0, 0-0, 0-1 for the three cases.
The point is not to return (lvalue - rvalue), because this
can run into overflow and give erroneous results.

Copying
=======

When you pass an item to hashlib you don't want to worry about
who owns the space it takes. Therefore the principle is
"hashlib owns all the items it stores". Thus hashlib makes a
copy of any data item it inserts into the table. Once more,
only you know how to do this, and you have to tell hashlib.

typedef void *(*hshdupfn)(vo id *item);

in hashlib.h specifies what this function must look like. For
the simple structure above, all it would have to do is malloc
space for a copy, and copy the fields. Remember it is dealing
with pointer to data, and the first thing you have to do is
make the item pointer into a pointer to your structure.

Lets make the simple data structure above more concrete:

typedef struct hashitem {
int yourkey;
int yourdata;
} item, *itemptr;

Then the hshdupefn (notice how the function is defined by
editing the typedef for hshdupfn) could be:

void *mydupe(void *item)
{
itemptr myitem = item;
itemptr newitem;

if (newitem = malloc(sizeof *newitem) {
newitem.yourkey = myitem.yourkey;
newitem.yourdat a = myitem.yourdata ;
/* or "*newitem = *myitem" in this case */
}
return newitem;
}

Notice again that only your code knows what is in the items to
be stored, and thus how to copy them. Your item can be as
complicated as you wish. So lets make it store strings:

typedef struct hashitem {
char *yourkey;
int yourdata;
} item, *itemptr;

and see how it affects the hshdupefn. Yourkey is now just a
pointer to a string somewhere, which may want to be modified
or used in some manner. So we have do what is called a deep
copy.

void *mydupe(void *item)
{
itemptr myitem = item;
itemptr newitem;

if (newitem = malloc(sizeof *newitem) {
if (newitem->yourkey =
malloc(1+strlen (myitem->yourkey) {
strcpy(newitem->yourkey, myitem->yourkey;
newitem.yourdat a = myitem.yourdata ;
}
else { /* we ran out of memory, release and fail */
free(newitem)
newitem = NULL
}
}
return newitem;
}

Notice how it returns NULL if malloc fails to secure the
necessary memory anywhere. This allows hashlib to do the
right things under nasty cases, such as exhausting memory.

The need for a deep copy is generally signalled by having
pointers in your data type description. All those pointers have
to be resolved to data that can belong to the hash table.
Letting Go
==========

Once you have thrown a whole mess of data at hashlib, and it is
keeping track, you may decide to release it all. While you
could often just abandon it, and let the operating system clean
up after you when your program ends, this is not a good
practice. Besides, your program may not end. So you have to
tell hashlib how to get rid of one item, which it will use to
get rid of all of them when you use the hshkill function
(described later).

typedef void (*hshfreefn)(vo id *item);

in hashlib.h describes that function. Now we will assume the
complex hshdupefn last described above, and the corresponding
type definition for an item. Again, we build the function
header by editing the typedef and converting the passed void*
pointer:

void myundupe(void *item)
{
itemptr myitem = item;

free(myitem->yourkey); /* First, because this won't */
free(myitem); /* exist after this one. */
}

thus returning all the allocated memory. Notice how it undoes
everything that mydupe did. The mydupe/myundupe pair could even
open and close files, but you will rarely want to handle
thousands of open files at once.

Hashing
=======

This is fundamental to the efficient operation of a hashtable,
although hashlib can put up with pretty rotten hashing and still
grind out answers (but it may take a long time). What we need
to do is calculate a single unsigned long value from the key.
What these functions are is basically black magic, therefore
hashlib contains a couple of utility functions usable for
hashing strings. There are also examples of hashing integers
in the hashtest.c program along with some references to the
subject of creating hash functions.

Because of the efficient way hashlib handles overflows (it
basically just corrects them) it is necessary to have two
hash functions. For the above item type with strings, they
would be:

typedef unsigned long (*hshfn)(void *item);

for reference, which we edit again and get:

unsigned long myhash(void *item)
{
itemptr myitem = item; /* getting used to this? */
return hshstrhash(myit em->yourkey);
}

and we need two such functions, so:

unsigned long myrehash(void *item)
{
itemptr myitem = item; /* getting used to this? */
return hshstrehash(myi tem->yourkey);
}

which basically differ only in their names and in the
convenience hash function they call.

Now we have finally customized the system to our own data
format. We will tell hashlib about these functions when
we create a hashtable with hshinit.

Using hashlib
=============

First, we need some way to refer to the table. So we must
have a data item of type hshtbl* to hold it. We will initialize
that by calling hshinit. This is much like opening a file. For
convenience here is the prototype for hshinit again:

/* initialize and return a pointer to the data base */
hshtbl *hshinit(hshfn hash, hshfn rehash,
hshcmpfn cmp,
hshdupfn dupe, hshfreefn undupe,
int hdebug);

Now this following is a fragment from your code:

hshtbl *mytable;

/* initialize and return a pointer to the data base */
mytable = hshinit(myhash, myrehash,
mycmp,
mydupe, myundupe,
0);

which tells hashlib all about the customizing functions you have
created. Note that all those functions can be static, unless
you have other uses for them outside your source file. You can
use those functions yourself as you please.

Don't forget the final 0 in the call to hshinit. That parameter
provides for future extensions and debugging abilities, and
passing a zero here will maintain compatibility.

You can create more than one hash table if you desire. If they
handle the same data format you can just do exactly the same
call as above, except you will need a new variable of type
hshtbl* to hold the table identification. If they don't hold
the same data type you can supply different functions to
hshinit. It is up to you.

hshtbl *mysecondtable;

mysecondtable = hshinit(....); /* as before */

These tables will live until you exterminate them. Meanwhile
you can store, find, delete, etc. items from the table. You
destroy the table by calling hshkill with the pointer that
hshinit returned.

hshkill(mytable ); /* all gone */

but until that is done, lets use the functions:

Inserting (storing) data:
=============== ==========
From here on I am assuming you have opened the hash table with

mytable = hshinit(...), and that you have defined your data
with:

typedef struct hashitem {
char *yourkey;
int yourdata;
} item, *itemptr;

Surprise, you store data by calling hshinsert. Here is the
prototype, for reference:

void * hshinsert(hshtb l *master, void *item);

and you call it with a pointer to the table in which to insert
the item, and a pointer to the item to insert.

You may have a variable of type item (after all, you know what
it is, even if hashlib does not). So the critical items are:

hshtable *mytable;
item myitem;
item *something;

You will put the data you want into myitem, filling its fields
as needed. Then you call:

something = hshinsert(mytab le, &myitem);

If, after this, 'something' is NULL, the insertion failed
(probably because you ran out of memory). Otherwise 'something'
points to the piece of memory owned by hshlib which stores a
copy of myitem. You can use something to modify the stored
copy, but you MUST NOT do anything that would change the value
of the key, and thus change what a hshfn such as myhash or
myrehash returns when passed that item. NEVER EVER do that.

One thing you might want to do is have a field in an item that
holds a count. You could have the dupe function zero this
field, so that you know how it is initialized. Then, when
hshinsert returns an itemptr you can use that to increment
that field. That way you can keep track of how many times a
given key has been inserted.

NOTE: If hshinsert finds an item already stored, it simply
returns a pointer to that storage. It does not use the dupe
function to make another copy.

Finding a data item by the key:
=============== ===============

Again we have the same variables as above for insertion. We
simply call:

something = hshfind(mytable , &item);

and if 'something' is NULL the item is not present, otherwise
it is a pointer to the memory holding it. The same cautions
as for hshinsert hold, i.e. you MUST NOT do anything that
affects the key and thus the hash functions. Being present
means only that 'something' and &item have identical keys, as
defined by mycmp() function.

Deleting stored items:
=============== ======

Again, we have the same variables. Surprise, the calling format
is the same:

something = hshdelete(mytab le, &item);

but now there is a significant difference. The hash table no
longer owns the memory that stored that item, you do. So you
have to do something with it, assuming it isn't NULL (meaning
that the value in item was never stored in the table). What
you do is up to you, but sooner or later you should release
it by:
myundupe(someth ing);

which you designed specifically for this purpose.

Other abilities
===============

I plan to add information about walking the entire contents of
the table, and performing operations on each stored item. There
are illustrations of these operations in the demonstration
applications (markov and wdfreq) in the hashlib package.


I don't have many comments right now, I'm sure if I used the library I
would think of some.

It would be a good idea to make an info page on hashlib too with the
same information in it. Maybe a man page too.
Nov 14 '05 #11
ro***********@a ntenova.com (Rob Thorpe) writes:
I don't have many comments right now, I'm sure if I used the library I
would think of some.

It would be a good idea to make an info page on hashlib too with the
same information in it. Maybe a man page too.


You quoted 423 lines of text to add "I don't have any comments?"
Please learn some netiquette.
--
Ben Pfaff
email: bl*@cs.stanford .edu
web: http://benpfaff.org
Nov 14 '05 #12
On Sat, 06 Nov 2004 09:54:03 -0800, Ben Pfaff <bl*@cs.stanfor d.edu> wrote:
ro***********@ antenova.com (Rob Thorpe) writes:
I don't have many comments right now, I'm sure if I used the library I
would think of some.

It would be a good idea to make an info page on hashlib too with the
same information in it. Maybe a man page too.


You quoted 423 lines of text to add "I don't have any comments?"
Please learn some netiquette.


I was about to make the same comment.

Jon
Nov 14 '05 #13
On Sat, 06 Nov 2004 18:49:42 GMT, Jonathan Kirwan
<jk*****@easyst reet.com> wrote:
On Sat, 06 Nov 2004 09:54:03 -0800, Ben Pfaff <bl*@cs.stanfor d.edu> wrote:
ro*********** @antenova.com (Rob Thorpe) writes:
I don't have many comments right now, I'm sure if I used the library I
would think of some.

It would be a good idea to make an info page on hashlib too with the
same information in it. Maybe a man page too.


You quoted 423 lines of text to add "I don't have any comments?"
Please learn some netiquette.


I was about to make the same comment.


And the pair of you have contributed even less of value to the thread
than Mr. Thorpe did.
Nov 14 '05 #14
Richard Harter wrote:
And the pair of you have contributed even less of value to the thread
than Mr. Thorpe did.


And the both of us even less. But I fully agree with the two gentlemen:
we could use some netiquete regarding quotes.

Regards.

Nov 14 '05 #15
On Sat, 06 Nov 2004 20:28:23 GMT
cr*@tiac.net (Richard Harter) wrote:
On Sat, 06 Nov 2004 18:49:42 GMT, Jonathan Kirwan
<jk*****@easyst reet.com> wrote:
On Sat, 06 Nov 2004 09:54:03 -0800, Ben Pfaff <bl*@cs.stanfor d.edu>
wrote:
ro*********** @antenova.com (Rob Thorpe) writes:
<snip>
You quoted 423 lines of text to add "I don't have any comments?"
Please learn some netiquette.


I was about to make the same comment.


And the pair of you have contributed even less of value to the thread
than Mr. Thorpe did.


However, they still managed to produce a vastly higher signal to noise
ratio.

Not snipping is a real problem.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 14 '05 #16
CBFalconer <cb********@yah oo.com> wrote in message news:<41******* ********@yahoo. com>...
Andy wrote:

Could you explain the advantages of using your library vs. for
example the default tool function of libc (search.h) like
hcreate_r(), hsearch_r(), etc.?


I don't understand the question. None of the things you mention
exist in standard C, so those examples don't help. As I said in
the manual, it handles putting things away, and finding them again
later. I even described all the function calls to it.

hcreate_r() and hsearch_r() are standard function calls in libc now (I
think since v. 2.0). Run for example "man hcreate" to get some basic
info (the _r versions are the re-entrant versions, you can find their
declarations in search.h).
I was able to run these functions successfully even though I haven't
found
a way to browse the contents of the hash table (in a similar way your
function hashwalk() does).
Nov 14 '05 #17
Andy wrote:

CBFalconer <cb********@yah oo.com> wrote in message news:<41******* ********@yahoo. com>...
Andy wrote:

Could you explain the advantages of using your library vs. for
example the default tool function of libc (search.h) like
hcreate_r(), hsearch_r(), etc.?


I don't understand the question. None of the things you mention
exist in standard C, so those examples don't help. As I said in
the manual, it handles putting things away, and finding them again
later. I even described all the function calls to it.


hcreate_r() and hsearch_r() are standard function calls in libc now (I
think since v. 2.0). Run for example "man hcreate" to get some basic
info (the _r versions are the re-entrant versions, you can find their
declarations in search.h).


That's not the point.
I don't know what libc is, but standard C functions
are the functions which are described in the C standard.

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n869/

--
pete
Nov 14 '05 #18
On 6 Nov 2004 18:54:58 -0800, in comp.lang.c , a_***********@h otmail.com
(Andy) wrote:
CBFalconer <cb********@yah oo.com> wrote in message news:<41******* ********@yahoo. com>...
Andy wrote:
>
> Could you explain the advantages of using your library vs. for
> example the default tool function of libc (search.h) like
> hcreate_r(), hsearch_r(), etc.?
I don't understand the question. None of the things you mention
exist in standard C,


hcreate_r() and hsearch_r() are standard function calls in libc now (I
think since v. 2.0).


CBF was being ironic.

When you x-post to comp.lang.c its as well to be sure you know the
topicality requirement here. That is standard C as definedby the ISO
standard. What extras might be in yuor libc are largely irrelevant, and
could technically render it an "illegal" c implementation.
Run for example "man hcreate"


f:\program files\4nt500>ma n hcreate
4NT: Unknown command "man"

Hmm.
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt >

----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Nov 14 '05 #19
CBFalconer wrote:
Eric Sosman wrote:
The implicit `int' strikes me as a poor idea --
it was, after all, outlawed five years ago.


What implicit int?


From the posting that started this thread:
Then your comparison function could be:

mycmp(void *litem, void *ritem)
{
itemptr left = litem;
itemptr right = ritem;
int lvalue, rvalue;

lvalue = left->yourkey;
rvalue = right->yourkey;
return lvalue == rvalue;
}
The function is defined without an explicit return type,
which means "implicit int" under C89 rules and "diagnostic
required" under C99.
The first mydupe() function has (at least) three
syntax errors. (Two of them are, I think, a consequence
of hiding a pointer behind a typedef, a practice I find
Really Ugly.) Unoriginal suggestion: Put all these code
snippets into a complete program, compile and test the
program, and then cut'n'paste into the manual. In short,
do as K&R did.


It is in a complete program - did you see the link to hashlib.zip?


The existence of a (putatively) correct program at the
other end of a link is not the issue: The problem is that
the illustrative code shown in the manual is faulty. Here
it is, again from the thread-originating post:
void *mydupe(void *item)
{
itemptr myitem = item;
itemptr newitem;

if (newitem = malloc(sizeof *newitem) {
newitem.yourkey = myitem.yourkey;
newitem.yourdat a = myitem.yourdata ;
/* or "*newitem = *myitem" in this case */
}
return newitem;
}


Note the unbalanced parentheses in the `if' statement and
the four uses of `.' where `->' was intended. (It's a good
thing I said "at least" three errors.)

I'm suggesting that you compile and test the actual code
given in the manual. He who fails to follow the example of
K&R risks becoming an example in the next edition of K&P.[*]
[*] Not Kernighan and Pike but Kernighan and Plauger
"The Elements of Programming Style." Instances of
faulty code are analyzed, not just for their faults
but also for the underlying causes. The bad code
comes from various published programming texts whose
authors seem not to have insisted upon attribution ...
A sobering must-read for any professional programmer.

--
Er*********@sun .com

Nov 14 '05 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
12683
by: chris.dunigan | last post by:
I'm looking for an example of how to execute an existing DTS­ package from an ASP (VB)script and would appreciate any and all response. ­I don't even know if it's possible Thanks - Chuck Gatto Dan Guzman Apr 27 2000, 12:00 am show options
3
1936
by: Petterson Mikael | last post by:
Hi, I have the following package names ( in an xml) that I will transform to html. I need to sort them. <package name="se.company.product.subproduct.boam.fpx.testsignals"> <package name="se.company.product.subproduct.boam.mao.iface.enum.hidden"> When I use <xsl:sort select="." order="ascending"/>
3
2836
by: shorti | last post by:
running on AIX with DB2 v8.2.2 I ran across a problem with naming source files with similar names. For instance, if I have these three files: upd_startaccessingdb.sqc upd_startusingdb.sqc upd_startreconproc.sqc and I precompile like so:
2
1968
by: rtilley | last post by:
Is there a road map for python a 2.5 releases yet? I'd like to begin testing the new hashlib module with some old scripts I have that currently use the md5 and sha modules. Thanks, Brad
0
1438
by: CBFalconer | last post by:
I have revised my hashlib package, it can now handle something like 48,000,000 entries. At this level (about 8,000,000 up) you may run into problems with your systems malloc/free package. However it evinces no problems with my revised nmalloc package for DJGPP. The interface is unchanged, so previous users should be able to drop in the new package to expand the capacity. Both hashlib and nmalloc are available at: ...
5
2183
by: Mathias Panzenboeck | last post by:
Hi. I wrote a small hashlib for C. Because I'm new to hashes I looked at pythons implementation and reused *some* of the code... or more the mathematical "hash-function", not really the code. In particular I looked at pythons hash and lookup functions, so I came up with this (see the code underneath). So, can this code be considered as derived and do I have to put my code under the GPL? I'd like to publish it under something less...
0
3880
debasisdas
by: debasisdas | last post by:
The following thread contains some useful tips/sample codes regarding PACKAGES in oracle, that the forum members may find useful. A package is a collection of procedures,functions,cursors,global variables etc. A package is also stored as an Object in the database. A package ha s two parts 1. Package-------------Specification. 2. Package body---Implimentaton.
0
3849
debasisdas
by: debasisdas | last post by:
SAMPLE PACKAGE EX#3 ==================== PACKAGE SPECIFICATION -------------------------------------------- CREATE OR REPLACE PACKAGE MYPACK AS PROCEDURE SHOWENAME(EMPID IN NUMBER); FUNCTION SHOWSAL(EMPID IN NUMBER) RETURN NUMBER; END MYPACK;
0
1923
by: Steven Samuel Cole | last post by:
Hi Stephane, thanks for your reply! :-) I do not get any notification or warning or whatever from dpkg, all output I get when running # sudo dpkg -i python-<package name>_0.0.1-4927-1_all.deb is Selecting previously deselected package python-<package name>. (Reading database ... 15026 files and directories currently installed.)
0
9687
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10251
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10027
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9072
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6805
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5463
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5585
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4139
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2938
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.