JASSv2
compress_integer.h
Go to the documentation of this file.
1 /*
2  COMPRESS_INTEGER.H
3  ------------------
4  Copyright (c) 2016 Andrew Trotman
5  Released under the 2-clause BSD license (See:https://en.wikipedia.org/wiki/BSD_licenses)
6 */
13 #pragma once
14 
15 #include <stdint.h>
16 #include <stdlib.h>
17 
18 #include <vector>
19 
20 #include "asserts.h"
21 
22 namespace JASS
23  {
24  /*
25  CLASS COMPRESS_INTEGER
26  ----------------------
27  */
35  {
36  private:
37  static constexpr int MAX_D_GAP = 64;
38 
39  public:
40  typedef uint32_t integer;
41  #define JASS_COMPRESS_INTEGER_BITS_PER_INTEGER 32
42 
43  public:
44  /*
45  COMPRESS_INTEGER::COMPRESS_INTEGER()
46  ------------------------------------
47  */
52  {
53  /* Nothing */
54  }
55  /*
56  COMPRESS_INTEGER::COMPRESS_INTEGER()
57  ------------------------------------
58  */
63  {
64  /* Nothing */
65  }
66 
67  /*
68  COMPRESS_INTEGER::D1_ENCODE()
69  -----------------------------
70  */
78  static size_t d1_encode(integer *encoded, const integer *source, size_t source_integers)
79  {
80  integer prior = 0;
81  const integer *end = source + source_integers;
82 
83  for (const integer *current = source; current < end; current++)
84  {
85  /*
86  This is done in this order so that the encoded and source buffers can be the same array.
87  */
88  integer d1 = *current - prior;
89  prior = *current;
90  *encoded++ = d1;
91  }
92  return source_integers;
93  }
94 
95  /*
96  COMPRESS_INTEGER::D1_DECODE()
97  -----------------------------
98  */
106  static size_t d1_decode(integer *decoded, const integer *source, size_t source_integers)
107  {
108  integer sum = 0;
109  const integer *end = source + source_integers;
110 
111  for (const integer *current = source; current < end; current++)
112  {
113  sum += *current;
114  *decoded++ = sum;
115  }
116 
117  return source_integers;
118  }
119 
120  /*
121  COMPRESS_INTEGER::DN_ENCODE()
122  -----------------------------
123  */
132  static size_t dn_encode(integer *encoded, const integer *source, size_t source_integers, size_t n = 1)
133  {
134  JASS_assert(n < MAX_D_GAP); // Verify that n isn't too large.
135  integer prior[MAX_D_GAP]; // temporary buffer of unencoded values stored so that source cab equal encoded (the pointers, that is)
136 
137  /*
138  The first n are not encoded, so write then directly into the output buffer
139  */
140  std::copy(source, source + n, encoded);
141 
142  /*
143  In order to be able to use the input buffer as the output buffer we cycle through an internal buffer
144  */
145  std::copy(source, source + n, prior);
146 
147  /*
148  The remainder are differences. We'll use two pointers to keep track of the sum and one for where we write into.
149  */
150  integer *into = encoded + n;
151  const integer *current = source + n;
152  size_t where = 0;
153 
154  const integer *end = source + source_integers;
155  while (current < end)
156  {
157  integer difference = *current - prior[where];
158  prior[where] = *current;
159  *into = difference;
160  into++;
161  current++;
162  where = (where + 1) % n;
163  }
164 
165  return source_integers;
166  }
167 
168  /*
169  COMPRESS_INTEGER::DN_DECODE()
170  -----------------------------
171  */
180  static size_t dn_decode(integer *decoded, const integer *source, size_t source_integers, size_t n = 1)
181  {
182  /*
183  The first n are not encoded, so write then directly into the output buffer
184  */
185  std::copy(source, source + n, decoded);
186 
187  /*
188  The remainder are encoded so decode them
189  */
190  integer *into = decoded + n;
191  integer *previous = decoded;
192  const integer *current = source + n;
193 
194  const integer *end = decoded + source_integers;
195  while (into < end)
196  *into++ = *previous++ + *current++;
197 
198  return source_integers;
199  }
200 
201  /*
202  COMPRESS_INTEGER::ENCODE()
203  --------------------------
204  */
213  virtual size_t encode(void *encoded, size_t encoded_buffer_length, const integer *source, size_t source_integers) = 0;
214 
215  /*
216  COMPRESS_INTEGER::DECODE()
217  --------------------------
218  */
226  virtual void decode(integer *decoded, size_t integers_to_decode, const void *source, size_t source_length) = 0;
227 
228  /*
229  COMPRESS_INTEGER::UNITTEST_ONE()
230  --------------------------------
231  */
237  static void unittest_one(compress_integer &encoder, const std::vector<uint32_t> &sequence);
238 
239  /*
240  COMPRESS_INTEGER::UNITTEST()
241  ----------------------------
242  */
248  static void unittest(compress_integer &compressor, uint32_t staring_from = 0);
249  } ;
250  }
static size_t d1_encode(integer *encoded, const integer *source, size_t source_integers)
Convert an array of integers into an array of D1 (delta, d-gap) encoded integers. ...
Definition: compress_integer.h:78
static void unittest_one(compress_integer &encoder, const std::vector< uint32_t > &sequence)
Test one sequence to make sure it encodes and decodes to the same thing. Assert if not...
Definition: compress_integer.cpp:21
replacement for the C runtime library assert that also works in release.
virtual ~compress_integer()
Destructor.
Definition: compress_integer.h:62
virtual size_t encode(void *encoded, size_t encoded_buffer_length, const integer *source, size_t source_integers)=0
Encode a sequence of integers returning the number of bytes used for the encoding, or 0 if the encoded sequence doesn&#39;t fit in the buffer.
Compression codexes for integer sequences.
Definition: compress_integer.h:34
uint32_t integer
This class and descendants will work on integers of this size. Do not change without also changing JA...
Definition: compress_integer.h:40
#define JASS_assert(expression)
Drop in replacement for assert() that aborts in Release as well as Debug.
Definition: asserts.h:33
compress_integer()
Constructor.
Definition: compress_integer.h:51
static size_t dn_decode(integer *decoded, const integer *source, size_t source_integers, size_t n=1)
Convert a Dn encoded array of integers into an array of integers.
Definition: compress_integer.h:180
static size_t dn_encode(integer *encoded, const integer *source, size_t source_integers, size_t n=1)
Convert an array of integers into an array of Dn (delta, d-gap) encoded integers with a gap of n...
Definition: compress_integer.h:132
virtual void decode(integer *decoded, size_t integers_to_decode, const void *source, size_t source_length)=0
Decode a sequence of integers encoded with this codex.
static constexpr int MAX_D_GAP
this is the maximum D-ness that this code supports, it can be changes to anything that won&#39;t reuslt i...
Definition: compress_integer.h:37
Definition: compress_integer_elias_delta_simd.c:23
static void unittest(compress_integer &compressor, uint32_t staring_from=0)
Unit test this class, assert on failure.
Definition: compress_integer.cpp:42
static size_t d1_decode(integer *decoded, const integer *source, size_t source_integers)
Convert a D1 encoded array of integers into an array of integers.
Definition: compress_integer.h:106