mirror of
https://github.com/mhx/dwarfs.git
synced 2025-09-11 13:30:47 -04:00
chore: sync fsst from upstream
This commit is contained in:
parent
73fdfc8a68
commit
388a66013a
@ -1,4 +1,4 @@
|
|||||||
cmake_minimum_required(VERSION 3.0)
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
project(fsst)
|
project(fsst)
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ fsst_decompress(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (posOut+24 <= size) { // handle the possibly 3 last bytes without a loop
|
if (posOut+32 <= size) { // handle the possibly 3 last bytes without a loop
|
||||||
if (posIn+2 <= lenIn) {
|
if (posIn+2 <= lenIn) {
|
||||||
strOut[posOut] = strIn[posIn+1];
|
strOut[posOut] = strIn[posIn+1];
|
||||||
if (strIn[posIn] != FSST_ESC) {
|
if (strIn[posIn] != FSST_ESC) {
|
||||||
|
@ -21,23 +21,31 @@
|
|||||||
#include <immintrin.h>
|
#include <immintrin.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
namespace libfsst {
|
||||||
bool fsst_hasAVX512() {
|
bool fsst_hasAVX512() {
|
||||||
int info[4];
|
int info[4];
|
||||||
__cpuidex(info, 0x00000007, 0);
|
__cpuidex(info, 0x00000007, 0);
|
||||||
return (info[1]>>16)&1;
|
return (info[1]>>16)&1;
|
||||||
}
|
}
|
||||||
|
} // namespace libfsst
|
||||||
#else
|
#else
|
||||||
#include <cpuid.h>
|
#include <cpuid.h>
|
||||||
|
namespace libfsst {
|
||||||
bool fsst_hasAVX512() {
|
bool fsst_hasAVX512() {
|
||||||
int info[4];
|
int info[4];
|
||||||
__cpuid_count(0x00000007, 0, info[0], info[1], info[2], info[3]);
|
__cpuid_count(0x00000007, 0, info[0], info[1], info[2], info[3]);
|
||||||
return (info[1]>>16)&1;
|
return (info[1]>>16)&1;
|
||||||
}
|
}
|
||||||
|
} // namespace libfsst
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
|
namespace libfsst {
|
||||||
bool fsst_hasAVX512() { return false; }
|
bool fsst_hasAVX512() { return false; }
|
||||||
|
} // namespace libfsst
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace libfsst {
|
||||||
|
|
||||||
// BULK COMPRESSION OF STRINGS
|
// BULK COMPRESSION OF STRINGS
|
||||||
//
|
//
|
||||||
// In one call of this function, we can compress 512 strings, each of maximum length 511 bytes.
|
// In one call of this function, we can compress 512 strings, each of maximum length 511 bytes.
|
||||||
@ -138,3 +146,5 @@ size_t fsst_compressAVX512(SymbolTable &symbolTable, u8* codeBase, u8* symbolBas
|
|||||||
#endif
|
#endif
|
||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
|
} // namespace libfsst
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
// You can contact the authors via the FSST source repository : https://github.com/cwida/fsst
|
// You can contact the authors via the FSST source repository : https://github.com/cwida/fsst
|
||||||
#include "libfsst.hpp"
|
#include "libfsst.hpp"
|
||||||
|
|
||||||
|
namespace libfsst {
|
||||||
Symbol concat(Symbol a, Symbol b) {
|
Symbol concat(Symbol a, Symbol b) {
|
||||||
Symbol s;
|
Symbol s;
|
||||||
u32 length = a.length()+b.length();
|
u32 length = a.length()+b.length();
|
||||||
@ -25,12 +26,13 @@ Symbol concat(Symbol a, Symbol b) {
|
|||||||
s.val.num = (b.val.num << (8*a.length())) | a.val.num;
|
s.val.num = (b.val.num << (8*a.length())) | a.val.num;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
} // namespace libfsst
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
template <>
|
template <>
|
||||||
class hash<QSymbol> {
|
class hash<libfsst::QSymbol> {
|
||||||
public:
|
public:
|
||||||
size_t operator()(const QSymbol& q) const {
|
size_t operator()(const libfsst::QSymbol& q) const {
|
||||||
uint64_t k = q.symbol.val.num;
|
uint64_t k = q.symbol.val.num;
|
||||||
const uint64_t m = 0xc6a4a7935bd1e995;
|
const uint64_t m = 0xc6a4a7935bd1e995;
|
||||||
const int r = 47;
|
const int r = 47;
|
||||||
@ -48,6 +50,7 @@ class hash<QSymbol> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace libfsst {
|
||||||
bool isEscapeCode(u16 pos) { return pos < FSST_CODE_BASE; }
|
bool isEscapeCode(u16 pos) { return pos < FSST_CODE_BASE; }
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out, const Symbol& s) {
|
std::ostream& operator<<(std::ostream& out, const Symbol& s) {
|
||||||
@ -289,7 +292,7 @@ static inline size_t compressSIMD(SymbolTable &symbolTable, u8* symbolBase, size
|
|||||||
if (++batchPos == 512) break;
|
if (++batchPos == 512) break;
|
||||||
} while(curOff < len[curLine]);
|
} while(curOff < len[curLine]);
|
||||||
|
|
||||||
if ((batchPos == 512) || (outOff > (1<<19)) || (++curLine >= nlines)) { // cannot accumulate more?
|
if ((batchPos == 512) || (outOff > (1<<19)) || (++curLine >= nlines) || (((len[curLine])*2 + 7) > budget)) { // cannot accumulate more?
|
||||||
if (batchPos-empty >= 32) { // if we have enough work, fire off fsst_compressAVX512 (32 is due to max 4x8 unrolling)
|
if (batchPos-empty >= 32) { // if we have enough work, fire off fsst_compressAVX512 (32 is due to max 4x8 unrolling)
|
||||||
// radix-sort jobs on length (longest string first)
|
// radix-sort jobs on length (longest string first)
|
||||||
// -- this provides best load balancing and allows to skip empty jobs at the end
|
// -- this provides best load balancing and allows to skip empty jobs at the end
|
||||||
@ -615,7 +618,9 @@ inline size_t _compressAuto(Encoder *e, size_t nlines, const size_t lenIn[], con
|
|||||||
size_t compressAuto(Encoder *e, size_t nlines, const size_t lenIn[], const u8 *strIn[], size_t size, u8 *output, size_t *lenOut, u8 *strOut[], int simd) {
|
size_t compressAuto(Encoder *e, size_t nlines, const size_t lenIn[], const u8 *strIn[], size_t size, u8 *output, size_t *lenOut, u8 *strOut[], int simd) {
|
||||||
return _compressAuto(e, nlines, lenIn, strIn, size, output, lenOut, strOut, simd);
|
return _compressAuto(e, nlines, lenIn, strIn, size, output, lenOut, strOut, simd);
|
||||||
}
|
}
|
||||||
|
} // namespace libfsst
|
||||||
|
|
||||||
|
using namespace libfsst;
|
||||||
// the main compression function (everything automatic)
|
// the main compression function (everything automatic)
|
||||||
extern "C" size_t fsst_compress(fsst_encoder_t *encoder, size_t nlines, const size_t lenIn[], const u8 *strIn[], size_t size, u8 *output, size_t *lenOut, u8 *strOut[]) {
|
extern "C" size_t fsst_compress(fsst_encoder_t *encoder, size_t nlines, const size_t lenIn[], const u8 *strIn[], size_t size, u8 *output, size_t *lenOut, u8 *strOut[]) {
|
||||||
// to be faster than scalar, simd needs 64 lines or more of length >=12; or fewer lines, but big ones (totLen > 32KB)
|
// to be faster than scalar, simd needs 64 lines or more of length >=12; or fewer lines, but big ones (totLen > 32KB)
|
||||||
@ -626,7 +631,7 @@ extern "C" size_t fsst_compress(fsst_encoder_t *encoder, size_t nlines, const si
|
|||||||
|
|
||||||
/* deallocate encoder */
|
/* deallocate encoder */
|
||||||
extern "C" void fsst_destroy(fsst_encoder_t* encoder) {
|
extern "C" void fsst_destroy(fsst_encoder_t* encoder) {
|
||||||
Encoder *e = (Encoder*) encoder;
|
Encoder *e = (Encoder*) encoder;
|
||||||
delete e;
|
delete e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,10 +37,12 @@ using namespace std;
|
|||||||
#include "fsst.h" // the official FSST API -- also usable by C mortals
|
#include "fsst.h" // the official FSST API -- also usable by C mortals
|
||||||
|
|
||||||
/* unsigned integers */
|
/* unsigned integers */
|
||||||
|
namespace libfsst {
|
||||||
typedef uint8_t u8;
|
typedef uint8_t u8;
|
||||||
typedef uint16_t u16;
|
typedef uint16_t u16;
|
||||||
typedef uint32_t u32;
|
typedef uint32_t u32;
|
||||||
typedef uint64_t u64;
|
typedef uint64_t u64;
|
||||||
|
} // namespace libfsst
|
||||||
|
|
||||||
#define FSST_ENDIAN_MARKER ((u64) 1)
|
#define FSST_ENDIAN_MARKER ((u64) 1)
|
||||||
#define FSST_VERSION_20190218 20190218
|
#define FSST_VERSION_20190218 20190218
|
||||||
@ -57,6 +59,7 @@ typedef uint64_t u64;
|
|||||||
#define FSST_CODE_MAX (1UL<<FSST_CODE_BITS) /* all bits set: indicating a symbol that has not been assigned a code yet */
|
#define FSST_CODE_MAX (1UL<<FSST_CODE_BITS) /* all bits set: indicating a symbol that has not been assigned a code yet */
|
||||||
#define FSST_CODE_MASK (FSST_CODE_MAX-1UL) /* all bits set: indicating a symbol that has not been assigned a code yet */
|
#define FSST_CODE_MASK (FSST_CODE_MAX-1UL) /* all bits set: indicating a symbol that has not been assigned a code yet */
|
||||||
|
|
||||||
|
namespace libfsst {
|
||||||
inline uint64_t fsst_unaligned_load(u8 const* V) {
|
inline uint64_t fsst_unaligned_load(u8 const* V) {
|
||||||
uint64_t Ret;
|
uint64_t Ret;
|
||||||
memcpy(&Ret, V, sizeof(uint64_t)); // compiler will generate efficient code (unaligned load, where possible)
|
memcpy(&Ret, V, sizeof(uint64_t)); // compiler will generate efficient code (unaligned load, where possible)
|
||||||
@ -449,3 +452,4 @@ fsst_compressAVX512(
|
|||||||
// C++ fsst-compress function with some more control of how the compression happens (algorithm flavor, simd unroll degree)
|
// C++ fsst-compress function with some more control of how the compression happens (algorithm flavor, simd unroll degree)
|
||||||
size_t compressImpl(Encoder *encoder, size_t n, size_t lenIn[], u8 *strIn[], size_t size, u8 * output, size_t *lenOut, u8 *strOut[], bool noSuffixOpt, bool avoidBranch, int simd);
|
size_t compressImpl(Encoder *encoder, size_t n, size_t lenIn[], u8 *strIn[], size_t size, u8 * output, size_t *lenOut, u8 *strOut[], bool noSuffixOpt, bool avoidBranch, int simd);
|
||||||
size_t compressAuto(Encoder *encoder, size_t n, size_t lenIn[], u8 *strIn[], size_t size, u8 * output, size_t *lenOut, u8 *strOut[], int simd);
|
size_t compressAuto(Encoder *encoder, size_t n, size_t lenIn[], u8 *strIn[], size_t size, u8 * output, size_t *lenOut, u8 *strOut[], int simd);
|
||||||
|
} // namespace libfsst
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
namespace libfsst {
|
||||||
Symbol concat(Symbol a, Symbol b) {
|
Symbol concat(Symbol a, Symbol b) {
|
||||||
Symbol s;
|
Symbol s;
|
||||||
u32 length = min(8, a.length()+b.length());
|
u32 length = min(8, a.length()+b.length());
|
||||||
@ -26,12 +27,14 @@ Symbol concat(Symbol a, Symbol b) {
|
|||||||
*(u64*) s.symbol = ((*(u64*) b.symbol) << (8*a.length())) | *(u64*) a.symbol;
|
*(u64*) s.symbol = ((*(u64*) b.symbol) << (8*a.length())) | *(u64*) a.symbol;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
} // namespace libfsst
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
template <>
|
template <>
|
||||||
class hash<Symbol> {
|
class hash<libfsst::Symbol> {
|
||||||
public:
|
public:
|
||||||
size_t operator()(const Symbol& s) const {
|
size_t operator()(const libfsst::Symbol& s) const {
|
||||||
|
using namespace libfsst;
|
||||||
uint64_t k = *(u64*) s.symbol;
|
uint64_t k = *(u64*) s.symbol;
|
||||||
const uint64_t m = 0xc6a4a7935bd1e995;
|
const uint64_t m = 0xc6a4a7935bd1e995;
|
||||||
const int r = 47;
|
const int r = 47;
|
||||||
@ -49,6 +52,7 @@ class hash<Symbol> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace libfsst {
|
||||||
std::ostream& operator<<(std::ostream& out, const Symbol& s) {
|
std::ostream& operator<<(std::ostream& out, const Symbol& s) {
|
||||||
for (u32 i=0; i<s.length(); i++)
|
for (u32 i=0; i<s.length(); i++)
|
||||||
out << s.symbol[i];
|
out << s.symbol[i];
|
||||||
@ -295,7 +299,9 @@ long makeSample(vector<ulong> &sample, ulong nlines, const ulong len[]) {
|
|||||||
assert(sampleLong > 0);
|
assert(sampleLong > 0);
|
||||||
return (sampleLong < FSST_SAMPLEMAXSZ)?sampleLong:FSST_SAMPLEMAXSZ-sampleLong;
|
return (sampleLong < FSST_SAMPLEMAXSZ)?sampleLong:FSST_SAMPLEMAXSZ-sampleLong;
|
||||||
}
|
}
|
||||||
|
} // namespace libfsst
|
||||||
|
|
||||||
|
using namespace libfsst;
|
||||||
extern "C" fsst_encoder_t* fsst_create(ulong n, const ulong lenIn[], const u8 *strIn[], int dummy) {
|
extern "C" fsst_encoder_t* fsst_create(ulong n, const ulong lenIn[], const u8 *strIn[], int dummy) {
|
||||||
vector<ulong> sample;
|
vector<ulong> sample;
|
||||||
(void) dummy;
|
(void) dummy;
|
||||||
@ -307,14 +313,14 @@ extern "C" fsst_encoder_t* fsst_create(ulong n, const ulong lenIn[], const u8 *s
|
|||||||
|
|
||||||
/* create another encoder instance, necessary to do multi-threaded encoding using the same dictionary */
|
/* create another encoder instance, necessary to do multi-threaded encoding using the same dictionary */
|
||||||
extern "C" fsst_encoder_t* fsst_duplicate(fsst_encoder_t *encoder) {
|
extern "C" fsst_encoder_t* fsst_duplicate(fsst_encoder_t *encoder) {
|
||||||
Encoder *e = new Encoder();
|
Encoder *e = new Encoder();
|
||||||
e->symbolMap = ((Encoder*)encoder)->symbolMap; // it is a shared_ptr
|
e->symbolMap = ((Encoder*)encoder)->symbolMap; // it is a shared_ptr
|
||||||
return (fsst_encoder_t*) e;
|
return (fsst_encoder_t*) e;
|
||||||
}
|
}
|
||||||
|
|
||||||
// export a dictionary in compact format.
|
// export a dictionary in compact format.
|
||||||
extern "C" u32 fsst_export(fsst_encoder_t *encoder, u8 *buf) {
|
extern "C" u32 fsst_export(fsst_encoder_t *encoder, u8 *buf) {
|
||||||
Encoder *e = (Encoder*) encoder;
|
Encoder *e = (Encoder*) encoder;
|
||||||
// In ->version there is a versionnr, but we hide also suffixLim/terminator/symbolCount there.
|
// In ->version there is a versionnr, but we hide also suffixLim/terminator/symbolCount there.
|
||||||
// This is sufficient in principle to *reconstruct* a fsst_encoder_t from a fsst_decoder_t
|
// This is sufficient in principle to *reconstruct* a fsst_encoder_t from a fsst_decoder_t
|
||||||
// (such functionality could be useful to append compressed data to an existing block).
|
// (such functionality could be useful to append compressed data to an existing block).
|
||||||
@ -375,6 +381,7 @@ extern "C" u32 fsst_import(fsst_decoder_t *decoder, u8 *buf) {
|
|||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace libfsst {
|
||||||
// runtime check for simd
|
// runtime check for simd
|
||||||
inline ulong _compressImpl(Encoder *e, ulong nlines, const ulong lenIn[], const u8 *strIn[], ulong size, u8 *output, ulong *lenOut, u8 *strOut[], bool noSuffixOpt, bool avoidBranch, int simd) {
|
inline ulong _compressImpl(Encoder *e, ulong nlines, const ulong lenIn[], const u8 *strIn[], ulong size, u8 *output, ulong *lenOut, u8 *strOut[], bool noSuffixOpt, bool avoidBranch, int simd) {
|
||||||
(void) noSuffixOpt;
|
(void) noSuffixOpt;
|
||||||
@ -394,7 +401,9 @@ inline ulong _compressAuto(Encoder *e, ulong nlines, const ulong lenIn[], const
|
|||||||
ulong compressAuto(Encoder *e, ulong nlines, const ulong lenIn[], const u8 *strIn[], ulong size, u8 *output, ulong *lenOut, u8 *strOut[], int simd) {
|
ulong compressAuto(Encoder *e, ulong nlines, const ulong lenIn[], const u8 *strIn[], ulong size, u8 *output, ulong *lenOut, u8 *strOut[], int simd) {
|
||||||
return _compressAuto(e, nlines, lenIn, strIn, size, output, lenOut, strOut, simd);
|
return _compressAuto(e, nlines, lenIn, strIn, size, output, lenOut, strOut, simd);
|
||||||
}
|
}
|
||||||
|
} // namespace libfsst
|
||||||
|
|
||||||
|
using namespace libfsst;
|
||||||
// the main compression function (everything automatic)
|
// the main compression function (everything automatic)
|
||||||
extern "C" ulong fsst_compress(fsst_encoder_t *encoder, ulong nlines, const ulong lenIn[], const u8 *strIn[], ulong size, u8 *output, ulong *lenOut, u8 *strOut[]) {
|
extern "C" ulong fsst_compress(fsst_encoder_t *encoder, ulong nlines, const ulong lenIn[], const u8 *strIn[], ulong size, u8 *output, ulong *lenOut, u8 *strOut[]) {
|
||||||
// to be faster than scalar, simd needs 64 lines or more of length >=12; or fewer lines, but big ones (totLen > 32KB)
|
// to be faster than scalar, simd needs 64 lines or more of length >=12; or fewer lines, but big ones (totLen > 32KB)
|
||||||
@ -405,7 +414,7 @@ extern "C" ulong fsst_compress(fsst_encoder_t *encoder, ulong nlines, const ulon
|
|||||||
|
|
||||||
/* deallocate encoder */
|
/* deallocate encoder */
|
||||||
extern "C" void fsst_destroy(fsst_encoder_t* encoder) {
|
extern "C" void fsst_destroy(fsst_encoder_t* encoder) {
|
||||||
Encoder *e = (Encoder*) encoder;
|
Encoder *e = (Encoder*) encoder;
|
||||||
delete e;
|
delete e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ using namespace std;
|
|||||||
|
|
||||||
#include "fsst12.h" // the official FSST API -- also usable by C mortals
|
#include "fsst12.h" // the official FSST API -- also usable by C mortals
|
||||||
|
|
||||||
|
namespace libfsst {
|
||||||
/* workhorse type for string and buffer lengths: 64-bits on 64-bits platforms and 32-bits on 32-bits platforms */
|
/* workhorse type for string and buffer lengths: 64-bits on 64-bits platforms and 32-bits on 32-bits platforms */
|
||||||
typedef unsigned long ulong;
|
typedef unsigned long ulong;
|
||||||
|
|
||||||
@ -44,6 +45,7 @@ typedef uint8_t u8;
|
|||||||
typedef uint16_t u16;
|
typedef uint16_t u16;
|
||||||
typedef uint32_t u32;
|
typedef uint32_t u32;
|
||||||
typedef uint64_t u64;
|
typedef uint64_t u64;
|
||||||
|
} // namespace libfsst
|
||||||
|
|
||||||
#define FSST_ENDIAN_MARKER ((u64) 1)
|
#define FSST_ENDIAN_MARKER ((u64) 1)
|
||||||
#define FSST_VERSION_20190218 20190218
|
#define FSST_VERSION_20190218 20190218
|
||||||
@ -54,6 +56,7 @@ typedef uint64_t u64;
|
|||||||
#define FSST_CODE_MAX 4096
|
#define FSST_CODE_MAX 4096
|
||||||
#define FSST_CODE_MASK ((u16) (FSST_CODE_MAX-1))
|
#define FSST_CODE_MASK ((u16) (FSST_CODE_MAX-1))
|
||||||
|
|
||||||
|
namespace libfsst {
|
||||||
inline uint64_t fsst_unaligned_load(u8 const* V) {
|
inline uint64_t fsst_unaligned_load(u8 const* V) {
|
||||||
uint64_t Ret;
|
uint64_t Ret;
|
||||||
memcpy(&Ret, V, sizeof(uint64_t)); // compiler will generate efficient code (unaligned load, where possible)
|
memcpy(&Ret, V, sizeof(uint64_t)); // compiler will generate efficient code (unaligned load, where possible)
|
||||||
@ -309,3 +312,4 @@ struct Encoder {
|
|||||||
// C++ fsst-compress function with some more control of how the compression happens (algorithm flavor, simd unroll degree)
|
// C++ fsst-compress function with some more control of how the compression happens (algorithm flavor, simd unroll degree)
|
||||||
ulong compressImpl(Encoder *encoder, ulong n, ulong lenIn[], u8 *strIn[], ulong size, u8 * output, ulong *lenOut, u8 *strOut[], bool noSuffixOpt, bool avoidBranch, int simd);
|
ulong compressImpl(Encoder *encoder, ulong n, ulong lenIn[], u8 *strIn[], ulong size, u8 * output, ulong *lenOut, u8 *strOut[], bool noSuffixOpt, bool avoidBranch, int simd);
|
||||||
ulong compressAuto(Encoder *encoder, ulong n, ulong lenIn[], u8 *strIn[], ulong size, u8 * output, ulong *lenOut, u8 *strOut[], int simd);
|
ulong compressAuto(Encoder *encoder, ulong n, ulong lenIn[], u8 *strIn[], ulong size, u8 * output, ulong *lenOut, u8 *strOut[], int simd);
|
||||||
|
} // namespace libfsst
|
||||||
|
Loading…
x
Reference in New Issue
Block a user