Turi Create  4.0
integer_pack_impl.hpp
1 /* Copyright © 2017 Apple Inc. All rights reserved.
2  *
3  * Use of this source code is governed by a BSD-3-clause license that can
4  * be found in the LICENSE.txt file or at https://opensource.org/licenses/BSD-3-Clause
5  */
6 #ifndef TURI_SFRAME_INTEGER_PACK_IMPL_HPP
7 #define TURI_SFRAME_INTEGER_PACK_IMPL_HPP
8 
9 
10 #include <core/storage/serialization/serialization_includes.hpp>
11 namespace turi {
12 
13 /**
14  * \ingroup sframe_physical
15  * \addtogroup Compression Integer Compression Routines
16  * \{
17  */
18 
19 /**
20  * \internal
21  * Integer Packing Routines
22  */
23 namespace integer_pack {
24 
25 /**
26  * Packs a sequence of 1 bit values
27  */
28 static inline size_t pack_1(const uint64_t* src, size_t srclen, uint8_t* out) {
29  uint8_t* initial_out = out;
30  size_t n = (srclen + 7) / 8;
31  uint8_t c = 0;
32  switch(srclen % 8) {
33  case 0: do { c |= ((*src++));
34  case 7: c |= ((*src++)) << 1;
35  case 6: c |= ((*src++)) << 2;
36  case 5: c |= ((*src++)) << 3;
37  case 4: c |= ((*src++)) << 4;
38  case 3: c |= ((*src++)) << 5;
39  case 2: c |= ((*src++)) << 6;
40  case 1: c |= ((*src++)) << 7;
41  (*out++) = c;
42  c = 0;
43  } while(--n > 0);
44  }
45  return out - initial_out;
46 }
47 
48 /**
49  * Packs a sequence of 2 bit values
50  */
51 static inline size_t pack_2(const uint64_t* src, size_t srclen, uint8_t* out) {
52  uint8_t* initial_out = out;
53  size_t n = (srclen + 7) / 8;
54  uint8_t c = 0;
55  switch(srclen % 8) {
56  case 0: do { c |= ((*src++));
57  case 7: c |= ((*src++)) << 2;
58  case 6: c |= ((*src++)) << 4;
59  case 5: c |= ((*src++)) << 6;
60  (*out++) = c;
61  c = 0;
62  case 4: c |= ((*src++));
63  case 3: c |= ((*src++)) << 2;
64  case 2: c |= ((*src++)) << 4;
65  case 1: c |= ((*src++)) << 6;
66  (*out++) = c;
67  c = 0;
68  } while(--n > 0);
69  }
70  return out - initial_out;
71 }
72 
73 
74 /**
75  * Packs a sequence of 4 bit values
76  */
77 static inline size_t pack_4(const uint64_t* src, size_t srclen, uint8_t* out) {
78  uint8_t* initial_out = out;
79  size_t n = (srclen + 7) / 8;
80  uint8_t c = 0;
81  switch(srclen % 8) {
82  case 0: do { c |= ((*src++));
83  case 7: c |= ((*src++)) << 4;
84  (*out++) = c;
85  c = 0;
86  case 6: c |= ((*src++));
87  case 5: c |= ((*src++)) << 4;
88  (*out++) = c;
89  c = 0;
90  case 4: c |= ((*src++));
91  case 3: c |= ((*src++)) << 4;
92  (*out++) = c;
93  c = 0;
94  case 2: c |= ((*src++));
95  case 1: c |= ((*src++)) << 4;
96  (*out++) = c;
97  c = 0;
98  } while(--n > 0);
99  }
100  return out - initial_out;
101 }
102 
103 /**
104  * Packs a sequence of 8 bit values
105  */
106 static inline size_t pack_8(const uint64_t* src, size_t srclen, uint8_t* out) {
107  uint8_t* initial_out = out;
108  const uint64_t* src_end = src + srclen;
109  while(src != src_end) {
110  (*out++) = (*src++);
111  }
112  return out - initial_out;
113 }
114 
115 /**
116  * Packs a sequence of 16 bit values
117  */
118 static inline size_t pack_16(const uint64_t* src, size_t srclen, uint16_t* out) {
119  uint16_t* initial_out = out;
120  const uint64_t* src_end = src + srclen;
121  while(src != src_end) {
122  (*out++) = (*src++);
123  }
124  return 2*(out - initial_out);
125 }
126 
127 /**
128  * Packs a sequence of 32 bit values
129  */
130 static inline size_t pack_32(const uint64_t* src, size_t srclen, uint32_t* out) {
131  uint32_t* initial_out = out;
132  const uint64_t* src_end = src + srclen;
133  while(src != src_end) {
134  (*out++) = static_cast<uint32_t>(*src++);
135  }
136  return 4*(out - initial_out);
137 }
138 
139 
140 /**
141  * Unpacks a sequence of 1 bit values
142  */
143 static inline void unpack_1(const uint8_t* src, size_t nout_values, uint64_t* out) {
144  size_t n = (nout_values + 7) / 8;
145  uint8_t c = (*src++);
146  // the first byte, if incomplete, annoying is going to live
147  // in the most significant bits of c. Thus if nout_value % 8 != 0,
148  // I need to do a bit of shifting.
149  c >>= ((8 - (nout_values % 8)) % 8);
150  switch(nout_values % 8) {
151  do { c = (*src++);
152  case 0: (*out++) = c & 1; c >>= 1;
153  case 7: (*out++) = c & 1; c >>= 1;
154  case 6: (*out++) = c & 1; c >>= 1;
155  case 5: (*out++) = c & 1; c >>= 1;
156  case 4: (*out++) = c & 1; c >>= 1;
157  case 3: (*out++) = c & 1; c >>= 1;
158  case 2: (*out++) = c & 1; c >>= 1;
159  case 1: (*out++) = c & 1; c >>= 1;
160  } while(--n > 0);
161  }
162 }
163 
164 
165 /**
166  * Unpacks a sequence of 2 bit values
167  */
168 static inline void unpack_2(const uint8_t* src, size_t nout_values, uint64_t* out) {
169  size_t n = (nout_values + 7) / 8;
170  uint8_t c = (*src++);
171  c >>= ((8 - 2 * (nout_values % 4)) % 8);
172  switch(nout_values % 8) {
173  do { c = (*src++);
174  case 0: (*out++) = c & 3; c >>= 2;
175  case 7: (*out++) = c & 3; c >>= 2;
176  case 6: (*out++) = c & 3; c >>= 2;
177  case 5: (*out++) = c & 3; c >>= 2;
178  c = (*src++);
179  case 4: (*out++) = c & 3; c >>= 2;
180  case 3: (*out++) = c & 3; c >>= 2;
181  case 2: (*out++) = c & 3; c >>= 2;
182  case 1: (*out++) = c & 3; c >>= 2;
183  } while(--n > 0);
184  }
185 }
186 
187 
188 /**
189  * Unpacks a sequence of 4 bit values
190  */
191 static inline void unpack_4(const uint8_t* src, size_t nout_values, uint64_t* out) {
192  size_t n = (nout_values + 7) / 8;
193  uint8_t c = (*src++);
194  c >>= ((8 - 4 * (nout_values % 2)) % 8);
195  switch(nout_values % 8) {
196  do { c = (*src++);
197  case 0: (*out++) = c & 15; c >>= 4;
198  case 7: (*out++) = c & 15; c >>= 4;
199  c = (*src++);
200  case 6: (*out++) = c & 15; c >>= 4;
201  case 5: (*out++) = c & 15; c >>= 4;
202  c = (*src++);
203  case 4: (*out++) = c & 15; c >>= 4;
204  case 3: (*out++) = c & 15; c >>= 4;
205  c = (*src++);
206  case 2: (*out++) = c & 15; c >>= 4;
207  case 1: (*out++) = c & 15; c >>= 4;
208  } while(--n > 0);
209  }
210 }
211 
212 
213 /**
214  * Unpacks a sequence of 8 bit values
215  */
216 static inline void unpack_8(const uint8_t* src, size_t nout_values, uint64_t* out) {
217  const uint8_t* src_end = src + nout_values;
218  while(src != src_end) {
219  (*out++) = (*src++);
220  }
221 }
222 
223 
224 /**
225  * Unpacks a sequence of 16 bit values
226  */
227 static inline void unpack_16(const uint16_t* src, size_t nout_values, uint64_t* out) {
228  const uint16_t* src_end = src + nout_values;
229  while(src != src_end) {
230  (*out++) = (*src++);
231  }
232 }
233 
234 /**
235  * Unpacks a sequence of 32 bit values
236  */
237 static inline void unpack_32(const uint32_t* src, size_t nout_values, uint64_t* out) {
238  const uint32_t* src_end = src + nout_values;
239  while(src != src_end) {
240  (*out++) = (*src++);
241  }
242 }
243 
244 
245 } // namespace integer_pack
246 
247 /// \}
248 } // namespace turi
249 
250 #endif
static void unpack_16(const uint16_t *src, size_t nout_values, uint64_t *out)
static size_t pack_32(const uint64_t *src, size_t srclen, uint32_t *out)
static size_t pack_4(const uint64_t *src, size_t srclen, uint8_t *out)
static size_t pack_8(const uint64_t *src, size_t srclen, uint8_t *out)
static size_t pack_16(const uint64_t *src, size_t srclen, uint16_t *out)
static size_t pack_2(const uint64_t *src, size_t srclen, uint8_t *out)
static void unpack_1(const uint8_t *src, size_t nout_values, uint64_t *out)
static void unpack_2(const uint8_t *src, size_t nout_values, uint64_t *out)
static void unpack_32(const uint32_t *src, size_t nout_values, uint64_t *out)
static void unpack_8(const uint8_t *src, size_t nout_values, uint64_t *out)
static size_t pack_1(const uint64_t *src, size_t srclen, uint8_t *out)
static void unpack_4(const uint8_t *src, size_t nout_values, uint64_t *out)