@trkyshorty/node-lzf 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +32 -0
- package/README.md +125 -60
- package/binding.gyp +10 -3
- package/index.d.ts +33 -0
- package/index.js +4 -5
- package/package.json +46 -24
- package/prebuilds/darwin-arm64/@trkyshorty+node-lzf.node +0 -0
- package/prebuilds/linux-arm64/@trkyshorty+node-lzf.node +0 -0
- package/prebuilds/linux-x64/@trkyshorty+node-lzf.node +0 -0
- package/prebuilds/win32-x64/@trkyshorty+node-lzf.node +0 -0
- package/src/lzf/lzfP.h +16 -2
- package/src/lzf.cc +267 -61
- package/benchmark/benchmark.js +0 -69
- package/benchmark/data/100.txt +0 -1
- package/benchmark/data/1000.txt +0 -3
- package/benchmark/data/10000.txt +0 -39
- package/benchmark/data/100000.txt +0 -247
- package/test/test.js +0 -27
package/src/lzf.cc
CHANGED
|
@@ -1,95 +1,301 @@
|
|
|
1
1
|
/* node-lzf (C) 2011 Ian Babrou <ibobrik@gmail.com> */
|
|
2
2
|
/* node-lzf (C) 2025 Maintained Türkay Tanrikulu <trky.shorty@gmail.com> */
|
|
3
3
|
|
|
4
|
-
#include <
|
|
5
|
-
#include <stdlib.h>
|
|
4
|
+
#include <napi.h>
|
|
6
5
|
|
|
7
|
-
#
|
|
8
|
-
#include <
|
|
9
|
-
#
|
|
6
|
+
#include <cerrno>
|
|
7
|
+
#include <climits>
|
|
8
|
+
#include <cstdlib>
|
|
9
|
+
#include <string>
|
|
10
10
|
|
|
11
|
-
#include "nan.h"
|
|
12
11
|
#include "lzf/lzf.h"
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
using namespace node;
|
|
13
|
+
namespace {
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
/* Hard caps so a bogus length argument can never trigger a multi-GB
|
|
16
|
+
* allocation. 1 GiB is far above any realistic LZF payload. */
|
|
17
|
+
constexpr size_t kMaxInputLength = 1024u * 1024u * 1024u;
|
|
18
|
+
constexpr size_t kMaxOutputLength = 1024u * 1024u * 1024u;
|
|
19
|
+
|
|
20
|
+
/* Worst-case compressed size for an input of n bytes (same formula the
|
|
21
|
+
* original node-lzf used; slightly above the theoretical n + n/32 + 1). */
|
|
22
|
+
inline size_t CompressBound(size_t n) {
|
|
23
|
+
return n + (n / 16) + 64 + 3;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
struct RawResult {
|
|
27
|
+
char* data = nullptr;
|
|
28
|
+
size_t length = 0;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/* Compresses into a malloc'd buffer shrunk to the exact result size.
|
|
32
|
+
* Returns false and fills `error` on failure (buffer already freed). */
|
|
33
|
+
bool DoCompress(const char* input, size_t inputLength, RawResult* out, std::string* error) {
|
|
34
|
+
size_t bound = CompressBound(inputLength);
|
|
35
|
+
char* buffer = static_cast<char*>(malloc(bound));
|
|
36
|
+
if (buffer == nullptr) {
|
|
37
|
+
*error = "Failed to allocate output buffer";
|
|
38
|
+
return false;
|
|
20
39
|
}
|
|
21
40
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
41
|
+
unsigned int compressedLength = lzf_compress(
|
|
42
|
+
input, static_cast<unsigned int>(inputLength),
|
|
43
|
+
buffer, static_cast<unsigned int>(bound));
|
|
25
44
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return
|
|
45
|
+
if (compressedLength == 0) {
|
|
46
|
+
free(buffer);
|
|
47
|
+
*error = "Compression failed";
|
|
48
|
+
return false;
|
|
30
49
|
}
|
|
31
50
|
|
|
32
|
-
|
|
33
|
-
|
|
51
|
+
char* shrunk = static_cast<char*>(realloc(buffer, compressedLength));
|
|
52
|
+
out->data = shrunk != nullptr ? shrunk : buffer;
|
|
53
|
+
out->length = compressedLength;
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
34
56
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
57
|
+
/* Decompresses into a malloc'd buffer of expectedLength, shrunk to the
|
|
58
|
+
* actual result size. Distinguishes "expected length too small" (E2BIG)
|
|
59
|
+
* from corrupted input via errno set by lzf_decompress. */
|
|
60
|
+
bool DoDecompress(const char* input, size_t inputLength, size_t expectedLength, RawResult* out,
|
|
61
|
+
std::string* error) {
|
|
62
|
+
char* buffer = static_cast<char*>(malloc(expectedLength));
|
|
63
|
+
if (buffer == nullptr) {
|
|
64
|
+
*error = "Failed to allocate output buffer";
|
|
65
|
+
return false;
|
|
38
66
|
}
|
|
39
67
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
68
|
+
errno = 0;
|
|
69
|
+
unsigned int decompressedLength = lzf_decompress(
|
|
70
|
+
input, static_cast<unsigned int>(inputLength),
|
|
71
|
+
buffer, static_cast<unsigned int>(expectedLength));
|
|
72
|
+
|
|
73
|
+
if (decompressedLength == 0) {
|
|
74
|
+
int cause = errno;
|
|
75
|
+
free(buffer);
|
|
76
|
+
*error = cause == E2BIG ? "Decompression failed: expected length too small"
|
|
77
|
+
: "Decompression failed: corrupted input";
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (decompressedLength < expectedLength) {
|
|
82
|
+
char* shrunk = static_cast<char*>(realloc(buffer, decompressedLength));
|
|
83
|
+
if (shrunk != nullptr) buffer = shrunk;
|
|
84
|
+
}
|
|
85
|
+
out->data = buffer;
|
|
86
|
+
out->length = decompressedLength;
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* Wraps a malloc'd result as a Buffer without copying when the runtime
|
|
91
|
+
* supports external buffers (plain Node does); falls back to copy+free. */
|
|
92
|
+
Napi::Value WrapResult(Napi::Env env, RawResult* result) {
|
|
93
|
+
return Napi::Buffer<char>::NewOrCopy(
|
|
94
|
+
env, result->data, result->length,
|
|
95
|
+
[](Napi::Env, char* data) { free(data); });
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* ---- argument validation ------------------------------------------------ */
|
|
48
99
|
|
|
49
|
-
|
|
100
|
+
bool ValidateInputBuffer(const Napi::CallbackInfo& info, std::string* error) {
|
|
101
|
+
if (info.Length() < 1 || !info[0].IsBuffer()) {
|
|
102
|
+
*error = "First argument must be a Buffer";
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
size_t length = info[0].As<Napi::Buffer<char>>().Length();
|
|
106
|
+
if (length == 0) {
|
|
107
|
+
*error = "Input buffer must not be empty";
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
if (length > kMaxInputLength) {
|
|
111
|
+
*error = "Input buffer exceeds 1 GiB limit";
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
return true;
|
|
50
115
|
}
|
|
51
116
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
117
|
+
/* expectedLength is required: the legacy default silently allocated a
|
|
118
|
+
* 999 MB buffer per call, which is a footgun rather than a feature. */
|
|
119
|
+
bool ValidateExpectedLength(const Napi::CallbackInfo& info, size_t* expectedLength,
|
|
120
|
+
std::string* error, bool* rangeError) {
|
|
121
|
+
*rangeError = false;
|
|
122
|
+
if (info.Length() < 2 || !info[1].IsNumber()) {
|
|
123
|
+
*error = "Second argument (expectedLength) must be a number";
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
double raw = info[1].As<Napi::Number>().DoubleValue();
|
|
127
|
+
if (raw != raw /* NaN */ || raw != static_cast<double>(static_cast<int64_t>(raw))) {
|
|
128
|
+
*rangeError = true;
|
|
129
|
+
*error = "expectedLength must be an integer";
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
int64_t value = static_cast<int64_t>(raw);
|
|
133
|
+
if (value <= 0 || static_cast<uint64_t>(value) > kMaxOutputLength) {
|
|
134
|
+
*rangeError = true;
|
|
135
|
+
*error = "expectedLength must be between 1 and 1 GiB";
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
*expectedLength = static_cast<size_t>(value);
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* ---- async workers ------------------------------------------------------ */
|
|
143
|
+
|
|
144
|
+
class CompressWorker : public Napi::AsyncWorker {
|
|
145
|
+
public:
|
|
146
|
+
CompressWorker(Napi::Env env, Napi::Buffer<char> input)
|
|
147
|
+
: Napi::AsyncWorker(env),
|
|
148
|
+
deferred_(Napi::Promise::Deferred::New(env)),
|
|
149
|
+
inputRef_(Napi::Persistent(input.As<Napi::Object>())),
|
|
150
|
+
data_(input.Data()),
|
|
151
|
+
length_(input.Length()) {}
|
|
152
|
+
|
|
153
|
+
Napi::Promise Promise() { return deferred_.Promise(); }
|
|
154
|
+
|
|
155
|
+
protected:
|
|
156
|
+
void Execute() override {
|
|
157
|
+
std::string error;
|
|
158
|
+
if (!DoCompress(data_, length_, &result_, &error)) SetError(error);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
void OnOK() override { deferred_.Resolve(WrapResult(Env(), &result_)); }
|
|
162
|
+
|
|
163
|
+
void OnError(const Napi::Error& e) override { deferred_.Reject(e.Value()); }
|
|
164
|
+
|
|
165
|
+
private:
|
|
166
|
+
Napi::Promise::Deferred deferred_;
|
|
167
|
+
Napi::ObjectReference inputRef_; // keeps the input buffer alive while the worker runs
|
|
168
|
+
const char* data_;
|
|
169
|
+
size_t length_;
|
|
170
|
+
RawResult result_;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
class DecompressWorker : public Napi::AsyncWorker {
|
|
174
|
+
public:
|
|
175
|
+
DecompressWorker(Napi::Env env, Napi::Buffer<char> input, size_t expectedLength)
|
|
176
|
+
: Napi::AsyncWorker(env),
|
|
177
|
+
deferred_(Napi::Promise::Deferred::New(env)),
|
|
178
|
+
inputRef_(Napi::Persistent(input.As<Napi::Object>())),
|
|
179
|
+
data_(input.Data()),
|
|
180
|
+
length_(input.Length()),
|
|
181
|
+
expectedLength_(expectedLength) {}
|
|
182
|
+
|
|
183
|
+
Napi::Promise Promise() { return deferred_.Promise(); }
|
|
184
|
+
|
|
185
|
+
protected:
|
|
186
|
+
void Execute() override {
|
|
187
|
+
std::string error;
|
|
188
|
+
if (!DoDecompress(data_, length_, expectedLength_, &result_, &error)) SetError(error);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
void OnOK() override { deferred_.Resolve(WrapResult(Env(), &result_)); }
|
|
192
|
+
|
|
193
|
+
void OnError(const Napi::Error& e) override { deferred_.Reject(e.Value()); }
|
|
194
|
+
|
|
195
|
+
private:
|
|
196
|
+
Napi::Promise::Deferred deferred_;
|
|
197
|
+
Napi::ObjectReference inputRef_;
|
|
198
|
+
const char* data_;
|
|
199
|
+
size_t length_;
|
|
200
|
+
size_t expectedLength_;
|
|
201
|
+
RawResult result_;
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
/* ---- sync API ----------------------------------------------------------- */
|
|
205
|
+
|
|
206
|
+
Napi::Value Compress(const Napi::CallbackInfo& info) {
|
|
207
|
+
Napi::Env env = info.Env();
|
|
208
|
+
|
|
209
|
+
std::string error;
|
|
210
|
+
if (!ValidateInputBuffer(info, &error)) {
|
|
211
|
+
Napi::TypeError::New(env, error).ThrowAsJavaScriptException();
|
|
212
|
+
return env.Undefined();
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
Napi::Buffer<char> input = info[0].As<Napi::Buffer<char>>();
|
|
216
|
+
RawResult result;
|
|
217
|
+
if (!DoCompress(input.Data(), input.Length(), &result, &error)) {
|
|
218
|
+
Napi::Error::New(env, error).ThrowAsJavaScriptException();
|
|
219
|
+
return env.Undefined();
|
|
55
220
|
}
|
|
221
|
+
return WrapResult(env, &result);
|
|
222
|
+
}
|
|
56
223
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
size_t lenIn = node::Buffer::Length(inBuf);
|
|
224
|
+
Napi::Value Decompress(const Napi::CallbackInfo& info) {
|
|
225
|
+
Napi::Env env = info.Env();
|
|
60
226
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
227
|
+
std::string error;
|
|
228
|
+
bool rangeError = false;
|
|
229
|
+
size_t expectedLength = 0;
|
|
230
|
+
if (!ValidateInputBuffer(info, &error)) {
|
|
231
|
+
Napi::TypeError::New(env, error).ThrowAsJavaScriptException();
|
|
232
|
+
return env.Undefined();
|
|
233
|
+
}
|
|
234
|
+
if (!ValidateExpectedLength(info, &expectedLength, &error, &rangeError)) {
|
|
235
|
+
if (rangeError) Napi::RangeError::New(env, error).ThrowAsJavaScriptException();
|
|
236
|
+
else Napi::TypeError::New(env, error).ThrowAsJavaScriptException();
|
|
237
|
+
return env.Undefined();
|
|
64
238
|
}
|
|
65
239
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
240
|
+
Napi::Buffer<char> input = info[0].As<Napi::Buffer<char>>();
|
|
241
|
+
RawResult result;
|
|
242
|
+
if (!DoDecompress(input.Data(), input.Length(), expectedLength, &result, &error)) {
|
|
243
|
+
Napi::Error::New(env, error).ThrowAsJavaScriptException();
|
|
244
|
+
return env.Undefined();
|
|
69
245
|
}
|
|
246
|
+
return WrapResult(env, &result);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/* ---- async API (libuv thread pool; never blocks the event loop) --------- */
|
|
250
|
+
|
|
251
|
+
Napi::Value RejectedPromise(Napi::Env env, const Napi::Error& error) {
|
|
252
|
+
auto deferred = Napi::Promise::Deferred::New(env);
|
|
253
|
+
deferred.Reject(error.Value());
|
|
254
|
+
return deferred.Promise();
|
|
255
|
+
}
|
|
70
256
|
|
|
71
|
-
|
|
72
|
-
|
|
257
|
+
Napi::Value CompressAsync(const Napi::CallbackInfo& info) {
|
|
258
|
+
Napi::Env env = info.Env();
|
|
73
259
|
|
|
74
|
-
|
|
75
|
-
if (
|
|
76
|
-
return
|
|
260
|
+
std::string error;
|
|
261
|
+
if (!ValidateInputBuffer(info, &error)) {
|
|
262
|
+
return RejectedPromise(env, Napi::TypeError::New(env, error));
|
|
77
263
|
}
|
|
78
264
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
265
|
+
auto* worker = new CompressWorker(env, info[0].As<Napi::Buffer<char>>());
|
|
266
|
+
Napi::Promise promise = worker->Promise();
|
|
267
|
+
worker->Queue();
|
|
268
|
+
return promise;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
Napi::Value DecompressAsync(const Napi::CallbackInfo& info) {
|
|
272
|
+
Napi::Env env = info.Env();
|
|
273
|
+
|
|
274
|
+
std::string error;
|
|
275
|
+
bool rangeError = false;
|
|
276
|
+
size_t expectedLength = 0;
|
|
277
|
+
if (!ValidateInputBuffer(info, &error)) {
|
|
278
|
+
return RejectedPromise(env, Napi::TypeError::New(env, error));
|
|
279
|
+
}
|
|
280
|
+
if (!ValidateExpectedLength(info, &expectedLength, &error, &rangeError)) {
|
|
281
|
+
if (rangeError) return RejectedPromise(env, Napi::RangeError::New(env, error));
|
|
282
|
+
return RejectedPromise(env, Napi::TypeError::New(env, error));
|
|
283
|
+
}
|
|
86
284
|
|
|
87
|
-
info.
|
|
285
|
+
auto* worker = new DecompressWorker(env, info[0].As<Napi::Buffer<char>>(), expectedLength);
|
|
286
|
+
Napi::Promise promise = worker->Promise();
|
|
287
|
+
worker->Queue();
|
|
288
|
+
return promise;
|
|
88
289
|
}
|
|
89
290
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
291
|
+
Napi::Object Init(Napi::Env env, Napi::Object exports) {
|
|
292
|
+
exports.Set("compress", Napi::Function::New(env, Compress));
|
|
293
|
+
exports.Set("decompress", Napi::Function::New(env, Decompress));
|
|
294
|
+
exports.Set("compressAsync", Napi::Function::New(env, CompressAsync));
|
|
295
|
+
exports.Set("decompressAsync", Napi::Function::New(env, DecompressAsync));
|
|
296
|
+
return exports;
|
|
93
297
|
}
|
|
94
298
|
|
|
95
|
-
|
|
299
|
+
} // namespace
|
|
300
|
+
|
|
301
|
+
NODE_API_MODULE(lzf, Init)
|
package/benchmark/benchmark.js
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
var lzf = require("../index.js");
|
|
2
|
-
var zlib = require("compress-buffer");
|
|
3
|
-
var fs = require("fs");
|
|
4
|
-
var path = require("path");
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
var Benchmark = require('benchmark');
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
function testCompression(length) {
|
|
11
|
-
var data = fs.readFileSync(path.join(__dirname, "data", length + ".txt"));
|
|
12
|
-
var suite = new Benchmark.Suite();
|
|
13
|
-
|
|
14
|
-
console.log("Testing compression at " + length + " bytes");
|
|
15
|
-
|
|
16
|
-
suite.add('lzf-compress', function() {
|
|
17
|
-
lzf.compress(data);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
suite.add('zlib-compress', function() {
|
|
21
|
-
zlib.compress(data);
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
suite.on('cycle', function(event, bench) {
|
|
25
|
-
console.log(String(bench));
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
suite.on('complete', function() {
|
|
29
|
-
console.log('Fastest is ' + this.filter('fastest').pluck('name'));
|
|
30
|
-
console.log();
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
suite.run();
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function testDecompression(length) {
|
|
37
|
-
var data = fs.readFileSync(path.join(__dirname, "data", length + ".txt"));
|
|
38
|
-
var suite = new Benchmark.Suite();
|
|
39
|
-
var lzfCompressed = lzf.compress(data);
|
|
40
|
-
var zlibCompressed = zlib.compress(data);
|
|
41
|
-
|
|
42
|
-
console.log("Testing decompression at " + length + " bytes");
|
|
43
|
-
|
|
44
|
-
suite.add('lzf-decompress', function() {
|
|
45
|
-
lzf.decompress(lzfCompressed);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
suite.add('zlib-decompress', function() {
|
|
49
|
-
zlib.uncompress(zlibCompressed);
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
suite.on('cycle', function(event, bench) {
|
|
53
|
-
console.log(String(bench));
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
suite.on('complete', function() {
|
|
57
|
-
console.log('Fastest is ' + this.filter('fastest').pluck('name'));
|
|
58
|
-
console.log();
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
suite.run();
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
for (var i = 0; i < 4; i++) {
|
|
65
|
-
var length = Math.pow(10, i + 2);
|
|
66
|
-
testCompression(length);
|
|
67
|
-
testDecompression(length);
|
|
68
|
-
}
|
|
69
|
-
|
package/benchmark/data/100.txt
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur vitae eros lorem. Duis cras amet.
|
package/benchmark/data/1000.txt
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum congue sem sed arcu fermentum suscipit. Cras eleifend purus sollicitudin enim condimentum molestie. Aliquam elementum arcu libero. Sed blandit quam luctus sapien ultricies dignissim. Aliquam blandit congue lorem at suscipit. Nulla eleifend volutpat mauris nec cursus. Sed sit amet lectus lorem. Sed tincidunt nunc nec dolor pulvinar imperdiet. Cras tincidunt lectus in orci sodales id congue felis condimentum. In ultricies, magna at viverra volutpat, tortor ante semper mauris, dignissim suscipit nisi risus a nulla.
|
|
2
|
-
|
|
3
|
-
Quisque nec urna nibh, ut molestie eros. Nunc lobortis pharetra vestibulum. Mauris facilisis tincidunt turpis, nec condimentum nisi vestibulum ac. Nullam sed odio sed arcu malesuada scelerisque. In hac habitasse platea dictumst. Phasellus risus odio, mollis sed interdum nec, commodo vel est. In porta euismod urna in pulvinar. Fusce suscipit vulputate odio vel venenatis. Vestibulum ante ipsum primis in cras amet.
|
package/benchmark/data/10000.txt
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec augue nibh, vitae sagittis mi. Suspendisse elementum dapibus eros nec varius. Ut mollis varius sapien, eget vehicula ipsum ultrices non. Nullam ac erat lectus. Quisque ultricies iaculis ipsum, eget suscipit eros venenatis non. Duis mattis justo in erat volutpat varius. Sed vitae lobortis odio.
|
|
2
|
-
|
|
3
|
-
Vestibulum posuere risus quis nisl vehicula adipiscing. Ut vitae mi et urna ultricies egestas ut ut est. Nam lobortis placerat dui, et imperdiet lacus aliquet imperdiet. Sed dapibus nisl ipsum, ac dignissim erat. Nam et nisl vitae nisl egestas vehicula. Vestibulum eget lobortis justo. Etiam laoreet pretium accumsan. Proin dapibus nisi vitae erat dapibus quis ultrices enim sollicitudin.
|
|
4
|
-
|
|
5
|
-
Mauris eu sem dui. Integer dignissim mollis massa, ac pharetra enim bibendum ut. Sed tempor quam vitae est aliquam rutrum. Duis aliquet cursus nisi non vestibulum. Sed ac sapien tortor, sed scelerisque enim. Suspendisse odio velit, dapibus nec posuere non, faucibus non nisl. Etiam dignissim sodales nibh ut commodo. Pellentesque non est sed mi elementum sagittis et eget odio.
|
|
6
|
-
|
|
7
|
-
Morbi feugiat dictum mollis. Pellentesque ultricies diam quis nisi auctor vitae tristique risus euismod. Sed condimentum feugiat leo sed euismod. Quisque pretium nunc porta arcu viverra convallis quis fringilla arcu. Nam facilisis, lorem a aliquet faucibus, neque elit bibendum erat, eget bibendum ipsum ante et purus. Cras est tellus, vestibulum vitae rutrum vel, ultrices quis sapien. Donec fringilla vehicula eros ac tincidunt. Nulla imperdiet, neque eget posuere aliquam, tortor magna tempus tortor, nec sodales libero turpis eget risus.
|
|
8
|
-
|
|
9
|
-
Vivamus auctor ligula nec turpis consectetur euismod. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur turpis tellus, pharetra in lobortis ac, semper sit amet turpis. Quisque dolor est, pulvinar a porttitor non, suscipit ut magna. Suspendisse eget arcu id urna eleifend ullamcorper sit amet id eros. Praesent tincidunt rhoncus tristique. Cras tempor adipiscing arcu eu posuere. Proin vulputate, enim sit amet volutpat facilisis, mi quam venenatis nulla, vitae varius ligula nibh non massa. Sed feugiat nibh et ipsum mollis ac porta urna auctor. Donec mauris mauris, elementum a sodales in, ultricies at tortor. Aenean commodo facilisis euismod. Integer sed urna at tortor cursus ultricies id a ante. In aliquam velit sit amet diam consequat egestas.
|
|
10
|
-
|
|
11
|
-
Vivamus ut dui ante, ut posuere turpis. Sed ornare risus quam. Aliquam sit amet ligula felis, ultrices sagittis mauris. Aenean faucibus molestie quam sodales molestie. Cras tincidunt sagittis purus, sed convallis sapien semper ut. Suspendisse luctus dapibus ante at ultricies. Nam at lacus orci. Aliquam mattis, velit in accumsan mattis, metus nisl mattis est, ut tincidunt sapien elit sit amet eros. Cras tempus ultrices feugiat.
|
|
12
|
-
|
|
13
|
-
In rhoncus lectus id lorem feugiat eu pulvinar metus scelerisque. Etiam a erat eget dolor facilisis luctus. Pellentesque at odio pretium nisi adipiscing laoreet. Etiam non justo ligula. Nunc mauris sapien, dictum tempor sodales non, pharetra congue mi. Mauris at lacus eu arcu scelerisque varius et ut augue. In consequat justo vitae ante condimentum euismod.
|
|
14
|
-
|
|
15
|
-
Aliquam molestie bibendum malesuada. Curabitur scelerisque, augue a bibendum vestibulum, justo massa mattis est, a ullamcorper velit ligula faucibus ligula. Donec sit amet nibh sed nibh malesuada dictum ut ut lectus. Fusce adipiscing urna felis, sed pharetra sapien. Suspendisse potenti. Aenean auctor orci commodo tellus sollicitudin dignissim. Donec posuere venenatis vulputate.
|
|
16
|
-
|
|
17
|
-
Mauris non ipsum turpis. Cras euismod, lectus sed commodo vulputate, lacus mi sodales risus, non sodales lorem justo sed erat. Mauris non adipiscing lorem. Phasellus at est quis metus auctor hendrerit. Cras sed purus erat, id dignissim elit. In sed est diam. Fusce id diam lorem, vel auctor nunc. Pellentesque mattis sollicitudin blandit. Phasellus vitae justo non sem gravida iaculis. Etiam cursus nisl nec sem mollis ac congue sapien pellentesque. In eu est urna.
|
|
18
|
-
|
|
19
|
-
Cras luctus bibendum feugiat. Sed varius, libero ornare dictum tempor, turpis quam mattis purus, nec pulvinar tellus odio nec metus. Pellentesque tempus vulputate fermentum. Proin porttitor viverra pretium. Donec interdum magna et augue vehicula non faucibus quam vehicula. Ut euismod, turpis eu vehicula gravida, augue ligula auctor nisl, non interdum felis mauris at nisi. Sed vulputate eleifend nisl, et consectetur sapien dignissim sit amet.
|
|
20
|
-
|
|
21
|
-
Proin elit est, congue vel sollicitudin ac, molestie sed justo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla facilisi. Duis est odio, sollicitudin a feugiat a, blandit eget felis. Vivamus vitae pharetra nisi. Vestibulum condimentum dui et ligula aliquam pretium. Nulla non dapibus metus. Suspendisse potenti. Aenean molestie hendrerit nulla, vel posuere nisi eleifend non. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed mauris dui, adipiscing quis vestibulum a, vestibulum ut lectus. Ut sit amet est nisl, a aliquam nulla. Nullam libero ipsum, consequat id pharetra sit amet, commodo at neque. Donec eget bibendum est.
|
|
22
|
-
|
|
23
|
-
Cras fermentum porttitor massa, nec convallis massa consequat at. Morbi eu vehicula orci. Aenean ultricies faucibus sapien eget dapibus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nunc in quam id leo interdum consectetur vitae interdum quam. Donec scelerisque purus et metus posuere eget viverra justo facilisis. Nam at eros sit amet sapien vehicula bibendum ut id enim. Vivamus rhoncus malesuada justo at ultricies. Nulla congue leo iaculis erat tempor tempor. Vivamus sagittis, elit ac faucibus tristique, leo odio adipiscing lorem, a volutpat lacus mi ac erat. Nulla facilisi. Nullam scelerisque auctor gravida. Proin a magna dolor. Morbi congue, nunc nec volutpat dictum, lorem odio consequat neque, vulputate egestas tortor elit eu neque.
|
|
24
|
-
|
|
25
|
-
Duis a nisi condimentum sem laoreet condimentum. Curabitur malesuada felis eget velit rutrum tincidunt. Nulla placerat laoreet placerat. Aliquam suscipit consequat elementum. Etiam pellentesque porttitor aliquam. Mauris non massa ut dui tincidunt sodales varius vitae eros. Quisque imperdiet aliquam orci, et suscipit metus facilisis vel.
|
|
26
|
-
|
|
27
|
-
Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum in massa eu augue lobortis volutpat non sit amet enim. Vestibulum quis ante tellus. Curabitur in arcu a ipsum commodo cursus. Pellentesque id lorem odio. Vivamus consequat purus in magna aliquet at tincidunt turpis varius. Praesent sed nunc quam, vel varius sem. Aenean eget vehicula massa. Aliquam posuere, massa non placerat molestie, magna orci aliquam justo, luctus ullamcorper ligula leo a quam.
|
|
28
|
-
|
|
29
|
-
Donec id leo sit amet nisl sollicitudin ultricies. Suspendisse blandit rutrum risus vel dictum. Duis tempus metus et risus ornare ut volutpat ligula ultrices. Proin accumsan tellus id felis elementum ornare. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis consequat justo at enim interdum a pretium justo suscipit. Nullam sit amet sapien placerat risus ultrices tincidunt.
|
|
30
|
-
|
|
31
|
-
Maecenas dignissim lacus non tortor scelerisque fringilla. Nulla facilisis diam non augue faucibus elementum. Maecenas vel magna lacus. Aliquam pretium semper dui, a fringilla ligula bibendum et. Pellentesque commodo metus id lectus lobortis eget feugiat enim scelerisque. Praesent accumsan iaculis ligula, et hendrerit sapien ultricies quis. In congue mauris a odio facilisis porttitor. Fusce vitae facilisis magna. Nam urna erat, feugiat at bibendum a, pretium a massa.
|
|
32
|
-
|
|
33
|
-
Suspendisse arcu lectus, sollicitudin nec ultrices eu, venenatis sit amet nulla. Quisque consequat tortor sed ligula tempor tristique. Cras ipsum dolor, congue vitae hendrerit eget, ornare eget metus. Suspendisse potenti. Morbi rhoncus rhoncus velit, et ultrices mi condimentum sed. Nullam metus justo, tempor a vestibulum eu, pellentesque in enim. Curabitur scelerisque, est non congue iaculis, magna lorem pretium nisl, ac aliquet nibh neque eu augue. Etiam vel arcu ut urna rutrum imperdiet. Aliquam semper nulla eget mi vulputate ac ornare tellus suscipit. Nunc vitae risus ac elit rutrum sodales vitae et velit. Duis in nibh a mi pharetra pulvinar. Nunc egestas, turpis vel ullamcorper luctus, nulla ligula ullamcorper dolor, accumsan egestas quam purus nec nisi. Donec sit amet dolor non dui semper euismod vitae non lectus. Vestibulum vel urna vel diam dignissim bibendum. Sed non justo in urna dignissim laoreet. Nulla rhoncus auctor blandit.
|
|
34
|
-
|
|
35
|
-
Suspendisse leo enim, dictum ut malesuada in, tempus sed purus. Integer commodo rutrum nisl id ullamcorper. Fusce imperdiet felis vel mauris imperdiet eget volutpat nibh pretium. Integer sit amet ipsum id nunc ullamcorper gravida ac facilisis purus. Etiam non enim purus, vel sagittis felis. Aliquam erat volutpat. Nunc eget ante eu magna egestas fringilla. Vivamus vel sem felis. Nullam tincidunt sapien vel nunc ullamcorper non feugiat turpis molestie.
|
|
36
|
-
|
|
37
|
-
Donec mattis faucibus quam non fermentum. Aenean volutpat leo et metus gravida accumsan. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec eleifend dui et ipsum tempus dictum. Sed eget nisl sit amet nisi sollicitudin adipiscing nec ac turpis. Suspendisse potenti. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce laoreet lacus vel mi tempor convallis. Aenean viverra auctor lobortis.
|
|
38
|
-
|
|
39
|
-
Nunc consectetur mattis dui, quis fermentum lectus feugiat tincidunt. Fusce tempus quam in dui malesuada quis semper ante tempus. Aliquam eget turpis et neque facilisis ornare. Sed rutrum, sem et euismod aliquam, arcu dolor bibendum erat, quis rutrum elit leo vel massa. Nam felis ipsum, varius in posuere id, interdum vel posuere.
|