summaryrefslogtreecommitdiff
path: root/src/runtime/c/gu/seq.c
diff options
context:
space:
mode:
authorkr.angelov <kr.angelov@gmail.com>2013-10-28 12:35:37 +0000
committerkr.angelov <kr.angelov@gmail.com>2013-10-28 12:35:37 +0000
commit151f86c1e9e518c34a76ff5fdab9afd34000fe0d (patch)
tree5d16b65e0abaae250f83e48b7bb849fce79180ba /src/runtime/c/gu/seq.c
parentcd5a0de253152b9aa484b6c684d9943094ac87dc (diff)
fix the handling of 'pre' in the C runtime
Diffstat (limited to 'src/runtime/c/gu/seq.c')
-rw-r--r--src/runtime/c/gu/seq.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/src/runtime/c/gu/seq.c b/src/runtime/c/gu/seq.c
index b798d2923..8ec6480cc 100644
--- a/src/runtime/c/gu/seq.c
+++ b/src/runtime/c/gu/seq.c
@@ -255,7 +255,7 @@ gu_buf_sort(GuBuf *buf, GuOrder *order)
}
void*
-gu_seq_binsearch_(GuSeq *seq, GuOrder *order, size_t elem_size, size_t field_offset, void *key)
+gu_seq_binsearch_(GuSeq *seq, GuOrder *order, size_t elem_size, void *key)
{
size_t i = 0;
size_t j = seq->len-1;
@@ -263,8 +263,8 @@ gu_seq_binsearch_(GuSeq *seq, GuOrder *order, size_t elem_size, size_t field_off
while (i <= j) {
size_t k = (i+j) / 2;
uint8_t* elem_p = &seq->data[elem_size * k];
- int cmp = order->compare(order, key, elem_p + field_offset);
-
+ int cmp = order->compare(order, key, elem_p);
+
if (cmp < 0) {
j = k-1;
} else if (cmp > 0) {
@@ -273,10 +273,36 @@ gu_seq_binsearch_(GuSeq *seq, GuOrder *order, size_t elem_size, size_t field_off
return elem_p;
}
}
-
+
return NULL;
}
+bool
+gu_seq_binsearch_index_(GuSeq *seq, GuOrder *order, size_t elem_size,
+ void *key, size_t *pindex)
+{
+ size_t i = 0;
+ size_t j = seq->len-1;
+
+ while (i <= j) {
+ size_t k = (i+j) / 2;
+ uint8_t* elem_p = &seq->data[elem_size * k];
+ int cmp = order->compare(order, key, elem_p);
+
+ if (cmp < 0) {
+ j = k-1;
+ } else if (cmp > 0) {
+ i = k+1;
+ } else {
+ *pindex = k;
+ return true;
+ }
+ }
+
+ *pindex = j;
+ return false;
+}
+
static void
gu_heap_siftdown(GuBuf *buf, GuOrder *order,
const void *value, int startpos, int pos)