Skip to content

Commit dd841fe

Browse files
committed
bin srch val intermediate
1 parent 3b87ee8 commit dd841fe

File tree

2 files changed

+183
-79
lines changed

2 files changed

+183
-79
lines changed

src/test_ulog_sqlite.c

Lines changed: 127 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,9 @@ void print_usage() {
154154
printf(" Appends to a Sqlite database created using -c above\n");
155155
printf(" with records in CSV format (page_size and col_count have to match)\n\n");
156156
printf("test_ulog_sqlite -r <db_name.db> <rowid>\n");
157-
printf(" Searches db_name.db for given row_id using\n");
157+
printf(" Searches <db_name.db> for given row_id and prints result\n\n");
158+
printf("test_ulog_sqlite -b <db_name.db> <col_idx> <value>\n");
159+
printf(" Searches <db_name.db> and column for given value using\n");
158160
printf(" binary search and prints result\n\n");
159161
printf("test_ulog_sqlite -n\n");
160162
printf(" Runs pre-defined tests and creates databases (verified manually)\n\n");
@@ -332,10 +334,126 @@ double read_double(const byte *ptr) {
332334
return ret;
333335
}
334336

337+
void display_row(struct uls_read_context ctx) {
338+
int col_count = uls_cur_row_col_count(&ctx);
339+
for (int i = 0; i < col_count; i++) {
340+
if (i)
341+
putchar('|');
342+
uint32_t col_type;
343+
const byte *col_val = (const byte *) uls_read_col_val(&ctx, i, &col_type);
344+
switch (col_type) {
345+
case 0:
346+
printf("null");
347+
break;
348+
case 1:
349+
printf("%d", *((int8_t *)col_val));
350+
break;
351+
case 2:
352+
if (1) {
353+
int16_t ival = read_int16(col_val);
354+
printf("%d", ival);
355+
}
356+
break;
357+
case 4: {
358+
int32_t ival = read_int32(col_val);
359+
printf("%d", ival);
360+
break;
361+
}
362+
case 6: {
363+
int64_t ival = read_int64(col_val);
364+
printf("%lld", ival);
365+
break;
366+
}
367+
case 7: {
368+
double dval = read_double(col_val);
369+
printf("%lf", dval);
370+
break;
371+
}
372+
default: {
373+
uint32_t col_len = uls_derive_data_len(col_type);
374+
for (int j = 0; j < col_len; j++) {
375+
if (col_type % 2)
376+
putchar(col_val[j]);
377+
else
378+
printf("x%2x ", col_val[j]);
379+
}
380+
}
381+
}
382+
}
383+
}
384+
385+
extern void write_uint8(byte *ptr, uint8_t input);
386+
extern void write_uint16(byte *ptr, uint16_t input);
387+
extern void write_uint32(byte *ptr, uint32_t input);
388+
extern void write_uint64(byte *ptr, uint64_t input);
389+
390+
int resolve_value(char *value, byte *out_val) {
391+
byte isInt = 1;
392+
byte isReal = 1;
393+
char *chr = value;
394+
while (*chr != '\0') {
395+
if ((*chr < '0' || *chr > '9') && *chr != '-' && *chr != '.') {
396+
isInt = 0;
397+
isReal = 0;
398+
} else {
399+
if (*chr == '.')
400+
isInt = 0;
401+
}
402+
chr++;
403+
}
404+
if (isInt) {
405+
int64_t ival = (int64_t) atoll(value);
406+
memcpy(out_val, &ival, sizeof(ival));
407+
return ULS_TYPE_INT;
408+
} else
409+
if (isReal) {
410+
double dval = atof(value);
411+
memcpy(out_val, &dval, sizeof(dval));
412+
return ULS_TYPE_REAL;
413+
}
414+
memcpy(out_val, value, strlen(value));
415+
return ULS_TYPE_TEXT;
416+
}
417+
418+
int bin_srch_db(int argc, char *argv[]) {
419+
int len = strlen(argv[4]);
420+
if (len > 71) {
421+
printf("Value too long\n");
422+
return -1;
423+
}
424+
byte buf[72];
425+
struct uls_read_context ctx;
426+
ctx.buf = buf;
427+
ctx.read_fn = read_fn_rctx;
428+
fd = open(argv[2], O_RDWR | O_SYNC, S_IRUSR | S_IWUSR);
429+
if (fd == -1) {
430+
perror("Error");
431+
return -2;
432+
}
433+
if (uls_read_init(&ctx)) {
434+
printf("Error during init\n");
435+
return -3;
436+
}
437+
byte page_buf[1 << (ctx.page_size_exp == 1 ? 16 : ctx.page_size_exp)];
438+
ctx.buf = page_buf;
439+
int col_idx = atol(argv[3]);
440+
int val_type = resolve_value(argv[4], buf);
441+
if (val_type == ULS_TYPE_INT || val_type == ULS_TYPE_REAL)
442+
len = 8;
443+
if (uls_bin_srch_row_by_val(&ctx, col_idx, val_type,
444+
buf, len, col_idx == -1 ? 1 : 0)) {
445+
printf("Not Found\n");
446+
} else {
447+
display_row(ctx);
448+
}
449+
putchar('\n');
450+
return 0;
451+
}
452+
335453
int read_db(int argc, char *argv[]) {
336-
byte initial_buf[72];
454+
byte buf[72];
337455
struct uls_read_context ctx;
338-
ctx.buf = initial_buf;
456+
ctx.buf = buf;
339457
ctx.read_fn = read_fn_rctx;
340458
fd = open(argv[2], O_RDWR | O_SYNC, S_IRUSR | S_IWUSR);
341459
if (fd == -1) {
@@ -346,57 +464,13 @@ int read_db(int argc, char *argv[]) {
346464
printf("Error during init\n");
347465
return -3;
348466
}
349-
byte actual_buf[1 << (ctx.page_size_exp == 1 ? 16 : ctx.page_size_exp)];
350-
ctx.buf = actual_buf;
467+
byte page_buf[1 << (ctx.page_size_exp == 1 ? 16 : ctx.page_size_exp)];
468+
ctx.buf = page_buf;
351469
uint32_t rowid = atol(argv[3]);
352470
if (uls_srch_row_by_id(&ctx, rowid)) {
353471
printf("Not Found\n");
354472
} else {
355-
int col_count = uls_cur_row_col_count(&ctx);
356-
for (int i = 0; i < col_count; i++) {
357-
if (i)
358-
putchar('|');
359-
uint32_t col_type;
360-
const byte *col_val = (const byte *) uls_read_col_val(&ctx, i, &col_type);
361-
switch (col_type) {
362-
case 0:
363-
printf("null");
364-
break;
365-
case 1:
366-
printf("%d", *((int8_t *)col_val));
367-
break;
368-
case 2:
369-
if (1) {
370-
int16_t ival = read_int16(col_val);
371-
printf("%d", ival);
372-
}
373-
break;
374-
case 4: {
375-
int32_t ival = read_int32(col_val);
376-
printf("%d", ival);
377-
break;
378-
}
379-
case 6: {
380-
int64_t ival = read_int64(col_val);
381-
printf("%lld", ival);
382-
break;
383-
}
384-
case 7: {
385-
double dval = read_double(col_val);
386-
printf("%lf", dval);
387-
break;
388-
}
389-
default: {
390-
uint32_t col_len = uls_derive_data_len(col_type);
391-
for (int j = 0; j < col_len; j++) {
392-
if (col_type % 2)
393-
putchar(col_val[j]);
394-
else
395-
printf("x%2x ", col_val[j]);
396-
}
397-
}
398-
}
399-
}
473+
display_row(ctx);
400474
}
401475
putchar('\n');
402476
return 0;
@@ -413,6 +487,9 @@ int main(int argc, char *argv[]) {
413487
if (argc == 4 && strcmp(argv[1], "-r") == 0) {
414488
read_db(argc, argv);
415489
} else
490+
if (argc == 5 && strcmp(argv[1], "-b") == 0) {
491+
bin_srch_db(argc, argv);
492+
} else
416493
if (argc == 2 && strcmp(argv[1], "-n") == 0) {
417494
test_basic("hello.db");
418495
test_multilevel("ml.db");

src/ulog_sqlite.c

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ int write_vint32(byte *ptr, uint32_t vint) {
6969
return len;
7070
}
7171

72+
// Reads and returns big-endian uint8_t
73+
// at a given memory location
74+
uint8_t read_uint8(byte *ptr) {
75+
return *ptr;
76+
}
77+
7278
// Reads and returns big-endian uint16_t
7379
// at a given memory location
7480
uint16_t read_uint16(byte *ptr) {
@@ -86,6 +92,16 @@ uint32_t read_uint32(byte *ptr) {
8692
return ret;
8793
}
8894

95+
// Reads and returns big-endian uint32_t
96+
// at a given memory location
97+
uint64_t read_uint64(byte *ptr) {
98+
uint32_t ret = 0;
99+
int len = 8;
100+
while (len--)
101+
ret += (*ptr++ << (8 * len));
102+
return ret;
103+
}
104+
89105
// Reads and returns variable integer
90106
// from given location as uint16_t
91107
// Also returns the length of the varint
@@ -972,14 +988,15 @@ byte *read_val_at(struct uls_read_context *rctx, uint32_t pos, int col_idx,
972988
int8_t vint_len;
973989
uint16_t rec_pos = read_uint16(rctx->buf + 8 + pos * 2);
974990
uint32_t row_id = read_vint32(rctx->buf + rec_pos + LEN_OF_REC_LEN, &vint_len);
975-
if (is_rowid)
991+
if (is_rowid) {
976992
*out_col_type = row_id;
977-
else {
993+
return (byte *) out_col_type;
994+
} else {
978995
uint16_t hdr_len;
979996
uint16_t rec_len;
980997
byte *data_ptr;
981998
byte *hdr_ptr;
982-
hdr_ptr = locate_column(rctx->buf, col_idx, &data_ptr, &rec_len, &hdr_len);
999+
hdr_ptr = locate_column(rctx->buf + rec_pos, col_idx, &data_ptr, &rec_len, &hdr_len);
9831000
if (!hdr_ptr)
9841001
return NULL;
9851002
*out_col_type = read_vint32(hdr_ptr, &vint_len);
@@ -1080,35 +1097,42 @@ int compare_values(byte *val_at, uint32_t u32_at, int val_type, void *val, uint1
10801097
if (is_rowid)
10811098
return (u32_at > *((uint32_t *) val) ? 1 : u32_at < *((uint32_t *) val) ? -1 : 0);
10821099
switch (val_type) {
1083-
case ULS_TYPE_INT:
1084-
if (u32_at != len)
1085-
return ULS_RES_TYPE_MISMATCH;
1086-
if (len == 4) {
1087-
int32_t iat = *((int32_t *) val_at);
1088-
int32_t ival = *((int32_t *) val);
1089-
return (iat > ival ? 1 : iat < ival ? -1 : 0);
1090-
}
1091-
if (len == 2) {
1092-
int16_t iat = *((int16_t *) val_at);
1093-
int16_t ival = *((int16_t *) val);
1094-
return (iat > ival ? 1 : iat < ival ? -1 : 0);
1095-
}
1096-
if (len == 6) {
1097-
int64_t iat = *((int64_t *) val_at);
1098-
int64_t ival = *((int64_t *) val);
1099-
return (iat > ival ? 1 : iat < ival ? -1 : 0);
1100+
case ULS_TYPE_INT: {
1101+
int64_t ival_at;
1102+
switch (u32_at) {
1103+
case 4:
1104+
ival_at = (int64_t) read_uint32(val_at);
1105+
break;
1106+
case 2:
1107+
ival_at = (int64_t) read_uint16(val_at);
1108+
break;
1109+
case 6:
1110+
ival_at = read_uint64(val_at);
1111+
break;
1112+
case 1:
1113+
ival_at = (int64_t) read_uint8(val_at);
11001114
}
1101-
if (len == 1) {
1102-
int8_t iat = *((int8_t *) val_at);
1103-
int8_t ival = *((int8_t *) val);
1104-
return (iat > ival ? 1 : iat < ival ? -1 : 0);
1115+
int64_t ival;
1116+
switch (len) {
1117+
case 4:
1118+
ival = *((int32_t *) val);
1119+
break;
1120+
case 2:
1121+
ival = *((int16_t *) val);
1122+
break;
1123+
case 8:
1124+
ival = *((int64_t *) val);
1125+
break;
1126+
case 1:
1127+
ival = *((int8_t *) val);
11051128
}
1106-
return ULS_RES_TYPE_MISMATCH;
1129+
return ival_at > ival ? 1 : (ival_at < ival ? -1 : 0);
1130+
}
11071131
case ULS_TYPE_REAL:
1108-
if ((len != 4 && len != 8) || u32_at != 8)
1132+
if ((len != 4 && len != 8) || u32_at != 7)
11091133
return ULS_RES_TYPE_MISMATCH;
11101134
uint64_t bytes64, bytes64_at;
1111-
bytes64 = *((uint64_t *) val_at);
1135+
bytes64_at = read_uint64(val_at);
11121136
if (len == 4)
11131137
bytes64 = float_to_double(val);
11141138
else
@@ -1163,7 +1187,8 @@ int uls_bin_srch_row_by_val(struct uls_read_context *rctx, int col_idx,
11631187
if (res)
11641188
return res;
11651189
first = 0;
1166-
size = read_uint16(rctx->buf + 3);
1190+
int16_t rec_count = read_uint16(rctx->buf + 3);
1191+
size = rec_count;
11671192
while (first < size) {
11681193
middle = (first + size) >> 1;
11691194
uint32_t u32_at;
@@ -1183,5 +1208,7 @@ int uls_bin_srch_row_by_val(struct uls_read_context *rctx, int col_idx,
11831208
return ULS_RES_OK;
11841209
}
11851210
}
1186-
return ULS_RES_NOT_FOUND;
1211+
rctx->cur_page = (found_at_page == rctx->last_leaf_page + 1 ? found_at_page - 1 : found_at_page);
1212+
rctx->cur_rec_pos = (rec_count == size ? size - 1 : size);
1213+
return ULS_RES_OK;
11871214
}

0 commit comments

Comments
 (0)