Skip to content

Commit 3b87ee8

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

File tree

2 files changed

+81
-39
lines changed

2 files changed

+81
-39
lines changed

src/ulog_sqlite.c

Lines changed: 80 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,14 @@ uint32_t read_uint32(byte *ptr) {
9191
// Also returns the length of the varint
9292
uint16_t read_vint16(byte *ptr, int8_t *vlen) {
9393
uint16_t ret = 0;
94-
*vlen = 3; // read max 3 bytes
94+
int8_t len = 3; // read max 3 bytes
9595
do {
9696
ret <<= 7;
9797
ret += *ptr & 0x7F;
98-
(*vlen)--;
99-
} while ((*ptr++ & 0x80) == 0x80 && *vlen);
100-
*vlen = 3 - *vlen;
98+
len--;
99+
} while ((*ptr++ & 0x80) == 0x80 && len);
100+
if (vlen)
101+
*vlen = 3 - len;
101102
return ret;
102103
}
103104

@@ -106,16 +107,33 @@ uint16_t read_vint16(byte *ptr, int8_t *vlen) {
106107
// Also returns the length of the varint
107108
uint32_t read_vint32(byte *ptr, int8_t *vlen) {
108109
uint32_t ret = 0;
109-
*vlen = 5; // read max 5 bytes
110+
int8_t len = 5; // read max 5 bytes
110111
do {
111112
ret <<= 7;
112113
ret += *ptr & 0x7F;
113-
(*vlen)--;
114-
} while ((*ptr++ & 0x80) == 0x80 && *vlen);
115-
*vlen = 5 - *vlen;
114+
len--;
115+
} while ((*ptr++ & 0x80) == 0x80 && len);
116+
if (vlen)
117+
*vlen = 5 - len;
116118
return ret;
117119
}
118120

121+
// Converts float to Sqlite's Big-endian double
122+
uint64_t float_to_double(const void *val) {
123+
uint32_t bytes = *((uint32_t *) val);
124+
uint8_t exp8 = (bytes >> 23) & 0xFF;
125+
uint16_t exp11 = exp8;
126+
if (exp11 != 0) {
127+
if (exp11 < 127)
128+
exp11 = 1023 - (127 - exp11);
129+
else
130+
exp11 = 1023 + (exp11 - 127);
131+
}
132+
return ((uint64_t)(bytes >> 31) << 63)
133+
| ((uint64_t)exp11 << 52)
134+
| ((uint64_t)(bytes & 0x7FFFFF) << (52-23) );
135+
}
136+
119137
// Returns actual page size from given exponent
120138
int32_t get_pagesize(byte page_size_exp) {
121139
return (int32_t) 1 << page_size_exp;
@@ -315,9 +333,9 @@ int check_sums(byte *buf, int32_t page_size, int check_or_calc) {
315333
while (i < page_size)
316334
chk_sum += buf[i++];
317335
if (check_or_calc)
318-
buf[69] = page_chk;
336+
buf[69] = chk_sum;
319337
else {
320-
if (buf[69] != page_chk)
338+
if (buf[69] != chk_sum)
321339
return ULS_RES_ERR;
322340
}
323341
}
@@ -916,22 +934,60 @@ int uls_read_last_row(struct uls_read_context *rctx) {
916934
// Reads the buffer part by part to avoid reading entire buffer into memory
917935
// to support low memory systems (2kb ram)
918936
// The underlying callback function hopefully optimizes repeated IO
919-
int read_last_rowid(struct uls_read_context *rctx, uint32_t pos, int32_t page_size, uint32_t *out_rowid, uint16_t *out_rec_pos) {
937+
int read_last_val(struct uls_read_context *rctx, uint32_t pos,
938+
int32_t page_size, int col_idx, byte **pval_at,
939+
uint32_t *out_col_type, uint16_t *out_rec_pos, byte is_rowid) {
920940
byte src_buf[12];
921941
int res = read_bytes_rctx(rctx, src_buf, pos * page_size, 12);
922942
if (res)
923943
return res;
924944
if (*src_buf != 13)
925945
return ULS_RES_MALFORMED;
926946
*out_rec_pos = read_uint16(src_buf + 3) - 1;
927-
res = read_bytes_rctx(rctx, src_buf, pos * page_size + read_uint16(src_buf + 5), 12);
947+
uint16_t last_pos = read_uint16(src_buf + 5);
948+
res = read_bytes_rctx(rctx, src_buf, pos * page_size + last_pos, 12);
928949
if (res)
929950
return res;
930951
int8_t vint_len;
931-
*out_rowid = read_vint32(src_buf + 3, &vint_len);
952+
uint32_t row_id = read_vint32(src_buf + 3, &vint_len);
953+
if (is_rowid)
954+
*out_col_type = row_id;
955+
else {
956+
uint16_t rec_len = read_vint16(src_buf, NULL) + vint_len + LEN_OF_REC_LEN;
957+
byte rec_buf[rec_len];
958+
res = read_bytes_rctx(rctx, rec_buf, pos * page_size + last_pos, rec_len);
959+
if (res)
960+
return res;
961+
uint16_t hdr_len;
962+
byte *hdr_ptr = locate_column(rec_buf, col_idx, pval_at, &rec_len, &hdr_len);
963+
if (!hdr_ptr)
964+
return ULS_RES_NOT_FOUND;
965+
*out_col_type = read_vint32(hdr_ptr, &vint_len);
966+
}
932967
return ULS_RES_OK;
933968
}
934969

970+
byte *read_val_at(struct uls_read_context *rctx, uint32_t pos, int col_idx,
971+
uint32_t *out_col_type, byte is_rowid) {
972+
int8_t vint_len;
973+
uint16_t rec_pos = read_uint16(rctx->buf + 8 + pos * 2);
974+
uint32_t row_id = read_vint32(rctx->buf + rec_pos + LEN_OF_REC_LEN, &vint_len);
975+
if (is_rowid)
976+
*out_col_type = row_id;
977+
else {
978+
uint16_t hdr_len;
979+
uint16_t rec_len;
980+
byte *data_ptr;
981+
byte *hdr_ptr;
982+
hdr_ptr = locate_column(rctx->buf, col_idx, &data_ptr, &rec_len, &hdr_len);
983+
if (!hdr_ptr)
984+
return NULL;
985+
*out_col_type = read_vint32(hdr_ptr, &vint_len);
986+
return data_ptr;
987+
}
988+
return NULL;
989+
}
990+
935991
// Returns the Row ID of the record at given position
936992
uint32_t read_rowid_at(struct uls_read_context *rctx, uint32_t rec_pos) {
937993
int8_t vint_len;
@@ -999,22 +1055,6 @@ int uls_srch_row_by_id(struct uls_read_context *rctx, uint32_t rowid) {
9991055
return ULS_RES_NOT_FOUND;
10001056
}
10011057

1002-
// Converts float to Sqlite's Big-endian double
1003-
uint64_t float_to_double(const void *val) {
1004-
uint32_t bytes = *((uint32_t *) val);
1005-
uint8_t exp8 = (bytes >> 23) & 0xFF;
1006-
uint16_t exp11 = exp8;
1007-
if (exp11 != 0) {
1008-
if (exp11 < 127)
1009-
exp11 = 1023 - (127 - exp11);
1010-
else
1011-
exp11 = 1023 + (exp11 - 127);
1012-
}
1013-
return ((uint64_t)(bytes >> 31) << 63)
1014-
| ((uint64_t)exp11 << 52)
1015-
| ((uint64_t)(bytes & 0x7FFFFF) << (52-23) );
1016-
}
1017-
10181058
// compares two binary strings and returns k, -k or 0
10191059
// 0 meaning the two are identical. If not, k is length that matches
10201060
int compare_bin(const byte *v1, byte len1, const byte *v2, byte len2) {
@@ -1036,7 +1076,7 @@ int compare_bin(const byte *v1, byte len1, const byte *v2, byte len2) {
10361076
}
10371077

10381078
// Compare values for binary search and return 1, -1 or 0
1039-
int compare_vals(byte *val_at, uint32_t u32_at, int val_type, void *val, uint16_t len, byte is_rowid) {
1079+
int compare_values(byte *val_at, uint32_t u32_at, int val_type, void *val, uint16_t len, byte is_rowid) {
10401080
if (is_rowid)
10411081
return (u32_at > *((uint32_t *) val) ? 1 : u32_at < *((uint32_t *) val) ? -1 : 0);
10421082
switch (val_type) {
@@ -1075,15 +1115,17 @@ int compare_vals(byte *val_at, uint32_t u32_at, int val_type, void *val, uint16_
10751115
bytes64 = *((uint64_t *) val);
10761116
return (bytes64_at > bytes64 ? 1 : bytes64_at < bytes64 ? -1 : 0);
10771117
case ULS_TYPE_BLOB:
1078-
case ULS_TYPE_TEXT:
1118+
case ULS_TYPE_TEXT: {
10791119
uint32_t len_at = uls_derive_data_len(u32_at);
10801120
int res = compare_bin(val_at, len_at, val, len);
10811121
return (res > 0 ? 1 : (res < 0 ? -1 : 0));
1122+
}
10821123
}
1124+
return 1;
10831125
}
10841126

10851127
// See .h file for API description
1086-
int uls_bin_srch_row_by_val(struct uls_read_context *rctx,
1128+
int uls_bin_srch_row_by_val(struct uls_read_context *rctx, int col_idx,
10871129
int val_type, void *val, uint16_t len, byte is_rowid) {
10881130
int32_t page_size = get_pagesize(rctx->page_size_exp);
10891131
if (rctx->last_leaf_page == 0)
@@ -1097,10 +1139,10 @@ int uls_bin_srch_row_by_val(struct uls_read_context *rctx,
10971139
uint16_t rec_pos;
10981140
byte *val_at;
10991141
uint32_t u32_at;
1100-
res = read_last_val(rctx, middle, page_size, &u32_at, is_rowid, &rec_pos);
1142+
res = read_last_val(rctx, middle, page_size, col_idx, &val_at, &u32_at, &rec_pos, is_rowid);
11011143
if (res)
11021144
return res;
1103-
int cmp = compare_vals(val_at, u32_at, val_type, val, len, is_rowid);
1145+
int cmp = compare_values(val_at, u32_at, val_type, val, len, is_rowid);
11041146
if (cmp == ULS_RES_TYPE_MISMATCH)
11051147
return cmp;
11061148
if (cmp < 0)
@@ -1125,10 +1167,10 @@ int uls_bin_srch_row_by_val(struct uls_read_context *rctx,
11251167
while (first < size) {
11261168
middle = (first + size) >> 1;
11271169
uint32_t u32_at;
1128-
byte *val_at = read_val_at(rctx, middle, &u32_at);
1129-
if (res)
1130-
return res;
1131-
int cmp = compare_vals(val_at, u32_at, val_type, val, len, is_rowid);
1170+
byte *val_at = read_val_at(rctx, middle, col_idx, &u32_at, is_rowid);
1171+
if (!val_at)
1172+
return ULS_RES_NOT_FOUND;
1173+
int cmp = compare_values(val_at, u32_at, val_type, val, len, is_rowid);
11321174
if (cmp == ULS_RES_TYPE_MISMATCH)
11331175
return cmp;
11341176
if (cmp < 0)

src/ulog_sqlite.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ int uls_srch_row_by_id(struct uls_read_context *rctx, uint32_t rowid);
145145
// Performs binary search on the inserted records
146146
// using the given Value and positions at the record found
147147
// Does not change position if record not found
148-
int uls_bin_srch_row_by_val(struct uls_read_context *rctx,
148+
int uls_bin_srch_row_by_val(struct uls_read_context *rctx, int col_idx,
149149
int val_type, void *val, uint16_t len, byte is_rowid);
150150

151151
#ifdef __cplusplus

0 commit comments

Comments
 (0)