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
d9297524
Commit
d9297524
authored
Mar 15, 2015
by
Rusty Russell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
invbloom: add callback for when an element becomes a singleton.
Signed-off-by:
Rusty Russell
<
rusty@rustcorp.com.au
>
parent
ea3e48a4
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
119 additions
and
3 deletions
+119
-3
ccan/invbloom/_info
ccan/invbloom/_info
+1
-0
ccan/invbloom/invbloom.c
ccan/invbloom/invbloom.c
+30
-3
ccan/invbloom/invbloom.h
ccan/invbloom/invbloom.h
+23
-0
ccan/invbloom/test/run-singletoncb.c
ccan/invbloom/test/run-singletoncb.c
+65
-0
No files found.
ccan/invbloom/_info
View file @
d9297524
...
...
@@ -59,6 +59,7 @@ int main(int argc, char *argv[])
printf("ccan/hash\n");
printf("ccan/short_types\n");
printf("ccan/tal\n");
printf("ccan/typesafe_cb\n");
return 0;
}
...
...
ccan/invbloom/invbloom.c
View file @
d9297524
...
...
@@ -23,6 +23,7 @@ struct invbloom *invbloom_new_(const tal_t *ctx,
ib
->
n_elems
=
n_elems
;
ib
->
id_size
=
id_size
;
ib
->
salt
=
salt
;
ib
->
singleton
=
NULL
;
ib
->
count
=
tal_arrz
(
ib
,
s32
,
n_elems
);
ib
->
idsum
=
tal_arrz
(
ib
,
u8
,
id_size
*
n_elems
);
if
(
!
ib
->
count
||
!
ib
->
idsum
)
...
...
@@ -31,6 +32,15 @@ struct invbloom *invbloom_new_(const tal_t *ctx,
return
ib
;
}
void
invbloom_singleton_cb_
(
struct
invbloom
*
ib
,
void
(
*
cb
)(
struct
invbloom
*
,
size_t
bucket
,
void
*
),
void
*
data
)
{
ib
->
singleton
=
cb
;
ib
->
singleton_data
=
data
;
}
static
size_t
hash_bucket
(
const
struct
invbloom
*
ib
,
const
void
*
id
,
size_t
i
)
{
return
hash
((
const
char
*
)
id
,
ib
->
id_size
,
ib
->
salt
+
i
*
7
)
%
ib
->
n_elems
;
...
...
@@ -41,6 +51,17 @@ static u8 *idsum_ptr(const struct invbloom *ib, size_t bucket)
return
(
u8
*
)
ib
->
idsum
+
bucket
*
ib
->
id_size
;
}
static
void
check_for_singleton
(
struct
invbloom
*
ib
,
size_t
bucket
)
{
if
(
!
ib
->
singleton
)
return
;
if
(
ib
->
count
[
bucket
]
!=
1
&&
ib
->
count
[
bucket
]
!=
-
1
)
return
;
ib
->
singleton
(
ib
,
bucket
,
ib
->
singleton_data
);
}
static
void
add_to_bucket
(
struct
invbloom
*
ib
,
size_t
n
,
const
u8
*
id
)
{
size_t
i
;
...
...
@@ -50,6 +71,8 @@ static void add_to_bucket(struct invbloom *ib, size_t n, const u8 *id)
for
(
i
=
0
;
i
<
ib
->
id_size
;
i
++
)
idsum
[
i
]
^=
id
[
i
];
check_for_singleton
(
ib
,
n
);
}
static
void
remove_from_bucket
(
struct
invbloom
*
ib
,
size_t
n
,
const
u8
*
id
)
...
...
@@ -60,6 +83,8 @@ static void remove_from_bucket(struct invbloom *ib, size_t n, const u8 *id)
ib
->
count
[
n
]
--
;
for
(
i
=
0
;
i
<
ib
->
id_size
;
i
++
)
idsum
[
i
]
^=
id
[
i
];
check_for_singleton
(
ib
,
n
);
}
void
invbloom_insert
(
struct
invbloom
*
ib
,
const
void
*
id
)
...
...
@@ -150,11 +175,13 @@ void invbloom_subtract(struct invbloom *ib1, const struct invbloom *ib2)
assert
(
ib1
->
id_size
==
ib2
->
id_size
);
assert
(
ib1
->
salt
==
ib2
->
salt
);
for
(
i
=
0
;
i
<
ib1
->
n_elems
;
i
++
)
ib1
->
count
[
i
]
-=
ib2
->
count
[
i
];
for
(
i
=
0
;
i
<
ib1
->
n_elems
*
ib1
->
id_size
;
i
++
)
ib1
->
idsum
[
i
]
^=
ib2
->
idsum
[
i
];
for
(
i
=
0
;
i
<
ib1
->
n_elems
;
i
++
)
{
ib1
->
count
[
i
]
-=
ib2
->
count
[
i
];
check_for_singleton
(
ib1
,
i
);
}
}
bool
invbloom_empty
(
const
struct
invbloom
*
ib
)
...
...
ccan/invbloom/invbloom.h
View file @
d9297524
...
...
@@ -2,6 +2,7 @@
#ifndef CCAN_INVBLOOM_H
#define CCAN_INVBLOOM_H
#include <ccan/short_types/short_types.h>
#include <ccan/typesafe_cb/typesafe_cb.h>
#include <ccan/tal/tal.h>
struct
invbloom
{
...
...
@@ -10,6 +11,8 @@ struct invbloom {
u32
salt
;
s32
*
count
;
/* [n_elems] */
u8
*
idsum
;
/* [n_elems][id_size] */
void
(
*
singleton
)(
struct
invbloom
*
ib
,
size_t
elem
,
void
*
);
void
*
singleton_data
;
};
/**
...
...
@@ -27,6 +30,26 @@ struct invbloom *invbloom_new_(const tal_t *ctx,
size_t
id_size
,
size_t
n_elems
,
u32
salt
);
/**
* invbloom_singleton_cb - set callback for when a singleton is found.
* @ib: the invertable bloom lookup table.
* @cb: the function to call (or NULL for none)
* @data: the data to hand to the function.
*
* This may be called by any function which mutates the table,
* possibly multiple times for a single call. The particular
* @ib bucket will be consistent, but the rest of the table may
* not be.
*/
#define invbloom_singleton_cb(ib, cb, data) \
invbloom_singleton_cb_((ib), \
typesafe_cb_preargs(void, void *, (cb), (data), \
struct invbloom *, size_t), (data))
void
invbloom_singleton_cb_
(
struct
invbloom
*
ib
,
void
(
*
cb
)(
struct
invbloom
*
,
size_t
bucket
,
void
*
),
void
*
data
);
/**
* invbloom_insert - add a new element
...
...
ccan/invbloom/test/run-singletoncb.c
0 → 100644
View file @
d9297524
#include <ccan/invbloom/invbloom.h>
/* Include the C files directly. */
#include <ccan/invbloom/invbloom.c>
#include <ccan/tap/tap.h>
static
void
singleton_cb
(
struct
invbloom
*
ib
,
size_t
n
,
unsigned
*
count
)
{
ok1
(
ib
->
count
[
n
]
==
1
||
ib
->
count
[
n
]
==
-
1
);
(
*
count
)
++
;
}
int
main
(
void
)
{
struct
invbloom
*
ib
;
const
tal_t
*
ctx
=
tal
(
NULL
,
char
);
int
val
;
unsigned
singleton_count
;
/* This is how many tests you plan to run */
plan_tests
(
10
+
3
+
NUM_HASHES
*
2
);
/* Single entry ib table keeps it simple. */
ib
=
invbloom_new
(
ctx
,
int
,
1
,
100
);
invbloom_singleton_cb
(
ib
,
singleton_cb
,
&
singleton_count
);
val
=
0
;
singleton_count
=
0
;
invbloom_insert
(
ib
,
&
val
);
ok1
(
ib
->
count
[
0
]
==
NUM_HASHES
);
ok1
(
singleton_count
==
1
);
ok1
(
!
invbloom_empty
(
ib
));
/* First delete takes it via singleton. */
invbloom_delete
(
ib
,
&
val
);
ok1
(
singleton_count
==
2
);
ok1
(
invbloom_empty
(
ib
));
/* Second delete creates negative singleton. */
invbloom_delete
(
ib
,
&
val
);
ok1
(
singleton_count
==
3
);
/* Now a larger table: this seed set so entries don't clash */
ib
=
invbloom_new
(
ctx
,
int
,
1024
,
0
);
singleton_count
=
0
;
invbloom_singleton_cb
(
ib
,
singleton_cb
,
&
singleton_count
);
val
=
0
;
invbloom_insert
(
ib
,
&
val
);
ok1
(
singleton_count
==
NUM_HASHES
);
/* First delete does nothing. */
invbloom_delete
(
ib
,
&
val
);
ok1
(
singleton_count
==
NUM_HASHES
);
ok1
(
invbloom_empty
(
ib
));
/* Second delete creates negative singletons. */
invbloom_delete
(
ib
,
&
val
);
ok1
(
singleton_count
==
NUM_HASHES
*
2
);
tal_free
(
ctx
);
/* This exits depending on whether all tests passed */
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