Skip to content

Commit 2d0b55d

Browse files
committed
bin srch val intermediate
1 parent 38e21c3 commit 2d0b55d

File tree

2 files changed

+84
-17
lines changed

2 files changed

+84
-17
lines changed

src/ulog_sqlite.c

Lines changed: 80 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -622,18 +622,7 @@ int uls_set_col_val(struct uls_write_context *wctx,
622622
} else
623623
if (type == ULS_TYPE_REAL && len == 4) {
624624
// Assumes float is represented in IEEE-754 format
625-
uint32_t bytes = *((uint32_t *) val);
626-
uint8_t exp8 = (bytes >> 23) & 0xFF;
627-
uint16_t exp11 = exp8;
628-
if (exp11 != 0) {
629-
if (exp11 < 127)
630-
exp11 = 1023 - (127 - exp11);
631-
else
632-
exp11 = 1023 + (exp11 - 127);
633-
}
634-
uint64_t bytes64 = ((uint64_t)(bytes >> 31) << 63)
635-
| ((uint64_t)exp11 << 52)
636-
| ((uint64_t)(bytes & 0x7FFFFF) << (52-23) );
625+
uint64_t bytes64 = float_to_double(val);
637626
write_uint64(data_ptr, bytes64);
638627
} else
639628
if (type == ULS_TYPE_REAL && len == 8) {
@@ -1010,20 +999,92 @@ int uls_srch_row_by_id(struct uls_read_context *rctx, uint32_t rowid) {
1010999
return ULS_RES_NOT_FOUND;
10111000
}
10121001

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+
1018+
// compares two binary strings and returns k, -k or 0
1019+
// 0 meaning the two are identical. If not, k is length that matches
1020+
int compare_bin(const byte *v1, byte len1, const byte *v2, byte len2) {
1021+
int k = 0;
1022+
int lim = (len2 < len1 ? len2 : len1);
1023+
while (k < lim) {
1024+
byte c1 = v1[k];
1025+
byte c2 = v2[k];
1026+
k++;
1027+
if (c1 < c2)
1028+
return -k;
1029+
else if (c1 > c2)
1030+
return k;
1031+
}
1032+
if (len1 == len2)
1033+
return 0;
1034+
k++;
1035+
return (len1 < len2 ? -k : k);
1036+
}
1037+
1038+
// Compare values for binary search and return 1, -1 or 0
10131039
int compare_vals(byte *val_at, uint32_t u32_at, int val_type, void *val, uint16_t len, byte is_rowid) {
10141040
if (is_rowid)
10151041
return (u32_at > *((uint32_t *) val) ? 1 : u32_at < *((uint32_t *) val) ? -1 : 0);
10161042
switch (val_type) {
10171043
case ULS_TYPE_INT:
1018-
1044+
if (u32_at != len)
1045+
return ULS_RES_TYPE_MISMATCH;
1046+
if (len == 4) {
1047+
int32_t iat = *((int32_t *) val_at);
1048+
int32_t ival = *((int32_t *) val);
1049+
return (iat > ival ? 1 : iat < ival ? -1 : 0);
1050+
}
1051+
if (len == 2) {
1052+
int16_t iat = *((int16_t *) val_at);
1053+
int16_t ival = *((int16_t *) val);
1054+
return (iat > ival ? 1 : iat < ival ? -1 : 0);
1055+
}
1056+
if (len == 6) {
1057+
int64_t iat = *((int64_t *) val_at);
1058+
int64_t ival = *((int64_t *) val);
1059+
return (iat > ival ? 1 : iat < ival ? -1 : 0);
1060+
}
1061+
if (len == 1) {
1062+
int8_t iat = *((int8_t *) val_at);
1063+
int8_t ival = *((int8_t *) val);
1064+
return (iat > ival ? 1 : iat < ival ? -1 : 0);
1065+
}
1066+
return ULS_RES_TYPE_MISMATCH;
10191067
case ULS_TYPE_REAL:
1020-
case ULS_TYPE_TEXT:
1068+
if ((len != 4 && len != 8) || u32_at != 8)
1069+
return ULS_RES_TYPE_MISMATCH;
1070+
uint64_t bytes64, bytes64_at;
1071+
bytes64 = *((uint64_t *) val_at);
1072+
if (len == 4)
1073+
bytes64 = float_to_double(val);
1074+
else
1075+
bytes64 = *((uint64_t *) val);
1076+
return (bytes64_at > bytes64 ? 1 : bytes64_at < bytes64 ? -1 : 0);
10211077
case ULS_TYPE_BLOB:
1078+
case ULS_TYPE_TEXT:
1079+
uint32_t len_at = uls_derive_data_len(u32_at);
1080+
int res = compare_bin(val_at, len_at, val, len);
1081+
return (res > 0 ? 1 : (res < 0 ? -1 : 0));
10221082
}
10231083
}
10241084

10251085
// See .h file for API description
1026-
int uls_bin_srch_row_by_val(struct uls_read_context *rctx, int val_type, void *val, uint16_t len, byte is_rowid) {
1086+
int uls_bin_srch_row_by_val(struct uls_read_context *rctx,
1087+
int val_type, void *val, uint16_t len, byte is_rowid) {
10271088
int32_t page_size = get_pagesize(rctx->page_size_exp);
10281089
if (rctx->last_leaf_page == 0)
10291090
return ULS_RES_NOT_FINALIZED;
@@ -1040,6 +1101,8 @@ int uls_bin_srch_row_by_val(struct uls_read_context *rctx, int val_type, void *v
10401101
if (res)
10411102
return res;
10421103
int cmp = compare_vals(val_at, u32_at, val_type, val, len, is_rowid);
1104+
if (cmp == ULS_RES_TYPE_MISMATCH)
1105+
return cmp;
10431106
if (cmp < 0)
10441107
first = middle + 1;
10451108
else if (cmp > 0)
@@ -1066,6 +1129,8 @@ int uls_bin_srch_row_by_val(struct uls_read_context *rctx, int val_type, void *v
10661129
if (res)
10671130
return res;
10681131
int cmp = compare_vals(val_at, u32_at, val_type, val, len, is_rowid);
1132+
if (cmp == ULS_RES_TYPE_MISMATCH)
1133+
return cmp;
10691134
if (cmp < 0)
10701135
first = middle + 1;
10711136
else if (cmp > 0)

src/ulog_sqlite.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ enum {ULS_RES_OK = 0, ULS_RES_ERR = -1, ULS_RES_INV_PAGE_SZ = -2,
1919
ULS_RES_TOO_LONG = -3, ULS_RES_WRITE_ERR = -4, ULS_RES_FLUSH_ERR = -5};
2020

2121
enum {ULS_RES_SEEK_ERR = -6, ULS_RES_READ_ERR = -7, ULS_RES_INVALID_SIG = -8,
22-
ULS_RES_MALFORMED = -9, ULS_RES_NOT_FOUND = -10, ULS_RES_NOT_FINALIZED = -11};
22+
ULS_RES_MALFORMED = -9, ULS_RES_NOT_FOUND = -10, ULS_RES_NOT_FINALIZED = -11,
23+
ULS_RES_TYPE_MISMATCH = -12};
2324

2425
// Write context to be passed to create / append
2526
// a database. The running values need not be supplied
@@ -144,7 +145,8 @@ int uls_srch_row_by_id(struct uls_read_context *rctx, uint32_t rowid);
144145
// Performs binary search on the inserted records
145146
// using the given Value and positions at the record found
146147
// Does not change position if record not found
147-
int uls_bin_srch_row_by_val(struct uls_read_context *rctx, byte *val, uint16_t len);
148+
int uls_bin_srch_row_by_val(struct uls_read_context *rctx,
149+
int val_type, void *val, uint16_t len, byte is_rowid);
148150

149151
#ifdef __cplusplus
150152
}

0 commit comments

Comments
 (0)