Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Tor
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Container Registry
Model registry
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
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
The Tor Project
Core
Tor
Commits
cfab9f07
Commit
cfab9f07
authored
12 years ago
by
Nick Mathewson
Browse files
Options
Downloads
Patches
Plain Diff
Add a data-invariant linear-search map structure
I'm going to use this for looking op keys server-side for ntor.
parent
014e6905
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/common/di_ops.c
+72
-0
72 additions, 0 deletions
src/common/di_ops.c
src/common/di_ops.h
+14
-0
14 additions, 0 deletions
src/common/di_ops.h
src/test/test_containers.c
+45
-0
45 additions, 0 deletions
src/test/test_containers.c
with
131 additions
and
0 deletions
src/common/di_ops.c
+
72
−
0
View file @
cfab9f07
...
...
@@ -8,6 +8,8 @@
#include
"orconfig.h"
#include
"di_ops.h"
#include
"torlog.h"
#include
"util.h"
/**
* Timing-safe version of memcmp. As memcmp, compare the <b>sz</b> bytes at
...
...
@@ -131,3 +133,73 @@ tor_memeq(const void *a, const void *b, size_t sz)
return
1
&
((
any_difference
-
1
)
>>
8
);
}
/* Implement di_digest256_map_t as a linked list of entries. */
struct
di_digest256_map_t
{
struct
di_digest256_map_t
*
next
;
uint8_t
key
[
32
];
void
*
val
;
};
/** Release all storage held in <b>map</b>, calling free_fn on each value
* as we go. */
void
dimap_free
(
di_digest256_map_t
*
map
,
dimap_free_fn
free_fn
)
{
while
(
map
)
{
di_digest256_map_t
*
victim
=
map
;
map
=
map
->
next
;
if
(
free_fn
)
free_fn
(
victim
->
val
);
tor_free
(
victim
);
}
}
/** Adjust the map at *<b>map</b>, adding an entry for <b>key</b> ->
* <b>val</b>, where <b>key</b> is a DIGEST256_LEN-byte key.
*
* The caller MUST NOT add a key that already appears in the map.
*/
void
dimap_add_entry
(
di_digest256_map_t
**
map
,
const
uint8_t
*
key
,
void
*
val
)
{
di_digest256_map_t
*
new_ent
;
{
void
*
old_val
=
dimap_search
(
*
map
,
key
,
NULL
);
tor_assert
(
!
old_val
);
tor_assert
(
val
);
}
new_ent
=
tor_malloc_zero
(
sizeof
(
di_digest256_map_t
));
new_ent
->
next
=
*
map
;
memcpy
(
new_ent
->
key
,
key
,
32
);
new_ent
->
val
=
val
;
*
map
=
new_ent
;
}
/** Search the map at <b>map</b> for an entry whose key is <b>key</b> (a
* DIGEST256_LEN-byte key) returning the corresponding value if we found one,
* and returning <b>dflt_val</b> if the key wasn't found.
*
* This operation takes an amount of time dependent only on the length of
* <b>map</b>, not on the position or presence of <b>key</b> within <b>map</b>.
*/
void
*
dimap_search
(
const
di_digest256_map_t
*
map
,
const
uint8_t
*
key
,
void
*
dflt_val
)
{
uintptr_t
result
=
(
uintptr_t
)
dflt_val
;
while
(
map
)
{
uintptr_t
r
=
(
uintptr_t
)
tor_memeq
(
map
->
key
,
key
,
32
);
r
-=
1
;
/* Now r is (uintptr_t)-1 if memeq returned false, and
* 0 if memeq returned true. */
result
&=
r
;
result
|=
((
uintptr_t
)(
map
->
val
))
&
~
r
;
map
=
map
->
next
;
}
return
(
void
*
)
result
;
}
This diff is collapsed.
Click to expand it.
src/common/di_ops.h
+
14
−
0
View file @
cfab9f07
...
...
@@ -27,5 +27,19 @@ int tor_memeq(const void *a, const void *b, size_t sz);
#define fast_memeq(a,b,c) (0==memcmp((a),(b),(c)))
#define fast_memneq(a,b,c) (0!=memcmp((a),(b),(c)))
/** A type for a map from DIGEST256_LEN-byte blobs to void*, such that
* data lookups take an amount of time proportional only to the size
* of the map, and not to the position or presence of the item in the map.
*
* Not efficient for large maps! */
typedef
struct
di_digest256_map_t
di_digest256_map_t
;
typedef
void
(
*
dimap_free_fn
)(
void
*
);
void
dimap_free
(
di_digest256_map_t
*
map
,
dimap_free_fn
free_fn
);
void
dimap_add_entry
(
di_digest256_map_t
**
map
,
const
uint8_t
*
key
,
void
*
val
);
void
*
dimap_search
(
const
di_digest256_map_t
*
map
,
const
uint8_t
*
key
,
void
*
dflt_val
);
#endif
This diff is collapsed.
Click to expand it.
src/test/test_containers.c
+
45
−
0
View file @
cfab9f07
...
...
@@ -782,6 +782,50 @@ test_container_order_functions(void)
;
}
static
void
test_di_map
(
void
*
arg
)
{
di_digest256_map_t
*
map
=
NULL
;
const
uint8_t
key1
[]
=
"In view of the fact that it was "
;
const
uint8_t
key2
[]
=
"superficially convincing, being "
;
const
uint8_t
key3
[]
=
"properly enciphered in a one-tim"
;
const
uint8_t
key4
[]
=
"e cipher scheduled for use today"
;
char
*
v1
=
tor_strdup
(
", it came close to causing a disaster..."
);
char
*
v2
=
tor_strdup
(
"I regret to have to advise you that the mission"
);
char
*
v3
=
tor_strdup
(
"was actually initiated..."
);
/* -- John Brunner, _The Shockwave Rider_ */
(
void
)
arg
;
/* Try searching on an empty map. */
tt_ptr_op
(
NULL
,
==
,
dimap_search
(
map
,
key1
,
NULL
));
tt_ptr_op
(
NULL
,
==
,
dimap_search
(
map
,
key2
,
NULL
));
tt_ptr_op
(
v3
,
==
,
dimap_search
(
map
,
key2
,
v3
));
dimap_free
(
map
,
NULL
);
map
=
NULL
;
/* Add a single entry. */
dimap_add_entry
(
&
map
,
key1
,
v1
);
tt_ptr_op
(
NULL
,
==
,
dimap_search
(
map
,
key2
,
NULL
));
tt_ptr_op
(
v3
,
==
,
dimap_search
(
map
,
key2
,
v3
));
tt_ptr_op
(
v1
,
==
,
dimap_search
(
map
,
key1
,
NULL
));
/* Now try it with three entries in the map. */
dimap_add_entry
(
&
map
,
key2
,
v2
);
dimap_add_entry
(
&
map
,
key3
,
v3
);
tt_ptr_op
(
v1
,
==
,
dimap_search
(
map
,
key1
,
NULL
));
tt_ptr_op
(
v2
,
==
,
dimap_search
(
map
,
key2
,
NULL
));
tt_ptr_op
(
v3
,
==
,
dimap_search
(
map
,
key3
,
NULL
));
tt_ptr_op
(
NULL
,
==
,
dimap_search
(
map
,
key4
,
NULL
));
tt_ptr_op
(
v1
,
==
,
dimap_search
(
map
,
key4
,
v1
));
done:
tor_free
(
v1
);
tor_free
(
v2
);
tor_free
(
v3
);
dimap_free
(
map
,
NULL
);
}
#define CONTAINER_LEGACY(name) \
{ #name, legacy_test_helper, 0, &legacy_setup, test_container_ ## name }
...
...
@@ -796,6 +840,7 @@ struct testcase_t container_tests[] = {
CONTAINER_LEGACY
(
strmap
),
CONTAINER_LEGACY
(
pqueue
),
CONTAINER_LEGACY
(
order_functions
),
{
"di_map"
,
test_di_map
,
0
,
NULL
,
NULL
},
END_OF_TESTCASES
};
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