Xpace
compress.h
Go to the documentation of this file.
1 
2 /************************************************************
3  **
4  ** @file data/compress/compress.h
5  **
6  ** Copyright (C) 2012 Xpace, LLC. All rights reserved
7  **
8  ** www.xpace.net
9  **
10  **************************************************************/
11 
12 #ifndef XPACE_COMPRESS_H
13 #define XPACE_COMPRESS_H
14 
15 #include "data/compress/list_int.h"
16 #include "base/decimalfloat.h"
17 
18 namespace Xpace
19 {
20  template <typename N, typename B = N>
22  {
23  public:
24  typedef N type;
28 
30  (N n = 0)
31  {
32  num = n;
33  }
34 
36  (MemBitStream* b,
37  BytePool*) :
38  num(getVar(b))
39  {
40  }
41 
42  static N min
43  ()
44  {
45  return std::numeric_limits<N>::min();
46  }
47  static N max
48  ()
49  {
50  return std::numeric_limits<N>::max();
51  }
52 
53  operator N
54  ()
55  const
56  {
57  return num;
58  }
59 
61  ()
62  const
63  {
64  return static_cast<CHANGE_SIGN(N)>(num);
65  }
66 
67  bool operator==
68  (const CompressibleInt<N, B>& rhs)
69  {
70  return num == rhs.num;
71  }
72  bool operator !=
73  (const CompressibleInt<N, B>& rhs)
74  {
75  return num != rhs.num;
76  }
77  bool operator>
78  (const CompressibleInt<N, B>& rhs)
79  {
80  return num > rhs.num;
81  }
82  bool operator<
83  (const CompressibleInt<N, B>& rhs)
84  {
85  return num < rhs.num;
86  }
87 
88  diffType diff
89  (const CompressibleInt<N, B>& rhs,
90  BytePool* = 0)
91  const
92  {
93  return num - rhs.num;
94  }
95  N operator-
96  (const CompressibleInt<N, B>& rhs)
97  {
98  return diff(rhs);
99  }
100  N sum
101  (diffType rhs,
102  BytePool* = 0)
103  {
104  return num + rhs;
105  }
106  CompressibleInt<N, B>& operator+
107  (diffType rhs)
108  {
109  sum(rhs);
110  return *this;
111  }
112  CompressibleInt<N, B>& operator++
113  ()
114  {
115  ++num;
116  return *this;
117  }
118  CompressibleInt<N, B>& operator+=
119  (N n)
120  {
121  num += n;
122  return *this;
123  }
124 
125  template<typename T, typename LIST>
126  static uint32 GCF
127  (const LIST& list, T minVal = 0);
128 
129  static bool writeGCF
130  (uint32 gcf,
131  MemBitStream* b)
132  {
133  return b->addVar(gcf - 1);
134  }
135  static uint32 readGCF
136  (MemBitStream* b)
137  {
138  return 1 + b->getVar<uint32>();
139  }
140 
141  UNSIGN(N) operator/
142  (uint d)
143  const
144  {
145  return static_cast<UNSIGN(N)>(num) / d;
146  }
147 
148  size_t bitsNeeded
149  ()
150  const
151  {
152  return Xpace::bitsNeeded(num);
153  }
154 
155  bool addBits
156  (size_t bits,
157  MemBitStream* b)
158  const
159  {
160  return b->addBits(bits, num);
161  }
162 
163  size_t lenVar
164  ()
165  const
166  {
167  return MemBitStream::lenVar(num);
168  }
169 
170  bool addVar
171  (MemBitStream* b)
172  const
173  {
174  return b->addVar(num);
175  }
176 
177  static
178  N getBits
179  (MemBitStream* b,
180  size_t numBits,
181  BytePool* = 0)
182  {
183  return b->getBits<N>(numBits);
184  }
185 
186  static
187  N getVar
188  (MemBitStream* b,
189  BytePool* = 0)
190  {
191  return b->getVar<N>();
192  }
193 
194  private:
195  N num;
196  };
197 
198  // ============================== STRING ====================
199 
200  template <typename CH>
201  inline
202  void readString
203  (MemBitStream* b,
204  CH* ch,
205  size_t length)
206  {
207  if (length)
208  {
209  size_t cs(1 + b->getBits<size_t>(3 + (sizeof(*ch) > 1)));
210  for ( ; length--; ++ch)
211  *ch = b->getBits<uint>(cs);
212  }
213  }
214 
215  template <typename STR>
216  inline
217  void readString
218  (MemBitStream* b,
219  STR* str)
220  {
221  readString(b, str->data, str->length);
222  }
223 
224  template <typename CH>
225  inline
226  size_t charSize
227  (const CH* str,
228  size_t length)
229  {
230  CH max_ch(0);
231  for (size_t i(length); i--; ++str)
232  max_ch = std::max(max_ch, *str);
233  return Xpace::bitsNeeded(max_ch);
234  }
235 
236  template <typename CH>
237  inline
238  size_t stringLen
239  (const CH* str,
240  size_t len)
241  {
242  size_t cs(charSize(str, len));
243  return MemBitStream::lenVar(len) +
244  3 +
245  len * cs;
246  }
247 
248  template <typename STR>
249  inline
250  size_t stringLen
251  (const STR& str)
252  {
253  return stringLen(str.data, str.length);
254  }
255 
256  template <typename CH>
257  inline
258  bool writeString
259  (const CH* str,
260  size_t length,
261  MemBitStream* b)
262  {
263  if (!b->addVar(length))
264  return false;
265  if (length)
266  {
267  size_t cs(charSize(str, length));
268  if (!b->addBits(3 + (sizeof(*str) > 1), cs - 1))
269  return false;
270 
271  const CH* ch(str);
272  for (size_t i(length); i--; ++ch)
273  if (!b->addBits(cs, *ch))
274  return false;
275  }
276 
277  return true;
278  }
279 
280  template <typename STR>
281  inline
282  bool writeString
283  (const STR& str,
284  MemBitStream* b)
285  {
286  return writeString(str.data, str.length, b);
287  }
288 
289  template <typename STR>
291  {
292  public:
294  class diffType;
295  typedef diffType normType;
296 
298  (int = 0)
299  {
300  }
301 
303  (const STR& s) :
304  str(s)
305  {
306  }
307 
309  (MemBitStream* b,
310  BytePool* pool) :
311  str(pool->allocString<STR>(b->getVar<uint>()))
312  {
313  readString(b, &str);
314  }
315 
316  CompressibleString& operator=
317  (const STR& s)
318  {
319  str = s;
320  return *this;
321  }
322 
323  operator const STR&
324  ()
325  const
326  {
327  return str;
328  }
329 
330  const typename STR::charType* data
331  ()
332  const
333  {
334  return str.data;
335  }
336 
337  size_t length
338  ()
339  const
340  {
341  return str.length;
342  }
343 
344  static STR min
345  ()
346  {
347  return min_str;
348  }
349  static STR max
350  ()
351  {
352  return max_str;
353  }
354 
355  bool operator==
357  const
358  {
359  return str == rhs.str;
360  }
361  bool operator!=
363  const
364  {
365  return str != rhs.str;
366  }
367  bool operator>
369  const
370  {
371  return str > rhs.str;
372  }
373  bool operator<
375  const
376  {
377  return str < rhs.str;
378  }
379 
380  diffType diff
381  (const CompressibleString&,
382  BytePool*)
383  const;
384  diffType operator-
386  {
387  assert(0);
388  return min_str;
389  }
391  (const diffType&,
392  BytePool*)
393  const;
394  CompressibleString operator+
395  (const diffType&)
396  {
397  assert(0);
398  return min_str;
399  }
400 
401  CompressibleString& operator+=
402  (const CompressibleString&);
403  CompressibleString& operator*
404  (uint32 rhs)
405  {
406  rhs = rhs;
407  assert(rhs == 1);
408  return *this;
409  }
410  CompressibleString& operator/
411  (uint32 rhs)
412  {
413  rhs = rhs;
414  assert(rhs == 1);
415  return *this;
416  }
417 
418  template<typename T, typename LIST>
419  static uint32 GCF
420  (const LIST& /*list*/, T /*minVal*/ = 0)
421  {
422  return 1;
423  }
424 
425  static bool writeGCF
427  MemBitStream*)
428  {
429  return true;
430  }
431 
432  static uint32 readGCF
433  (MemBitStream*)
434  {
435  return 1;
436  }
437 
438  size_t bitsNeeded
439  ()
440  const
441  {
442  return 1000000; // TODO; max str is not the biggest str
443  }
444 
445  bool addBits
446  (size_t,
447  MemBitStream*)
448  const
449  {
450  assert(0);
451  return false;
452  }
453 
454  size_t lenVar
455  ()
456  const
457  {
458  return stringLen(str);
459  }
460 
461  virtual
462  bool addVar
463  (MemBitStream* b)
464  const
465  {
466  return writeString(str, b);
467  }
468 
469  static
471  (MemBitStream* /*b*/,
472  size_t /*numBits*/)
473  {
474  assert(0);
475  return CompressibleString();
476  }
477 
478  static
480  (MemBitStream* b,
481  BytePool* pool)
482  {
483  return CompressibleString(b, pool);
484  }
485 
486  friend uint qHash
487  (const CompressibleString& cs)
488  {
489  return qHash(QByteArray(reinterpret_cast<const char*>(cs.str.data), int(sizeof(typename STR::charType) * cs.str.length)));
490  }
491 
492  private:
493  STR str;
494  static STR min_str, max_str;
495  };
496 
497  template <typename STR>
498  class CompressibleString<STR>::diffType
499  {
500  friend class CompressibleString<STR>;
501  public:
502  typedef diffType normType;
503 
504  diffType
505  (int = 0) :
506  prefix(0)
507  {
508  }
509 
510  diffType
511  (MemBitStream* b,
512  BytePool* pool) :
513  prefix(b->getVar<uint>()),
514  str(b, pool)
515  {
516  }
517 
518  static diffType min
519  ()
520  {
521  return diffType();
522  }
523 
524  static diffType max
525  ()
526  {
527  diffType ret;
528  ret.prefix = ~0;
529  ret.str = CompressibleString<STR>::max();
530  return ret;
531  }
532 
533  bool operator==
534  (const diffType& rhs)
535  const
536  {
537  return (prefix == rhs.prefix) && (str == rhs.str);
538  }
539  bool operator!=
540  (const diffType& rhs)
541  const
542  {
543  return !(*this == rhs);
544  }
545  bool operator>
546  (const diffType& rhs)
547  const
548  {
549  if (prefix > rhs.prefix)
550  return true;
551  if (prefix < rhs.prefix)
552  return false;
553  return str > rhs.str;
554  }
555  bool operator<
556  (const diffType& rhs)
557  const
558  {
559  if (prefix < rhs.prefix)
560  return true;
561  if (prefix > rhs.prefix)
562  return false;
563  return str < rhs.str;
564  }
565 
566  diffType& operator=
567  (const STR& s)
568  {
569  str = s;
570  prefix = 0;
571  return *this;
572  }
573 
574  const diffType& operator*
575  (uint32 rhs)
576  const
577  {
578  rhs = rhs;
579  assert(rhs == 1);
580  return *this;
581  }
582  const diffType& operator/
583  (uint32 rhs)
584  const
585  {
586  rhs = rhs;
587  assert(rhs == 1);
588  return *this;
589  }
590 
591  template<typename T, typename LIST>
592  static uint32 GCF
593  (const LIST& /*list*/,
594  T /*minVal*/ = 0)
595  {
596  return 1;
597  }
598 
599  static bool writeGCF
601  MemBitStream*)
602  {
603  return true;
604  }
605 
606  static uint32 readGCF
607  (MemBitStream*)
608  {
609  return 1;
610  }
611 
612  size_t bitsNeeded
613  ()
614  const
615  {
616  return 1000000; // TODO; max str is not the biggest str
617  }
618 
619  bool addBits
620  (size_t,
621  MemBitStream*)
622  const
623  {
624  assert(0);
625  return false;
626  }
627 
628  size_t lenVar
629  ()
630  const
631  {
632  return MemBitStream::lenVar(prefix) + str.lenVar();
633  }
634 
635  bool addVar
636  (MemBitStream* b)
637  const
638  {
639  return b->addVar(prefix) + str.addVar(b);
640  }
641 
642  static
643  diffType getVar
644  (MemBitStream* b,
645  BytePool* pool)
646  {
647  return diffType(b, pool);
648  }
649 
650  static
651  diffType getBits
652  (MemBitStream* b,
653  size_t numBits)
654  {
655  assert(0);
656  return diffType();
657  }
658 
659  const diffType& diff
660  (const diffType&,
661  BytePool*)
662  const
663  {
664  return *this;
665  }
666 
667  const diffType& sum
668  (const diffType& rhs,
669  BytePool*)
670  {
671  return rhs;
672  }
673 
674  friend uint qHash
675  (const diffType& dt)
676  {
677  return ::qHash(dt.prefix) + qHash(dt.str);
678  }
679 
680  private:
681  uint prefix;
683  };
684 
685  // ================================ COMPRESS LIST ===========
686 
687  template <typename T>
689  {
690  public:
691  size_t findLength
692  (const std::vector<T>& vals,
693  size_t count,
694  BytePool* pool = 0); // pool for temps if Ts aren't self-contained
695 
696  void continueEncode
697  (const std::vector<T>& vals,
698  MemBitStream* b);
699 
700  void encode
701  (const std::vector<T>& vals,
702  size_t count,
703  MemBitStream* b,
704  BytePool* pool = 0)
705  {
706  findLength(vals, count, pool);
707  continueEncode(vals, b);
708  }
709 
710  void decode
711  (MemBitStream* b,
712  std::vector<T>* vals,
713  BytePool* pool = 0, // pool for Ts' content if they aren't self contained
714  size_t maxVals = ~0); // maximum number of values to decode
715 
716  private:
717  iList<T> vals_list;
718  std::vector<typename T::diffType> deltas;
719  iList<typename T::diffType> deltas_list;
720 
721  // communication from findLength to continueEncode
722  bool is_single;
723  size_t vals_len, deltas_len;
724  };
725 
726  class FloatList
727  {
728  public:
729  FloatList
730  (uint precision = ~0);
731 
732  void encode
733  (const std::vector<DecimalFloat>& startVals,
734  size_t count,
735  MemBitStream* b);
736 
737  void decode
738  (MemBitStream* b,
739  std::vector<DecimalFloat>* vals);
740 
741  private:
742  const uint precision;
743  std::vector<CompressibleInt<int64> > ints;
745  };
746 
747 
748  // ==========================================================
749  // ==========================================================
750  // ==========================================================
751 
752  // ================================ COMPRESS LIST ===========
753 
754  template<typename T>
755  inline
757  (const std::vector<T>& vals,
758  size_t count,
759  BytePool* pool)
760  {
761  if (count == 1)
762  {
763  is_single = true;
764  return vals.front().lenVar();
765  }
766 
767  is_single = false;
768 
769  vals_list.set(vals, count, pool);
770  vals_len = vals_list.getLen();
771 
772  deltas.clear();
773  for (typename std::vector<T>::const_iterator v(vals.begin()); ++v != vals.begin() + count; )
774  deltas.push_back(v->diff(*(v - 1), pool));
775  deltas_list.set(deltas, count - 1, pool);
776 
777  deltas_len = MemBitStream::lenVar(vals[0]) + deltas_list.getLen();
778 
779  return std::min(vals_len, deltas_len);
780  }
781 
782  template<typename T>
783  inline
785  (const std::vector<T>& vals,
786  MemBitStream* b)
787  {
788  if (is_single)
789  {
790  #if SHOW_STATS
791  _is_delta = false;
792  #endif
793 
794  b->addBit(0);
795  vals.front().addVar(b);
796  }
797 
798  else
799  {
800  #if SHOW_STATS
801  _is_delta = (deltas_len < vals_len);
802  #endif
803 
804  if (vals_len <= deltas_len)
805  {
806  b->addBit(0);
807  vals_list.encode(b);
808  }
809  else
810  {
811  b->addBit(1);
812  vals.front().addVar(b);
813  deltas_list.encode(b);
814  }
815  }
816  }
817 
818  template<typename T>
819  inline
821  (MemBitStream* b,
822  std::vector<T>* vals,
823  BytePool* pool,
824  size_t maxVals)
825  {
826  if (b->getBit())
827  {
828  vals->push_back(T::getVar(b, pool));
829  deltas.clear();
830  if (!INVALID(maxVals))
831  --maxVals;
832  deltas_list.decode(b, pool, &deltas, maxVals);
833  for (typename std::vector<typename T::diffType>::const_iterator d(deltas.begin()); d != deltas.end(); ++d)
834  vals->push_back(vals->back().sum(*d, pool));
835  }
836  else
837  vals_list.decode(b, pool, vals, maxVals);
838  }
839 
840  // ================================ GCF =====================
841 
842  // static
843  template <typename N, typename B>
844  template<typename T, typename LIST>
845  inline
846  uint32 CompressibleInt<N, B>::GCF(const LIST& list, T minVal)
847  {
848  auto it(list.begin());
849  while (*it == minVal)
850  if (++it == list.end())
851  return 1;
852 
853  std::vector<uint32> factors;
854  typename T::normType n(*it - minVal);
855  static uint32 primes[] = { 2u, 3u, 5u, 7u, 11u, 13u, 17u, 19u, 23u, 29u, 31u, 37u, 41u,
856  43u, 47u, 53u, 59u, 61u, 67u, 71u, 73u, 79u, 83u, 89u, 97u,
857  ~0u };
858  for (uint32 *f(primes); (typename T::type(n) > typename T::type(*f)) && (*f != ~0u); )
859  {
860  divide<typename T::normType> d(n, *f);
861  if (d.rem == 0)
862  {
863  factors.push_back(*f);
864  n = d.quot;
865  }
866  else
867  ++f;
868  }
869 
870  uint32 gcf(1);
871  for (std::vector<uint32>::const_iterator f(factors.begin()); f < factors.end(); ++f)
872  gcf *= *f;
873 
874  if (gcf > 1)
875  for (it = list.begin(); ++it != list.end(); )
876  {
877  if (*it == *(it - 1))
878  continue;
879 
880  n = *it - minVal;
881  for (std::vector<uint32>::iterator f(factors.begin()); f < factors.end(); ++f)
882  {
883  divide<typename T::normType> d(n, *f);
884  if (d.rem == 0)
885  n = d.quot;
886  else
887  {
888  if ((gcf /= *f) == 1)
889  return 1;
890  *f = 1;
891  }
892  }
893  }
894 
895  return gcf;
896  }
897 
898  // ================================ COMPRESS STRING =========
899 
900 
901  template <typename STR>
904  BytePool* pool)
905  const
906  {
907  diffType result;
908 
909  typename STR::charType *l(str.data), *r(rhs.str.data);
910  size_t len(std::min(str.length, rhs.str.length));
911  for (result.prefix = 0; len -- && (*l == *r); ++l, ++r)
912  ++result.prefix;
913 
914  typename STR::charType* d(result.str.str.data = reinterpret_cast<typename STR::charType*>(pool->alloc(sizeof(typename STR::charType) * (result.str.str.length = str.length - result.prefix))));
915 
916  while (l < str.data + str.length)
917  *d++ = *l++;
918 
919  assert(ptrdiff_t(result.str.str.length) == d - result.str.str.data);
920 
921  return result;
922  }
923 
924  template <typename STR>
926  (const diffType& rhs,
927  BytePool* pool)
928  const
929  {
931  result.str.length = rhs.prefix + rhs.str.str.length;
932  result.str.data = reinterpret_cast<typename STR::charType*>(pool->alloc(sizeof(typename STR::charType) * result.str.length));
933 
934  typename STR::charType* d(result.str.data);
935 
936  typename STR::charType *l(str.data);
937  for (size_t prefix(rhs.prefix); prefix--; )
938  *d++ = *l++;
939 
940  typename STR::charType *r(rhs.str.str.data);
941  for (size_t body(rhs.str.str.length); body--; )
942  *d++ = *r++;
943 
944  return result;
945  }
946 }
947 
948 #endif
static bool writeGCF(uint32 gcf, MemBitStream *b)
Definition: compress.h:130
void continueEncode(const std::vector< T > &vals, MemBitStream *b)
Definition: compress.h:785
const Xpace_Char16 Xpace_Data_Type type
Definition: table_c.h:141
CompressibleString< STR > baseType
Definition: compress.h:293
Copyright (C) 2012 Xpace, LLC.
void decode(MemBitStream *b, std::vector< T > *vals, BytePool *pool=0, size_t maxVals=~0)
Definition: compress.h:821
unsigned int uint
Definition: types.h:75
static N getBits(MemBitStream *b, size_t numBits, BytePool *=0)
Definition: compress.h:179
bool _is_delta
bool INVALID(N n)
Definition: types.h:96
size_t lenVar() const
Definition: compress.h:164
bool addVar(MemBitStream *b) const
Definition: compress.h:171
uint const Xpace_Char8 size_t len
Definition: table_c.h:180
static uint32 GCF(const LIST &list, T minVal=0)
Definition: compress.h:846
void readString(MemBitStream *b, CH *ch, size_t length)
Definition: compress.h:203
CompressibleInt< UNSIGN(N), N > normType
Definition: compress.h:27
static uint32 readGCF(MemBitStream *b)
Definition: compress.h:136
static N getVar(MemBitStream *b, BytePool *=0)
Definition: compress.h:188
bool writeString(const CH *str, size_t length, MemBitStream *b)
Definition: compress.h:259
size_t charSize(const CH *str, size_t length)
Definition: compress.h:227
size_t bitsNeeded() const
Definition: compress.h:149
diffType diff(const CompressibleString &, BytePool *) const
Definition: compress.h:903
Xpace_StoreAccess Xpace_Table * result
Definition: table_c.h:42
N sum(diffType rhs, BytePool *=0)
Definition: compress.h:101
unsigned int uint32
Definition: types.h:85
size_t findLength(const std::vector< T > &vals, size_t count, BytePool *pool=0)
Definition: compress.h:757
size_t stringLen(const CH *str, size_t len)
Definition: compress.h:239
uint const Xpace_Char8 * data
Definition: table_c.h:180
#define CHANGE_SIGN(T)
Definition: types.h:140
UNSIGN(N) operator/(uint d) const
Definition: compress.h:141
Xpace project main namespace
Definition: datetime.h:18
diffType diff(const CompressibleInt< N, B > &rhs, BytePool *=0) const
Definition: compress.h:89
CompressibleInt< SIGN(N), N > diffType
Definition: compress.h:26
bool addBits(size_t bits, MemBitStream *b) const
Definition: compress.h:156
CompressibleInt< B > baseType
Definition: compress.h:25
CompressibleString sum(const diffType &, BytePool *) const
Definition: compress.h:926

current as of Wed Jun 10 2026 12:00:05