@@ -34,87 +34,62 @@ this program; if not, write to the Free Software Foundation, Inc.,
34
34
#ifndef INNOBASE_FTS0VLC_IC
35
35
#define INNOBASE_FTS0VLC_IC
36
36
37
+ #include <cstddef>
38
+ #include <cstdint>
37
39
#include "fts0types.h"
38
40
39
- /** Return length of val if it were encoded using our VLC scheme.
40
- FIXME: We will need to be able encode 8 bytes value
41
- @return length of value encoded, in bytes */
42
- inline ulint fts_get_encoded_len(ulint val) /* in: value to encode */
43
- {
44
- if (val <= 127) {
45
- return (1);
46
- } else if (val <= 16383) {
47
- return (2);
48
- } else if (val <= 2097151) {
49
- return (3);
50
- } else if (val <= 268435455) {
51
- return (4);
52
- } else {
53
- /* Possibly we should care that on 64-bit machines ulint can
54
- contain values that we can't encode in 5 bytes, but
55
- fts_encode_int doesn't handle them either so it doesn't much
56
- matter. */
57
-
58
- return (5);
41
+ inline unsigned int fts_get_encoded_len(uint64_t val) {
42
+ unsigned int length = 1;
43
+ for (;;) {
44
+ val >>= 7;
45
+ if (val != 0) {
46
+ ++length;
47
+ } else {
48
+ break;
49
+ }
59
50
}
51
+ return length;
60
52
}
61
53
62
- /** Encode an integer using our VLC scheme and return the length in bytes.
63
- @return length of value encoded, in bytes */
64
- inline ulint fts_encode_int(ulint val, /* in: value to encode */
65
- byte *buf) /* in: buffer, must have enough space */
66
- {
67
- ulint len;
68
-
69
- if (val <= 127) {
70
- *buf = (byte)val;
71
-
72
- len = 1;
73
- } else if (val <= 16383) {
74
- *buf++ = (byte)(val >> 7);
75
- *buf = (byte)(val & 0x7F);
76
-
77
- len = 2;
78
- } else if (val <= 2097151) {
79
- *buf++ = (byte)(val >> 14);
80
- *buf++ = (byte)((val >> 7) & 0x7F);
81
- *buf = (byte)(val & 0x7F);
82
-
83
- len = 3;
84
- } else if (val <= 268435455) {
85
- *buf++ = (byte)(val >> 21);
86
- *buf++ = (byte)((val >> 14) & 0x7F);
87
- *buf++ = (byte)((val >> 7) & 0x7F);
88
- *buf = (byte)(val & 0x7F);
89
-
90
- len = 4;
91
- } else {
92
- /* Best to keep the limitations of the 32/64 bit versions
93
- identical, at least for the time being. */
94
- ut_ad(val <= 4294967295u);
95
-
96
- *buf++ = (byte)(val >> 28);
97
- *buf++ = (byte)((val >> 21) & 0x7F);
98
- *buf++ = (byte)((val >> 14) & 0x7F);
99
- *buf++ = (byte)((val >> 7) & 0x7F);
100
- *buf = (byte)(val & 0x7F);
101
-
102
- len = 5;
54
+ inline unsigned int fts_encode_int(uint64_t val, byte *buf) {
55
+ constexpr unsigned int max_length = 10;
56
+
57
+ /* skip leading zeros */
58
+ unsigned int count = max_length - 1;
59
+ while (count > 0) {
60
+ /* We split the value into 7 bit batches); so val >= 2^63 need 10 bytes,
61
+ 2^63 > val >= 2^56 needs 9 bytes, 2^56 > val >= 2^49 needs 8 bytes etc.
62
+ */
63
+ if (val >= uint64_t(1) << (count * 7)) {
64
+ break;
65
+ }
66
+ --count;
67
+ }
68
+
69
+ unsigned int length = count + 1;
70
+
71
+ byte *bufptr{buf};
72
+
73
+ for (;;) {
74
+ *bufptr = (byte)((val >> (7 * count)) & 0x7f);
75
+ if (count == 0) {
76
+ /* High-bit on means "last byte in the encoded integer". */
77
+ *bufptr |= 0x80;
78
+ break;
79
+ } else {
80
+ --count;
81
+ ++bufptr;
82
+ }
103
83
}
104
84
105
- /* High-bit on means "last byte in the encoded integer". */
106
- * buf |= 0x80 ;
85
+ ut_ad(length <= max_length);
86
+ ut_a(bufptr - buf == std::ptrdiff_t(length) - 1) ;
107
87
108
- return (len) ;
88
+ return length ;
109
89
}
110
90
111
- /** Decode and return the integer that was encoded using our VLC scheme.
112
- @return value decoded */
113
- inline ulint fts_decode_vlc(
114
- byte **ptr) /* in: ptr to decode from, this ptr is
115
- incremented by the number of bytes decoded */
116
- {
117
- ulint val = 0;
91
+ inline uint64_t fts_decode_vlc(byte **ptr) {
92
+ uint64_t val = 0;
118
93
119
94
for (;;) {
120
95
byte b = **ptr;
@@ -130,7 +105,7 @@ inline ulint fts_decode_vlc(
130
105
}
131
106
}
132
107
133
- return ( val) ;
108
+ return val;
134
109
}
135
110
136
111
#endif
0 commit comments