/* Copyright 2014-2016 Jan Huwald, Stephan Richter
This file is part of HRTC.
HRTC is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
HRTC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with this program (see file LICENSE). If not, see
. */
#pragma once
#include
#include
#include
#include
#include
#include
using namespace std;
#include
#include
#include
#include
using boost::dynamic_bitset;
using boost::optional;
namespace prog_options = boost::program_options;
#include
using integer_encoding::EncodingPtr;
// space time points
typedef uint64_t Time;
const Time maxTime = Time(1) << 48;
typedef uint16_t TId;
const TId maxTId = -1;
union STP {
uint64_t raw;
struct {
Time time : 48;
TId id : 16; // trajectory id
};
STP& operator= (STP const &s) { raw = s.raw; return *this; }
bool operator== (STP const &s) const { return raw == s.raw; }
};
#define GEN(op) \
bool operator op (STP p1, STP p2) { \
static_assert(sizeof(p1) == sizeof(p1.raw), "STP not packed"); \
return (p1.time op p2.time) || ((p1.time == p2.time) && (p1.id op p2.id)); \
}
GEN(<)
GEN(>)
#undef GEN
// support vector
struct SVI {
// To save space using the variable length encoding, dt-1 is
// stored. This works as dt >= 1 is guaranteed.
uint32_t dt;
// Signed difference, encoded via signed2unsigned
uint32_t v;
};
// A buffer that stores SVI structs (x0, v0), ..., (xn, vn) in memory
// as xn, ..., x0, v0, ..., vn and helps with (de)compression. This
// keeps numbers of the same magnitude proximate in memory while
// compressing only one buffer (storing only one size, not copying
// memory arounds)
//
// ATTENTION pointer mangling: uncompressed stores the center of the
// buffer pointed to by uncompressed_full. Elements are appended by
// growing in both directions.
struct SplitSVIBuffer {
size_t size, compressed_size; // no. of uint32_t, not bytes!
uint32_t *uncompressed_full,
*uncompressed,
*compressed;
EncodingPtr codec;
// init with max. number of pairs to store
SplitSVIBuffer(EncodingPtr codec, size_t size)
: size(size),
compressed_size(codec->require(2 * size)),
uncompressed_full(new uint32_t[DECODE_REQUIRE_MEM(2 * size)]),
uncompressed(uncompressed_full + size),
compressed(new uint32_t[compressed_size]),
codec(codec) {
}
void set(size_t pos, SVI val) {
*(uncompressed + pos) = val.dt;
*(uncompressed - pos - 1) = val.v;
}
SVI get(size_t pos) {
SVI res;
res.dt = *(uncompressed + pos);
res.v = *(uncompressed - pos - 1);
return res;
}
// return pointer to buf, buf size in uint32_t
tuple encode(size_t numSVI) {
auto res_size = compressed_size;
codec->encodeArray(uncompressed - numSVI, numSVI * 2, compressed, &res_size);
return make_tuple(compressed, res_size);
}
void decode(size_t numSVI, size_t csize) {
codec->decodeArray(compressed, csize, uncompressed - numSVI, 2 * numSVI);
}
~SplitSVIBuffer() {
delete[] uncompressed_full;
delete[] compressed;
}
};
struct ChunkSize {
uint32_t raw; // uncompressed size in bytes
uint32_t compressed; // compressed size in bytes
};
template
Dst bit_convert(Src s) {
static_assert(sizeof(Src) == sizeof(Dst), "bit size mismatch");
union {
Src s;
Dst d;
} c;
c.s = s;
return c.d;
}
template
constexpr int bitsizeof() { return 8 * sizeof(T); }
char* hrtc_version_string() {
#define str(s) #s
#define xstr(s) str(s)
return (char*) xstr(HRTC_VERSION);
#undef str
}