Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
T
tor
Manage
Activity
Members
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
jarl
tor
Commits
d5c47f04
Commit
d5c47f04
authored
8 years ago
by
Nick Mathewson
Browse files
Options
Downloads
Patches
Plain Diff
Add some how-to documentation for ht.h. Closes #19896
parent
7e3e482d
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/ext/ht.h
+90
-0
90 additions, 0 deletions
src/ext/ht.h
with
90 additions
and
0 deletions
src/ext/ht.h
+
90
−
0
View file @
d5c47f04
...
...
@@ -5,6 +5,96 @@
/* Based on ideas by Christopher Clark and interfaces from Niels Provos. */
/*
These macros provide an intrustive implementation for a typesafe chaining
hash table, loosely based on the BSD tree.h and queue.h macros. Here's
how to use them.
First, pick a the structure that you'll be storing in the hashtable. Let's
say that's "struct dinosaur". To this structure, you add an HT_ENTRY()
member, as such:
struct dinosaur {
HT_ENTRY(dinosaur) node; // The name inside the () must match the
// struct.
// These are just fields from the dinosaur structure...
long dinosaur_id;
char *name;
long age;
int is_ornithischian;
int is_herbivorous;
};
You can declare the hashtable itself as:
HT_HEAD(dinosaur_ht, dinosaur);
This declares a new 'struct dinosaur_ht' type.
Now you need to declare two functions to help implement the hashtable: one
compares two dinosaurs for equality, and one computes the hash of a
dinosaur. Let's say that two dinosaurs are equal if they have the same ID
and name.
int
dinosaurs_equal(const struct dinosaur *d1, const struct dinosaur *d2)
{
return d1->dinosaur_id == d2->dinosaur_id &&
0 == strcmp(d1->name, d2->name);
}
unsigned
dinosaur_hash(const struct dinosaur *d)
{
// This is a very bad hash function. Use siphash24g instead.
return (d->dinosaur_id + d->name[0] ) * 1337 + d->name[1] * 1337;
}
Now you'll need to declare the functions that manipulate the hash table.
To do this, you put this declaration either in a header file, or inside
a regular module, depending on what visibility you want.
HT_PROTOTYPE(dinosaur_ht, // The name of the hashtable struct
dinosaur, // The name of the element struct,
node, // The name of HT_ENTRY member
dinosaur_hash, dinosaurs_equal);
Later, inside a C function, you use this macro to declare the hashtable
functions.
HT_GENERATE2(dinosaur_ht, dinosaur, node, dinosaur_hash, dinosaurs_equal,
0.6, tor_reallocarray, tor_free_);
Note the use of tor_free_, not tor_free. The 0.6 is magic.
Now you can use the hashtable! You can initialize one with
struct dinosaur_ht my_dinos = HT_INITIALIZER();
Or create one in core with
struct dinosaur_ht *dinos = tor_malloc(sizeof(dinosaur_ht));
HT_INIT(dinosaur_ht, dinos);
To the hashtable, you use the HT_FOO(dinosaur_ht, ...) macros. For
example, to put new_dino into dinos, you say:
HT_REPLACE(dinosaur_ht, dinos, new_dino);
If you're searching for an element, you need to use a dummy 'key' element in
the search. For example.
struct dinosaur dino_key;
dino_key.dinosaur_id = 12345;
dino_key.name = tor_strdup("Atrociraptor");
struct dinosaur *found = HT_FIND(dinosaurs_ht, dinos, &dino_key);
Have fun with your hash table!
*/
#ifndef HT_H_INCLUDED_
#define HT_H_INCLUDED_
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment