-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathGlobal.hpp
187 lines (144 loc) · 4.68 KB
/
Global.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/*
Copyright 2011-2024 Frederic Langlet
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
you may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
#ifndef _Global_
#define _Global_
#include <set>
#include <string>
#include "types.hpp"
namespace kanzi {
class Global {
public:
enum DataType { UNDEFINED, TEXT, MULTIMEDIA, EXE, NUMERIC, BASE64, DNA, BIN, UTF8, SMALL_ALPHABET };
static int stretch(int d); // ln(x / (1 - x))
static int squash(int d); // 1 / (1 + e-x) (inverse of stretch)
static int log2(uint32 x); // fast, integer rounded
static int log2(uint64 x); // fast, integer rounded
static int _log2(uint32 x); // same as log2 minus check on input value
static int _log2(uint64 x); // same as log2 minus check on input value
static int trailingZeros(uint32 x);
static int trailingZeros(uint64 x);
static int log2_1024(uint32 x); // slow, accurate to 1/1024th
static void computeJobsPerTask(int jobsPerTask[], int jobs, int tasks);
static int computeFirstOrderEntropy1024(int blockLen, const uint histo[]);
static void computeHistogram(const byte block[], int end, uint freqs[], bool isOrder0=true, bool withTotal=false);
static DataType detectSimpleType(int count, const uint histo[]);
static bool isReservedName(std::string fileName);
private:
Global();
~Global() {};
static const Global _singleton;
static const int LOG2_4096[257]; // 4096*Math.log2(x)
static const int LOG2[256]; // int(Math.log2(x-1))
static int STRETCH[4096];
static int SQUASH[4096];
static char BASE64_SYMBOLS[];
static char DNA_SYMBOLS[];
static char NUMERIC_SYMBOLS[];
std::set<std::string> _reservedNames;
};
// return p = 1/(1 + exp(-d)), d scaled by 8 bits, p scaled by 12 bits
inline int Global::squash(int d)
{
if (d >= 2048)
return 4095;
return (d <= -2048) ? 0 : SQUASH[d + 2047];
}
inline int Global::stretch(int d)
{
return STRETCH[d];
}
// x cannot be 0
inline int Global::_log2(uint32 x)
{
#if defined(_MSC_VER)
unsigned long res;
_BitScanReverse(&res, x);
return int(res);
#elif defined(__GNUG__)
return 31 ^ __builtin_clz(x);
#elif defined(__clang__)
return 31 ^ __builtin_clz(x);
#else
int res = 0;
if (x >= 1 << 16) {
x >>= 16;
res = 16;
}
if (x >= 1 << 8) {
x >>= 8;
res += 8;
}
return res + Global::LOG2[x - 1];
#endif
}
// x cannot be 0
inline int Global::_log2(uint64 x)
{
#if defined(_MSC_VER) && defined(_M_AMD64)
unsigned long res;
_BitScanReverse64(&res, x);
return int(res);
#elif defined(__GNUG__)
return 63 ^ __builtin_clzll(x);
#elif defined(__clang__)
return 63 ^ __builtin_clzll(x);
#else
int res = 0;
if (x >= uint64(1) << 32) {
x >>= 32;
res = 32;
}
if (x >= uint64(1) << 16) {
x >>= 16;
res += 16;
}
if (x >= uint64(1) << 8) {
x >>= 8;
res += 8;
}
return res + Global::LOG2[x - 1];
#endif
}
// x cannot be 0
inline int Global::trailingZeros(uint32 x)
{
#if defined(_MSC_VER)
unsigned long res;
_BitScanForward(&res, x);
return int(res);
#elif defined(__GNUG__)
return __builtin_ctz(x);
#elif defined(__clang__)
return __builtin_ctz(x);
#else
return _log2((x & (~x + 1)) - 1);
#endif
}
// x cannot be 0
inline int Global::trailingZeros(uint64 x)
{
#if defined(_MSC_VER) && defined(_M_AMD64)
unsigned long res;
_BitScanForward64(&res, x);
return int(res);
#elif defined(__GNUG__)
return __builtin_ctzll(x);
#elif defined(__clang__)
return __builtin_ctzll(x);
#else
return _log2((x & (~x + 1)) - 1);
#endif
}
}
#endif