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
0d8d8a9c
Commit
0d8d8a9c
authored
Sep 30, 2009
by
Rusty Russell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sparse_bsearch: new module
parent
51711449
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
216 additions
and
0 deletions
+216
-0
ccan/sparse_bsearch/_info
ccan/sparse_bsearch/_info
+66
-0
ccan/sparse_bsearch/sparse_bsearch.c
ccan/sparse_bsearch/sparse_bsearch.c
+36
-0
ccan/sparse_bsearch/sparse_bsearch.h
ccan/sparse_bsearch/sparse_bsearch.h
+50
-0
ccan/sparse_bsearch/test/run.c
ccan/sparse_bsearch/test/run.c
+64
-0
No files found.
ccan/sparse_bsearch/_info
0 → 100644
View file @
0d8d8a9c
#include <string.h>
#include <stdio.h>
#include "config.h"
/**
* sparse_bsearch - search a sorted array with some invalid entries
*
* bsearch() is great for searching an array, but if you are deleting from
* the array, you then need to memmove() to keep it dense.
*
* Sometimes there is a useful invalid value which can be used to mark deleted
* entries, but such a "gappy" array breaks bsearch. This function allows
* "invalid" entries in your array, which are ignored for the search.
*
* Example:
* #include <ccan/sparse_bsearch/sparse_bsearch.h>
*
* static bool val_valid(unsigned int *val)
* {
* return *val != 0;
* }
* static int val_cmp(const unsigned int *a, const unsigned int *b)
* {
* return (int)((*a) - (*b));
* }
* static unsigned int values[] = { 1, 7, 11, 1235, 99999 };
*
* // Return true if this value is in set, and remove it.
* bool remove_from_values(unsigned int val)
* {
* unsigned int *p;
* // We use 5 here, but ccan/array_size.h is better!
* p = sparse_bsearch(&val, values, 5, val_cmp, val_valid);
* if (!p)
* return false;
* *p = 0;
* return true;
* }
*
* int main(int argc, char *argv[])
* {
* int i, val;
* for (i = 1; i < argc; i++) {
* val = atoi(argv[i]);
* if (remove_from_values(val))
* printf("%i removed.\n", val);
* else
* printf("%i wasn't there.\n", val);
* }
* return 0;
* }
*/
int main(int argc, char *argv[])
{
/* Expect exactly one argument */
if (argc != 2)
return 1;
if (strcmp(argv[1], "depends") == 0) {
printf("ccan/typesafe_cb\n"
"ccan/check_type\n");
return 0;
}
return 1;
}
ccan/sparse_bsearch/sparse_bsearch.c
0 → 100644
View file @
0d8d8a9c
#include "sparse_bsearch.h"
void
*
_sparse_bsearch
(
const
void
*
key
,
const
void
*
base
,
size_t
nmemb
,
size_t
size
,
int
(
*
cmpfn
)(
const
void
*
,
const
void
*
),
bool
(
*
validfn
)(
const
void
*
))
{
ssize_t
start
=
0
,
end
=
nmemb
-
1
;
const
char
*
p
=
base
;
while
(
start
<=
end
)
{
ssize_t
next
=
(
start
+
end
)
/
2
;
int
result
;
while
(
!
validfn
(
p
+
next
*
size
))
{
/* Try the next one along. */
next
++
;
if
(
next
>
end
)
{
/* Hmm, none of these were valid. */
next
=
(
start
+
end
)
/
2
;
goto
trim
;
}
}
result
=
cmpfn
(
key
,
p
+
next
*
size
);
if
(
result
==
0
)
return
(
void
*
)(
p
+
next
*
size
);
else
if
(
result
>
0
)
start
=
next
+
1
;
else
{
trim:
end
=
next
-
1
;
}
}
return
NULL
;
}
ccan/sparse_bsearch/sparse_bsearch.h
0 → 100644
View file @
0d8d8a9c
#ifndef SPARSE_BSEARCH_H
#define SPARSE_BSEARCH_H
#include <stdbool.h>
#include <stdlib.h>
#include <ccan/typesafe_cb/typesafe_cb.h>
#include <ccan/check_type/check_type.h>
/**
* sparse_bsearch - binary search of a sorted array with gaps.
* @key: the key to search for
* @base: the head of the array
* @nmemb: the number of elements in the array
* @cmpfn: the compare function (qsort/bsearch style)
* @validfn: whether this element is valid.
*
* Binary search of a sorted array, which may have some invalid entries.
*
* Example:
* static bool val_valid(unsigned int *val)
* {
* return *val != 0;
* }
* static int val_cmp(const unsigned int *a, const unsigned int *b)
* {
* return (int)((*a) - (*b));
* }
* static unsigned int values[] = { 1, 7, 11, 1235, 99999 };
*
* // Return true if this value is in set, and remove it.
* bool remove_from_values(unsigned int val)
* {
* unsigned int *p;
* p = sparse_bsearch(&val, values, 5, val_cmp, val_valid);
* if (!p)
* return false;
* *p = 0;
* return true;
* }
*/
#define sparse_bsearch(key, base, nmemb, cmpfn, validfn) \
_sparse_bsearch((key)+check_types_match((key), &(base)[0]), \
(base), (nmemb), sizeof((base)[0]), \
typesafe_cb_cmp(int, (cmpfn), (base)), \
typesafe_cb_const(bool, (validfn), (base)))
void
*
_sparse_bsearch
(
const
void
*
key
,
const
void
*
base
,
size_t
nmemb
,
size_t
size
,
int
(
*
cmpfn
)(
const
void
*
,
const
void
*
),
bool
(
*
validfn
)(
const
void
*
));
#endif
/* SPARSE_BSEARCH_H */
ccan/sparse_bsearch/test/run.c
0 → 100644
View file @
0d8d8a9c
/* Include the main header first, to test it works */
#include <ccan/sparse_bsearch/sparse_bsearch.h>
/* Include the C files directly. */
#include <ccan/sparse_bsearch/sparse_bsearch.c>
#include <ccan/tap/tap.h>
static
int
cmp
(
const
unsigned
int
*
a
,
const
unsigned
int
*
b
)
{
return
(
*
a
)
-
(
*
b
);
}
static
bool
valid
(
const
unsigned
int
*
a
)
{
return
*
a
!=
0
;
}
int
main
(
void
)
{
unsigned
int
i
,
j
,
master
[
4
]
=
{
1
,
2
,
3
,
4
},
arr
[
4
];
plan_tests
((
1
<<
4
)
*
4
+
(
1
<<
3
)
*
3
);
/* We test all possibilities of an even and an odd array len. */
for
(
i
=
0
;
i
<
(
1
<<
4
);
i
++
)
{
/* Setup partial arr[] */
for
(
j
=
0
;
j
<
4
;
j
++
)
{
if
(
i
&
(
1
<<
j
))
arr
[
j
]
=
master
[
j
];
else
arr
[
j
]
=
0
;
}
for
(
j
=
1
;
j
<=
4
;
j
++
)
{
unsigned
int
*
ptr
;
ptr
=
sparse_bsearch
(
&
j
,
arr
,
4
,
cmp
,
valid
);
if
(
i
&
(
1
<<
(
j
-
1
)))
ok1
(
ptr
&&
*
ptr
==
j
);
else
ok1
(
!
ptr
);
}
}
for
(
i
=
0
;
i
<
(
1
<<
3
);
i
++
)
{
/* Setup partial arr[] */
for
(
j
=
0
;
j
<
3
;
j
++
)
{
if
(
i
&
(
1
<<
j
))
arr
[
j
]
=
master
[
j
];
else
arr
[
j
]
=
0
;
}
for
(
j
=
1
;
j
<=
3
;
j
++
)
{
unsigned
int
*
ptr
;
ptr
=
sparse_bsearch
(
&
j
,
arr
,
3
,
cmp
,
valid
);
if
(
i
&
(
1
<<
(
j
-
1
)))
ok1
(
ptr
&&
*
ptr
==
j
);
else
ok1
(
!
ptr
);
}
}
/* 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