2016-04-01 10:46:28 +03:00
|
|
|
// Copyright 2016-present Facebook. All Rights Reserved.
|
|
|
|
//
|
|
|
|
// bsearch.c: binary search implementation with context-aware callback.
|
2016-04-01 21:19:53 +03:00
|
|
|
//
|
|
|
|
// no-check-code
|
2016-04-01 10:46:28 +03:00
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
|
|
|
|
#include "bsearch.h"
|
|
|
|
|
2016-04-09 08:33:07 +03:00
|
|
|
size_t bsearch_between(const void *needle,
|
|
|
|
const void *base, const size_t nel, const size_t width,
|
|
|
|
int (*compare)(const void *needle,
|
|
|
|
const void *fromarray,
|
|
|
|
const void *context),
|
|
|
|
const void *context) {
|
2016-04-01 10:46:28 +03:00
|
|
|
ptrdiff_t start = 0;
|
|
|
|
ptrdiff_t end = nel;
|
|
|
|
|
|
|
|
while (start < end) {
|
|
|
|
ptrdiff_t midpoint = start + ((end - start) / 2);
|
|
|
|
|
|
|
|
if (midpoint == nel) {
|
|
|
|
return nel;
|
|
|
|
}
|
|
|
|
|
2016-04-09 08:33:07 +03:00
|
|
|
const void *ptr = base + (midpoint * width);
|
2016-04-01 10:46:28 +03:00
|
|
|
|
|
|
|
int cmp = compare(needle, ptr, context);
|
|
|
|
|
|
|
|
if (cmp == 0) {
|
|
|
|
return midpoint;
|
|
|
|
} else if (cmp < 0) {
|
|
|
|
end = midpoint;
|
|
|
|
} else {
|
|
|
|
start = midpoint + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return start;
|
|
|
|
}
|