-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.c
107 lines (89 loc) · 2.5 KB
/
index.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include "config.h"
#include "system.h"
#include "memory.h"
#include "head.h"
#include "value.h"
#include "tuple.h"
#include "index.h"
static void merge(Tuple *keys[],
Tuple *tmp[],
int pos[],
int len,
int left,
int mid,
int right)
{
int llen = mid - left;
int rlen = right - mid;
Tuple **l = tmp;
Tuple **r = tmp + llen + 1;
for (int i = 0; i < llen; ++i)
l[i] = keys[left + i];
for (int i = 0; i < rlen; ++i)
r[i] = keys[mid + i];
l[llen] = NULL;
r[rlen] = NULL;
int i = 0, j = 0, k = left;
while (l[i] != NULL && r[j] != NULL)
if (tuple_cmp(l[i], r[j], pos, pos, len) <= 0)
keys[k++] = l[i++];
else
keys[k++] = r[j++];
while (l[i] != NULL)
keys[k++] = l[i++];
while (r[j] != NULL)
keys[k++] = r[j++];
}
static void sort(Tuple *keys[],
Tuple *tmp[],
int pos[],
int len,
int left,
int right)
{
int elems = right - left;
if (elems < 2)
return;
int mid = left + elems / 2;
sort(keys, tmp, pos, len, left, mid);
sort(keys, tmp, pos, len, mid, right);
merge(keys, tmp, pos, len, left, mid, right);
}
static int find(TBuf *idx, Tuple *t, int ipos[], int tpos[], int len)
{
int low = 0, high = idx->len - 1;
while (low <= high) {
int mid = (low + high) / 2;
if (tuple_cmp(t, idx->buf[mid], tpos, ipos, len) < 0)
high = mid - 1;
else if (tuple_cmp(t, idx->buf[mid], tpos, ipos, len) > 0)
low = mid + 1;
else
return mid;
}
return -1;
}
extern void index_sort(TBuf *buf, int pos[], int len)
{
Tuple **tmp = mem_alloc((buf->len + 2) * sizeof(Tuple*));
sort(buf->buf, tmp, pos, len, 0, buf->len);
mem_free(tmp);
}
extern int index_has(TBuf *idx, Tuple *t, int ipos[], int tpos[], int len)
{
return find(idx, t, ipos, tpos, len) >= 0;
}
extern TBuf *index_match(TBuf *idx, Tuple *t, int ipos[], int tpos[], int len)
{
int match = find(idx, t, ipos, tpos, len);
if (match < 0)
return NULL;
TBuf *res = tbuf_new();
int i = match - 1;
while (i >= 0 && tuple_cmp(idx->buf[i], t, ipos, tpos, len) == 0)
tbuf_add(res, idx->buf[i--]);
i = match;
while (i < idx->len && tuple_cmp(idx->buf[i], t, ipos, tpos, len) == 0)
tbuf_add(res, idx->buf[i++]);
return res;
}