Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
ccan
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
mirror
ccan
Commits
209a8190
Commit
209a8190
authored
Feb 20, 2020
by
Rusty Russell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
htable: htable_pick helper to select a random entry.
Signed-off-by:
Rusty Russell
<
rusty@rustcorp.com.au
>
parent
c910bdce
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
48 additions
and
3 deletions
+48
-3
ccan/htable/htable.c
ccan/htable/htable.c
+14
-0
ccan/htable/htable.h
ccan/htable/htable.h
+13
-0
ccan/htable/htable_type.h
ccan/htable/htable_type.h
+9
-1
ccan/htable/test/run-type.c
ccan/htable/test/run-type.c
+4
-1
ccan/htable/test/run.c
ccan/htable/test/run.c
+8
-1
No files found.
ccan/htable/htable.c
View file @
209a8190
...
...
@@ -365,6 +365,20 @@ void htable_delval_(struct htable *ht, struct htable_iter *i)
ht
->
deleted
++
;
}
void
*
htable_pick_
(
const
struct
htable
*
ht
,
size_t
seed
,
struct
htable_iter
*
i
)
{
void
*
e
;
struct
htable_iter
unwanted
;
if
(
!
i
)
i
=
&
unwanted
;
i
->
off
=
seed
%
((
size_t
)
1
<<
ht
->
bits
);
e
=
htable_next
(
ht
,
i
);
if
(
!
e
)
e
=
htable_first
(
ht
,
i
);
return
e
;
}
struct
htable
*
htable_check
(
const
struct
htable
*
ht
,
const
char
*
abortstr
)
{
void
*
p
;
...
...
ccan/htable/htable.h
View file @
209a8190
...
...
@@ -267,6 +267,19 @@ void *htable_prev_(const struct htable *htable, struct htable_iter *i);
htable_delval_(htable_debug(htable, HTABLE_LOC), i)
void
htable_delval_
(
struct
htable
*
ht
,
struct
htable_iter
*
i
);
/**
* htable_pick - set iterator to a random valid entry.
* @ht: the htable
* @seed: a random number to use.
* @i: the htable_iter which is output (or NULL).
*
* Usually used with htable_delval to delete a random entry. Returns
* NULL iff the table is empty, otherwise a random entry.
*/
#define htable_pick(htable, seed, i) \
htable_pick_(htable_debug(htable, HTABLE_LOC), seed, i)
void
*
htable_pick_
(
const
struct
htable
*
ht
,
size_t
seed
,
struct
htable_iter
*
i
);
/**
* htable_set_allocator - set calloc/free functions.
* @alloc: allocator to use, must zero memory!
...
...
ccan/htable/htable_type.h
View file @
209a8190
...
...
@@ -48,7 +48,8 @@
* type *<name>_first(const struct <name> *ht, struct <name>_iter *i);
* type *<name>_next(const struct <name> *ht, struct <name>_iter *i);
* type *<name>_prev(const struct <name> *ht, struct <name>_iter *i);
*
* type *<name>_pick(const struct <name> *ht, size_t seed,
* struct <name>_iter *i);
* It's currently safe to iterate over a changing hashtable, but you might
* miss an element. Iteration isn't very efficient, either.
*
...
...
@@ -146,6 +147,13 @@
return name##_del(ht, elem); \
return false; \
} \
static inline UNNEEDED bool name##_pick(const struct name *ht, \
size_t seed, \
struct name##_iter *iter) \
{ \
/* Note &iter->i == NULL iff iter is NULL */
\
return htable_pick(&ht->raw, seed, &iter->i); \
} \
static inline UNNEEDED type *name##_first(const struct name *ht, \
struct name##_iter *iter) \
{ \
...
...
ccan/htable/test/run-type.c
View file @
209a8190
...
...
@@ -116,7 +116,7 @@ int main(void)
void
*
p
;
struct
htable_obj_iter
iter
;
plan_tests
(
3
2
);
plan_tests
(
3
5
);
for
(
i
=
0
;
i
<
NUM_VALS
;
i
++
)
val
[
i
].
key
=
i
;
dne
=
i
;
...
...
@@ -128,6 +128,7 @@ int main(void)
/* We cannot find an entry which doesn't exist. */
ok1
(
!
htable_obj_get
(
&
ht
,
&
dne
));
ok1
(
!
htable_obj_pick
(
&
ht
,
0
,
NULL
));
/* Fill it, it should increase in size. */
add_vals
(
&
ht
,
val
,
NUM_VALS
);
...
...
@@ -142,6 +143,8 @@ int main(void)
/* Find all. */
find_vals
(
&
ht
,
val
,
NUM_VALS
);
ok1
(
!
htable_obj_get
(
&
ht
,
&
dne
));
ok1
(
htable_obj_pick
(
&
ht
,
0
,
NULL
));
ok1
(
htable_obj_pick
(
&
ht
,
0
,
&
iter
));
/* Walk once, should get them all. */
i
=
0
;
...
...
ccan/htable/test/run.c
View file @
209a8190
...
...
@@ -105,7 +105,7 @@ int main(void)
void
*
p
;
struct
htable_iter
iter
;
plan_tests
(
38
);
plan_tests
(
43
);
for
(
i
=
0
;
i
<
NUM_VALS
;
i
++
)
val
[
i
]
=
i
;
dne
=
i
;
...
...
@@ -134,6 +134,12 @@ int main(void)
/* Mask should be set. */
ok1
(
check_mask
(
&
ht
,
val
,
1
));
/* htable_pick should always return that value */
ok1
(
htable_pick
(
&
ht
,
0
,
NULL
)
==
val
);
ok1
(
htable_pick
(
&
ht
,
1
,
NULL
)
==
val
);
ok1
(
htable_pick
(
&
ht
,
0
,
&
iter
)
==
val
);
ok1
(
get_raw_ptr
(
&
ht
,
ht
.
table
[
iter
.
off
])
==
val
);
/* This should increase it again. */
add_vals
(
&
ht
,
val
,
1
,
1
);
ok1
(
ht
.
bits
==
2
);
...
...
@@ -210,6 +216,7 @@ int main(void)
htable_clear
(
&
ht
);
ok1
(
htable_count
(
&
ht
)
==
0
);
ok1
(
htable_pick
(
&
ht
,
0
,
NULL
)
==
NULL
);
return
exit_status
();
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment