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
8c2ee69f
Commit
8c2ee69f
authored
Mar 17, 2015
by
Rusty Russell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
invbloom: singleton callback for when destroying a singleton, too.
Signed-off-by:
Rusty Russell
<
rusty@rustcorp.com.au
>
parent
eaab3d3e
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
44 additions
and
25 deletions
+44
-25
ccan/invbloom/invbloom.c
ccan/invbloom/invbloom.c
+13
-6
ccan/invbloom/invbloom.h
ccan/invbloom/invbloom.h
+10
-4
ccan/invbloom/test/run-singletoncb.c
ccan/invbloom/test/run-singletoncb.c
+21
-15
No files found.
ccan/invbloom/invbloom.c
View file @
8c2ee69f
...
@@ -34,7 +34,7 @@ struct invbloom *invbloom_new_(const tal_t *ctx,
...
@@ -34,7 +34,7 @@ struct invbloom *invbloom_new_(const tal_t *ctx,
void
invbloom_singleton_cb_
(
struct
invbloom
*
ib
,
void
invbloom_singleton_cb_
(
struct
invbloom
*
ib
,
void
(
*
cb
)(
struct
invbloom
*
,
void
(
*
cb
)(
struct
invbloom
*
,
size_t
bucket
,
void
*
),
size_t
bucket
,
bool
,
void
*
),
void
*
data
)
void
*
data
)
{
{
ib
->
singleton
=
cb
;
ib
->
singleton
=
cb
;
...
@@ -51,7 +51,7 @@ static u8 *idsum_ptr(const struct invbloom *ib, size_t bucket)
...
@@ -51,7 +51,7 @@ static u8 *idsum_ptr(const struct invbloom *ib, size_t bucket)
return
(
u8
*
)
ib
->
idsum
+
bucket
*
ib
->
id_size
;
return
(
u8
*
)
ib
->
idsum
+
bucket
*
ib
->
id_size
;
}
}
static
void
check_for_singleton
(
struct
invbloom
*
ib
,
size_t
bucket
)
static
void
check_for_singleton
(
struct
invbloom
*
ib
,
size_t
bucket
,
bool
before
)
{
{
if
(
!
ib
->
singleton
)
if
(
!
ib
->
singleton
)
return
;
return
;
...
@@ -59,7 +59,7 @@ static void check_for_singleton(struct invbloom *ib, size_t bucket)
...
@@ -59,7 +59,7 @@ static void check_for_singleton(struct invbloom *ib, size_t bucket)
if
(
ib
->
count
[
bucket
]
!=
1
&&
ib
->
count
[
bucket
]
!=
-
1
)
if
(
ib
->
count
[
bucket
]
!=
1
&&
ib
->
count
[
bucket
]
!=
-
1
)
return
;
return
;
ib
->
singleton
(
ib
,
bucket
,
ib
->
singleton_data
);
ib
->
singleton
(
ib
,
bucket
,
before
,
ib
->
singleton_data
);
}
}
static
void
add_to_bucket
(
struct
invbloom
*
ib
,
size_t
n
,
const
u8
*
id
)
static
void
add_to_bucket
(
struct
invbloom
*
ib
,
size_t
n
,
const
u8
*
id
)
...
@@ -67,12 +67,14 @@ static void add_to_bucket(struct invbloom *ib, size_t n, const u8 *id)
...
@@ -67,12 +67,14 @@ static void add_to_bucket(struct invbloom *ib, size_t n, const u8 *id)
size_t
i
;
size_t
i
;
u8
*
idsum
=
idsum_ptr
(
ib
,
n
);
u8
*
idsum
=
idsum_ptr
(
ib
,
n
);
check_for_singleton
(
ib
,
n
,
true
);
ib
->
count
[
n
]
++
;
ib
->
count
[
n
]
++
;
for
(
i
=
0
;
i
<
ib
->
id_size
;
i
++
)
for
(
i
=
0
;
i
<
ib
->
id_size
;
i
++
)
idsum
[
i
]
^=
id
[
i
];
idsum
[
i
]
^=
id
[
i
];
check_for_singleton
(
ib
,
n
);
check_for_singleton
(
ib
,
n
,
false
);
}
}
static
void
remove_from_bucket
(
struct
invbloom
*
ib
,
size_t
n
,
const
u8
*
id
)
static
void
remove_from_bucket
(
struct
invbloom
*
ib
,
size_t
n
,
const
u8
*
id
)
...
@@ -80,11 +82,13 @@ static void remove_from_bucket(struct invbloom *ib, size_t n, const u8 *id)
...
@@ -80,11 +82,13 @@ static void remove_from_bucket(struct invbloom *ib, size_t n, const u8 *id)
size_t
i
;
size_t
i
;
u8
*
idsum
=
idsum_ptr
(
ib
,
n
);
u8
*
idsum
=
idsum_ptr
(
ib
,
n
);
check_for_singleton
(
ib
,
n
,
true
);
ib
->
count
[
n
]
--
;
ib
->
count
[
n
]
--
;
for
(
i
=
0
;
i
<
ib
->
id_size
;
i
++
)
for
(
i
=
0
;
i
<
ib
->
id_size
;
i
++
)
idsum
[
i
]
^=
id
[
i
];
idsum
[
i
]
^=
id
[
i
];
check_for_singleton
(
ib
,
n
);
check_for_singleton
(
ib
,
n
,
false
);
}
}
void
invbloom_insert
(
struct
invbloom
*
ib
,
const
void
*
id
)
void
invbloom_insert
(
struct
invbloom
*
ib
,
const
void
*
id
)
...
@@ -175,12 +179,15 @@ void invbloom_subtract(struct invbloom *ib1, const struct invbloom *ib2)
...
@@ -175,12 +179,15 @@ void invbloom_subtract(struct invbloom *ib1, const struct invbloom *ib2)
assert
(
ib1
->
id_size
==
ib2
->
id_size
);
assert
(
ib1
->
id_size
==
ib2
->
id_size
);
assert
(
ib1
->
salt
==
ib2
->
salt
);
assert
(
ib1
->
salt
==
ib2
->
salt
);
for
(
i
=
0
;
i
<
ib1
->
n_elems
;
i
++
)
check_for_singleton
(
ib1
,
i
,
true
);
for
(
i
=
0
;
i
<
ib1
->
n_elems
*
ib1
->
id_size
;
i
++
)
for
(
i
=
0
;
i
<
ib1
->
n_elems
*
ib1
->
id_size
;
i
++
)
ib1
->
idsum
[
i
]
^=
ib2
->
idsum
[
i
];
ib1
->
idsum
[
i
]
^=
ib2
->
idsum
[
i
];
for
(
i
=
0
;
i
<
ib1
->
n_elems
;
i
++
)
{
for
(
i
=
0
;
i
<
ib1
->
n_elems
;
i
++
)
{
ib1
->
count
[
i
]
-=
ib2
->
count
[
i
];
ib1
->
count
[
i
]
-=
ib2
->
count
[
i
];
check_for_singleton
(
ib1
,
i
);
check_for_singleton
(
ib1
,
i
,
false
);
}
}
}
}
...
...
ccan/invbloom/invbloom.h
View file @
8c2ee69f
...
@@ -11,7 +11,7 @@ struct invbloom {
...
@@ -11,7 +11,7 @@ struct invbloom {
u32
salt
;
u32
salt
;
s32
*
count
;
/* [n_elems] */
s32
*
count
;
/* [n_elems] */
u8
*
idsum
;
/* [n_elems][id_size] */
u8
*
idsum
;
/* [n_elems][id_size] */
void
(
*
singleton
)(
struct
invbloom
*
ib
,
size_t
elem
,
void
*
);
void
(
*
singleton
)(
struct
invbloom
*
ib
,
size_t
elem
,
bool
,
void
*
);
void
*
singleton_data
;
void
*
singleton_data
;
};
};
...
@@ -31,7 +31,7 @@ struct invbloom *invbloom_new_(const tal_t *ctx,
...
@@ -31,7 +31,7 @@ struct invbloom *invbloom_new_(const tal_t *ctx,
size_t
n_elems
,
u32
salt
);
size_t
n_elems
,
u32
salt
);
/**
/**
* invbloom_singleton_cb - set callback for
when a singleton is foun
d.
* invbloom_singleton_cb - set callback for
a singleton created/destroye
d.
* @ib: the invertable bloom lookup table.
* @ib: the invertable bloom lookup table.
* @cb: the function to call (or NULL for none)
* @cb: the function to call (or NULL for none)
* @data: the data to hand to the function.
* @data: the data to hand to the function.
...
@@ -40,15 +40,21 @@ struct invbloom *invbloom_new_(const tal_t *ctx,
...
@@ -40,15 +40,21 @@ struct invbloom *invbloom_new_(const tal_t *ctx,
* possibly multiple times for a single call. The particular
* possibly multiple times for a single call. The particular
* @ib bucket will be consistent, but the rest of the table may
* @ib bucket will be consistent, but the rest of the table may
* not be.
* not be.
*
* @cb is of form "void @cb(struct invbloom *ib, size_t bucket, bool
* before, data)". @before is true if the call is done before the
* singleton in @bucket is removed (ie. ib->counts[bucket] is -1 or 1,
* but is about to change). @before is false if the call is done
* after the operation, and the bucket is now a singleton.
*/
*/
#define invbloom_singleton_cb(ib, cb, data) \
#define invbloom_singleton_cb(ib, cb, data) \
invbloom_singleton_cb_((ib), \
invbloom_singleton_cb_((ib), \
typesafe_cb_preargs(void, void *, (cb), (data), \
typesafe_cb_preargs(void, void *, (cb), (data), \
struct invbloom *, size_t), (data))
struct invbloom *, size_t
, bool
), (data))
void
invbloom_singleton_cb_
(
struct
invbloom
*
ib
,
void
invbloom_singleton_cb_
(
struct
invbloom
*
ib
,
void
(
*
cb
)(
struct
invbloom
*
,
void
(
*
cb
)(
struct
invbloom
*
,
size_t
bucket
,
void
*
),
size_t
bucket
,
bool
before
,
void
*
),
void
*
data
);
void
*
data
);
/**
/**
...
...
ccan/invbloom/test/run-singletoncb.c
View file @
8c2ee69f
...
@@ -3,11 +3,11 @@
...
@@ -3,11 +3,11 @@
#include <ccan/invbloom/invbloom.c>
#include <ccan/invbloom/invbloom.c>
#include <ccan/tap/tap.h>
#include <ccan/tap/tap.h>
static
void
singleton_cb
(
struct
invbloom
*
ib
,
size_t
n
,
static
void
singleton_cb
(
struct
invbloom
*
ib
,
size_t
n
,
bool
before
,
unsigned
*
count
)
unsigned
*
count
)
{
{
ok1
(
ib
->
count
[
n
]
==
1
||
ib
->
count
[
n
]
==
-
1
);
ok1
(
ib
->
count
[
n
]
==
1
||
ib
->
count
[
n
]
==
-
1
);
(
*
count
)
++
;
count
[
before
]
++
;
}
}
int
main
(
void
)
int
main
(
void
)
...
@@ -15,48 +15,54 @@ int main(void)
...
@@ -15,48 +15,54 @@ int main(void)
struct
invbloom
*
ib
;
struct
invbloom
*
ib
;
const
tal_t
*
ctx
=
tal
(
NULL
,
char
);
const
tal_t
*
ctx
=
tal
(
NULL
,
char
);
int
val
;
int
val
;
unsigned
singleton_count
;
unsigned
singleton_count
[
2
]
;
/* This is how many tests you plan to run */
/* This is how many tests you plan to run */
plan_tests
(
1
0
+
3
+
NUM_HASHES
*
2
);
plan_tests
(
1
6
+
6
+
NUM_HASHES
*
3
);
/* Single entry ib table keeps it simple. */
/* Single entry ib table keeps it simple. */
ib
=
invbloom_new
(
ctx
,
int
,
1
,
100
);
ib
=
invbloom_new
(
ctx
,
int
,
1
,
100
);
invbloom_singleton_cb
(
ib
,
singleton_cb
,
&
singleton_count
);
invbloom_singleton_cb
(
ib
,
singleton_cb
,
singleton_count
);
val
=
0
;
val
=
0
;
singleton_count
=
0
;
singleton_count
[
false
]
=
singleton_count
[
true
]
=
0
;
invbloom_insert
(
ib
,
&
val
);
invbloom_insert
(
ib
,
&
val
);
ok1
(
ib
->
count
[
0
]
==
NUM_HASHES
);
ok1
(
ib
->
count
[
0
]
==
NUM_HASHES
);
ok1
(
singleton_count
==
1
);
ok1
(
singleton_count
[
true
]
==
1
);
ok1
(
singleton_count
[
false
]
==
1
);
ok1
(
!
invbloom_empty
(
ib
));
ok1
(
!
invbloom_empty
(
ib
));
/* First delete takes it via singleton. */
/* First delete takes it via singleton. */
invbloom_delete
(
ib
,
&
val
);
invbloom_delete
(
ib
,
&
val
);
ok1
(
singleton_count
==
2
);
ok1
(
singleton_count
[
true
]
==
2
);
ok1
(
singleton_count
[
false
]
==
2
);
ok1
(
invbloom_empty
(
ib
));
ok1
(
invbloom_empty
(
ib
));
/* Second delete creates negative singleton. */
/* Second delete creates negative singleton. */
invbloom_delete
(
ib
,
&
val
);
invbloom_delete
(
ib
,
&
val
);
ok1
(
singleton_count
==
3
);
ok1
(
singleton_count
[
true
]
==
3
);
ok1
(
singleton_count
[
false
]
==
3
);
/* Now a larger table: this seed set so entries don't clash */
/* Now a larger table: this seed set so entries don't clash */
ib
=
invbloom_new
(
ctx
,
int
,
1024
,
0
);
ib
=
invbloom_new
(
ctx
,
int
,
1024
,
0
);
singleton_count
=
0
;
singleton_count
[
false
]
=
singleton_count
[
true
]
=
0
;
invbloom_singleton_cb
(
ib
,
singleton_cb
,
&
singleton_count
);
invbloom_singleton_cb
(
ib
,
singleton_cb
,
singleton_count
);
val
=
0
;
val
=
0
;
invbloom_insert
(
ib
,
&
val
);
invbloom_insert
(
ib
,
&
val
);
ok1
(
singleton_count
==
NUM_HASHES
);
ok1
(
singleton_count
[
true
]
==
0
);
ok1
(
singleton_count
[
false
]
==
NUM_HASHES
);
/* First delete
does nothing
. */
/* First delete
removes singletons
. */
invbloom_delete
(
ib
,
&
val
);
invbloom_delete
(
ib
,
&
val
);
ok1
(
singleton_count
==
NUM_HASHES
);
ok1
(
singleton_count
[
true
]
==
NUM_HASHES
);
ok1
(
singleton_count
[
false
]
==
NUM_HASHES
);
ok1
(
invbloom_empty
(
ib
));
ok1
(
invbloom_empty
(
ib
));
/* Second delete creates negative singletons. */
/* Second delete creates negative singletons. */
invbloom_delete
(
ib
,
&
val
);
invbloom_delete
(
ib
,
&
val
);
ok1
(
singleton_count
==
NUM_HASHES
*
2
);
ok1
(
singleton_count
[
true
]
==
NUM_HASHES
);
ok1
(
singleton_count
[
false
]
==
NUM_HASHES
*
2
);
tal_free
(
ctx
);
tal_free
(
ctx
);
...
...
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