Skip to content

Commit bdc2b07

Browse files
authored
Streams of JSON documents + Large files (>4GB) (simdjson#350) (simdjson#364)
* rough prototype working. Needs more test and fine tuning. * prototype working on large files. * prototype working on large files. * Adding benchmarks * jsonstream API adjustment * type * minor fixes and cleaning. * minor fixes and cleaning. * removing warnings * removing some copies * runtime dispatch error fix * makefile linking src/jsonstream.cpp * fixing arm stage 1 headers * fixing stage 2 headers * fixing stage 1 arm header * making jsonstream portable * cleaning imports * including <algorithms> for windows compiler * cleaning benchmark imports * adding jsonstream to amalgamation * merged main into branch * bug fix where JsonStream would bug on rare cases. * Addind a JsonStream Demo to Amalgamation * Fix for simdjson#345 * Follow up test and fix for simdjson#345 (simdjson#347) * Final (?) fix for simdjson#345 * Verbose basictest * Being more forgiving of powers of ten. * Let us zero the tail end. * add basic fuzzers (simdjson#348) * add basic fuzzing using libFuzzer * let cmake respect cflags, otherwise the fuzzer flags go unnoticed also, integrates badly with oss-fuzz * add new fuzzer for minification, simplify the old one * add fuzzer for the dump example * clang format * adding Paul Dreik * rough prototype working. Needs more test and fine tuning. * prototype working on large files. * prototype working on large files. * Adding benchmarks * jsonstream API adjustment * type * minor fixes and cleaning. * Fixing issue 351 (simdjson#352) * Fixing issues 351 and 353 * minor fixes and cleaning. * removing warnings * removing some copies * Fix ARM compile errors on g++ 7.4 (simdjson#354) * Fix ARM compilation errors * Update singleheader * runtime dispatch error fix * makefile linking src/jsonstream.cpp * fixing arm stage 1 headers * fixing stage 2 headers * fixing stage 1 arm header * fix integer overflow in subnormal_power10 (simdjson#355) detected by oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18714 * Adding new test file, following simdjson#355 * making jsonstream portable * cleaning imports * including <algorithms> for windows compiler * cleaning benchmark imports * adding jsonstream to amalgamation * merged main into branch * bug fix where JsonStream would bug on rare cases. * Addind a JsonStream Demo to Amalgamation * merging main * rough prototype working. Needs more test and fine tuning. * prototype working on large files. * prototype working on large files. * Adding benchmarks * jsonstream API adjustment * minor fixes and cleaning. * minor fixes and cleaning. * removing warnings * removing some copies * runtime dispatch error fix * makefile linking src/jsonstream.cpp * fixing arm stage 1 headers * fixing stage 2 headers * fixing stage 1 arm header * making jsonstream portable * cleaning imports * including <algorithms> for windows compiler * cleaning benchmark imports * adding jsonstream to amalgamation * bug fix where JsonStream would bug on rare cases. * Addind a JsonStream Demo to Amalgamation * rough prototype working. Needs more test and fine tuning. * minor fixes and cleaning. * adding jsonstream to amalgamation * merged main into branch * Addind a JsonStream Demo to Amalgamation * merging main * merging main * make file fix
1 parent 6888ca7 commit bdc2b07

29 files changed

Lines changed: 5137 additions & 1043 deletions

Makefile

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,16 @@ endif # ifeq ($(SANITIZE),1)
5959
endif # ifeq ($(MEMSANITIZE),1)
6060

6161
MAINEXECUTABLES=parse minify json2json jsonstats statisticalmodel jsonpointer
62-
TESTEXECUTABLES=jsoncheck jsoncheck_noavx integer_tests numberparsingcheck stringparsingcheck pointercheck
62+
TESTEXECUTABLES=jsoncheck jsoncheck_noavx integer_tests numberparsingcheck stringparsingcheck pointercheck jsonstream_test
6363
COMPARISONEXECUTABLES=minifiercompetition parsingcompetition parseandstatcompetition distinctuseridcompetition allparserscheckfile allparsingcompetition
6464
SUPPLEMENTARYEXECUTABLES=parse_noutf8validation parse_nonumberparsing parse_nostringparsing
6565

6666
# Load headers and sources
67-
LIBHEADERS=src/simdprune_tables.h src/numberparsing.h src/jsoncharutils.h src/arm64/bitmask.h src/arm64/simd.h src/arm64/stage1_find_marks.h src/arm64/stage2_build_tape.h src/arm64/stringparsing.h src/generic/stage1_find_marks.h src/generic/stage2_build_tape.h src/generic/stringparsing.h src/haswell/bitmask.h src/haswell/simd.h src/generic/simdutf8check.h src/haswell/stage1_find_marks.h src/haswell/stage2_build_tape.h src/haswell/stringparsing.h src/westmere/bitmask.h src/westmere/simd.h src/westmere/stage1_find_marks.h src/westmere/stage2_build_tape.h src/westmere/stringparsing.h
67+
LIBHEADERS=src/simdprune_tables.h src/numberparsing.h src/jsoncharutils.h src/arm64/bitmask.h src/arm64/simd.h src/arm64/stage1_find_marks.h src/arm64/stage2_build_tape.h src/arm64/stringparsing.h src/generic/stage1_find_marks.h src/generic/stage2_build_tape.h src/generic/stringparsing.h src/haswell/bitmask.h src/haswell/simd.h src/generic/simdutf8check.h src/haswell/stage1_find_marks.h src/haswell/stage2_build_tape.h src/haswell/stringparsing.h src/westmere/bitmask.h src/westmere/simd.h src/westmere/stage1_find_marks.h src/westmere/stage2_build_tape.h src/westmere/stringparsing.h src/generic/stage2_streaming_build_tape.h
6868
PUBHEADERS=include/simdjson/common_defs.h include/simdjson/isadetection.h include/simdjson/jsonformatutils.h include/simdjson/jsonioutil.h include/simdjson/jsonminifier.h include/simdjson/jsonparser.h include/simdjson/padded_string.h include/simdjson/parsedjson.h include/simdjson/parsedjsoniterator.h include/simdjson/portability.h include/simdjson/simdjson.h include/simdjson/simdjson_version.h include/simdjson/stage1_find_marks.h include/simdjson/stage2_build_tape.h
6969
HEADERS=$(PUBHEADERS) $(LIBHEADERS)
7070

71-
LIBFILES=src/jsonioutil.cpp src/jsonparser.cpp src/simdjson.cpp src/stage1_find_marks.cpp src/stage2_build_tape.cpp src/parsedjson.cpp src/parsedjsoniterator.cpp
71+
LIBFILES=src/jsonioutil.cpp src/jsonparser.cpp src/jsonstream.cpp src/simdjson.cpp src/stage1_find_marks.cpp src/stage2_build_tape.cpp src/parsedjson.cpp src/parsedjsoniterator.cpp
7272
MINIFIERHEADERS=include/simdjson/jsonminifier.h
7373
MINIFIERLIBFILES=src/jsonminifier.cpp
7474

@@ -111,6 +111,9 @@ run_stringparsingcheck: stringparsingcheck
111111
run_jsoncheck: jsoncheck
112112
./jsoncheck
113113

114+
run_jsonstream_test: jsonstream_test
115+
./jsonstream_test
116+
114117
run_jsoncheck_noavx: jsoncheck_noavx
115118
./jsoncheck_noavx
116119

@@ -123,12 +126,12 @@ run_issue150_sh: allparserscheckfile
123126
run_testjson2json_sh: minify json2json
124127
./scripts/testjson2json.sh
125128

126-
test: run_basictests run_jsoncheck run_numberparsingcheck run_integer_tests run_stringparsingcheck run_pointercheck run_testjson2json_sh run_issue150_sh run_jsoncheck_noavx
129+
test: run_basictests run_jsoncheck run_numberparsingcheck run_integer_tests run_stringparsingcheck run_jsonstream_test run_pointercheck run_testjson2json_sh run_issue150_sh run_jsoncheck_noavx
127130
@echo "It looks like the code is good!"
128131

129-
quiettest: run_basictests run_jsoncheck run_numberparsingcheck run_integer_tests run_stringparsingcheck run_pointercheck run_testjson2json_sh run_issue150_sh run_jsoncheck_noavx
132+
quiettest: run_basictests run_jsoncheck run_numberparsingcheck run_integer_tests run_stringparsingcheck run_jsoncheck run_jsonstream_test run_pointercheck run_testjson2json_sh run_issue150_sh run_jsoncheck_noavx
130133

131-
quicktests: run_basictests run_jsoncheck run_numberparsingcheck run_integer_tests run_stringparsingcheck run_pointercheck run_jsoncheck_noavx
134+
quicktests: run_basictests run_jsoncheck run_numberparsingcheck run_integer_tests run_stringparsingcheck run_jsoncheck run_jsonstream_test run_pointercheck run_jsoncheck_noavx
132135

133136
slowtests: run_testjson2json_sh run_issue150_sh
134137

@@ -168,6 +171,9 @@ parse_nostringparsing: benchmark/parse.cpp $(HEADERS) $(LIBFILES)
168171
jsoncheck:tests/jsoncheck.cpp $(HEADERS) $(LIBFILES)
169172
$(CXX) $(CXXFLAGS) -o jsoncheck $(LIBFILES) tests/jsoncheck.cpp -I. $(LIBFLAGS)
170173

174+
jsonstream_test:tests/jsonstream_test.cpp $(HEADERS) $(LIBFILES)
175+
$(CXX) $(CXXFLAGS) -o jsonstream_test $(LIBFILES) tests/jsonstream_test.cpp -I. $(LIBFLAGS)
176+
171177

172178
jsoncheck_noavx:tests/jsoncheck.cpp $(HEADERS) $(LIBFILES)
173179
$(CXX) $(CXXFLAGS) -o jsoncheck_noavx $(LIBFILES) tests/jsoncheck.cpp -I. $(LIBFLAGS) -DSIMDJSON_DISABLE_AVX2_DETECTION

amalgamation.sh

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ $SCRIPTPATH/src/simdjson.cpp
2020
$SCRIPTPATH/src/jsonioutil.cpp
2121
$SCRIPTPATH/src/jsonminifier.cpp
2222
$SCRIPTPATH/src/jsonparser.cpp
23+
$SCRIPTPATH/src/jsonstream.cpp
2324
$SCRIPTPATH/src/arm64/bitmask.h
2425
$SCRIPTPATH/src/haswell/bitmask.h
2526
$SCRIPTPATH/src/westmere/bitmask.h
@@ -57,6 +58,7 @@ $SCRIPTPATH/include/simdjson/parsedjsoniterator.h
5758
$SCRIPTPATH/include/simdjson/stage1_find_marks.h
5859
$SCRIPTPATH/include/simdjson/stage2_build_tape.h
5960
$SCRIPTPATH/include/simdjson/jsonparser.h
61+
$SCRIPTPATH/include/simdjson/jsonstream.h
6062
"
6163

6264
for i in ${ALLCHEADERS} ${ALLCFILES}; do
@@ -134,17 +136,36 @@ cat <<< '
134136
#include "simdjson.h"
135137
#include "simdjson.cpp"
136138
int main(int argc, char *argv[]) {
137-
if(argc < 2) {
138-
std::cerr << "Please specify a filename " << std::endl;
139+
if(argc < 3) {
140+
std::cerr << "Please specify filenames " << std::endl;
139141
}
140142
const char * filename = argv[1];
141143
simdjson::padded_string p = simdjson::get_corpus(filename);
142144
simdjson::ParsedJson pj = simdjson::build_parsed_json(p); // do the parsing
143145
if( ! pj.is_valid() ) {
144-
std::cout << "not valid" << std::endl;
146+
std::cout << "build_parsed_json not valid" << std::endl;
145147
} else {
146-
std::cout << "valid" << std::endl;
148+
std::cout << "build_parsed_json valid" << std::endl;
147149
}
150+
151+
//JsonStream
152+
const char * filename2 = argv[2];
153+
simdjson::padded_string p2 = simdjson::get_corpus(filename2);
154+
simdjson::ParsedJson pj2;
155+
simdjson::JsonStream js{p2.data(), p2.size()};
156+
int parse_res = simdjson::SUCCESS_AND_HAS_MORE;
157+
158+
while (parse_res == simdjson::SUCCESS_AND_HAS_MORE) {
159+
parse_res = js.json_parse(pj2);
160+
}
161+
162+
if( ! pj2.is_valid()) {
163+
std::cout << "JsonStream not valid" << std::endl;
164+
} else {
165+
std::cout << "JsonStream valid" << std::endl;
166+
}
167+
168+
148169
return EXIT_SUCCESS;
149170
}
150171
' >> "${DEMOCPP}"
@@ -160,16 +181,16 @@ echo "Giving final instructions:"
160181
CPPBIN=${DEMOCPP%%.*}
161182

162183
echo "Try :"
163-
echo "c++ -O3 -std=c++17 -o ${CPPBIN} ${DEMOCPP} && ./${CPPBIN} ../jsonexamples/twitter.json "
184+
echo "c++ -O3 -std=c++17 -o ${CPPBIN} ${DEMOCPP} && ./${CPPBIN} ../jsonexamples/twitter.json ../jsonexamples/amazon_cellphones.ndjson"
164185

165186
SINGLEHDR=$SCRIPTPATH/singleheader
166187
echo "Copying files to $SCRIPTPATH/singleheader "
167188
mkdir -p $SINGLEHDR
168-
echo "c++ -O3 -std=c++17 -o ${CPPBIN} ${DEMOCPP} && ./${CPPBIN} ../jsonexamples/twitter.json " > $SINGLEHDR/README.md
189+
echo "c++ -O3 -std=c++17 -o ${CPPBIN} ${DEMOCPP} && ./${CPPBIN} ../jsonexamples/twitter.json ../jsonexamples/amazon_cellphones.ndjson" > $SINGLEHDR/README.md
169190
cp ${AMAL_C} ${AMAL_H} ${DEMOCPP} $SINGLEHDR
170191
ls $SINGLEHDR
171192

172-
cd $SINGLEHDR && c++ -O3 -std=c++17 -o ${CPPBIN} ${DEMOCPP} && ./${CPPBIN} ../jsonexamples/twitter.json
193+
cd $SINGLEHDR && c++ -O3 -std=c++17 -o ${CPPBIN} ${DEMOCPP} && ./${CPPBIN} ../jsonexamples/twitter.json ../jsonexamples/amazon_cellphones.ndjson
173194

174195
lowercase(){
175196
echo "$1" | tr 'A-Z' 'a-z'

benchmark/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ target_include_directories(${SIMDJSON_LIB_NAME}
66

77
add_cpp_benchmark(parse)
88
add_cpp_benchmark(statisticalmodel)
9+
add_cpp_benchmark(parse_stream)
910
add_executable(perfdiff perfdiff.cpp)

benchmark/parse_stream.cpp

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
#include <iostream>
2+
#include <algorithm>
3+
#include <chrono>
4+
#include <vector>
5+
#include "simdjson/jsonstream.h"
6+
#include <map>
7+
#include "simdjson/jsonparser.h"
8+
#include "simdjson/parsedjson.h"
9+
10+
#define NB_ITERATION 5
11+
#define MIN_BATCH_SIZE 100000
12+
#define MAX_BATCH_SIZE 10000000
13+
14+
bool test_baseline = false;
15+
bool test_per_batch = true;
16+
bool test_best_batch = true;
17+
18+
bool compare(std::pair<size_t, double> i, std::pair<size_t, double> j){
19+
return i.second > j.second;
20+
}
21+
22+
int main (int argc, char *argv[]){
23+
24+
if (argc <= 1) {
25+
std::cerr << "Usage: " << argv[0] << " <jsonfile>" << std::endl;
26+
exit(1);
27+
}
28+
const char *filename = argv[1];
29+
simdjson::padded_string p;
30+
try {
31+
std::wclog << "loading " << filename << "\n" << std::endl;
32+
simdjson::get_corpus(filename).swap(p);
33+
} catch (const std::exception &) { // caught by reference to base
34+
std::cerr << "Could not load the file " << filename << std::endl;
35+
return EXIT_FAILURE;
36+
}
37+
if (test_baseline) {
38+
std::wclog << "Baseline: Getline + normal parse... " << std::endl;
39+
std::cout << "Gigabytes/second\t" << "Nb of documents parsed" << std::endl;
40+
for (auto i = 0; i < 3; i++) {
41+
//Actual test
42+
simdjson::ParsedJson pj;
43+
bool allocok = pj.allocate_capacity(p.size());
44+
if (!allocok) {
45+
std::cerr << "failed to allocate memory" << std::endl;
46+
return EXIT_FAILURE;
47+
}
48+
std::istringstream ss(std::string(p.data(), p.size()));
49+
50+
auto start = std::chrono::steady_clock::now();
51+
int count = 0;
52+
std::string line;
53+
int parse_res = simdjson::SUCCESS;
54+
while (getline(ss, line)) {
55+
parse_res = simdjson::json_parse(line, pj);
56+
count++;
57+
}
58+
59+
auto end = std::chrono::steady_clock::now();
60+
61+
std::chrono::duration<double> secs = end - start;
62+
double speedinGBs = (p.size()) / (secs.count() * 1000000000.0);
63+
std::cout << speedinGBs << "\t\t\t\t" << count << std::endl;
64+
65+
if (parse_res != simdjson::SUCCESS) {
66+
std::cerr << "Parsing failed" << std::endl;
67+
exit(1);
68+
}
69+
}
70+
}
71+
72+
std::map<size_t, double> batch_size_res;
73+
if(test_per_batch) {
74+
std::wclog << "Jsonstream: Speed per batch_size... from " << MIN_BATCH_SIZE
75+
<< " bytes to " << MAX_BATCH_SIZE << " bytes..." << std::endl;
76+
std::cout << "Batch Size\t" << "Gigabytes/second\t" << "Nb of documents parsed" << std::endl;
77+
for (size_t i = MIN_BATCH_SIZE; i <= MAX_BATCH_SIZE; i += (MAX_BATCH_SIZE - MIN_BATCH_SIZE) / 200) {
78+
batch_size_res.insert(std::pair<size_t, double>(i, 0));
79+
int count;
80+
for (size_t j = 0; j < 5; j++) {
81+
//Actual test
82+
simdjson::ParsedJson pj;
83+
simdjson::JsonStream js{p.data(), p.size(), i};
84+
int parse_res = simdjson::SUCCESS_AND_HAS_MORE;
85+
86+
auto start = std::chrono::steady_clock::now();
87+
count = 0;
88+
while (parse_res == simdjson::SUCCESS_AND_HAS_MORE) {
89+
parse_res = js.json_parse(pj);
90+
count++;
91+
}
92+
93+
auto end = std::chrono::steady_clock::now();
94+
95+
std::chrono::duration<double> secs = end - start;
96+
double speedinGBs = (p.size()) / (secs.count() * 1000000000.0);
97+
if (speedinGBs > batch_size_res.at(i))
98+
batch_size_res[i] = speedinGBs;
99+
100+
if (parse_res != simdjson::SUCCESS) {
101+
std::wcerr << "Parsing failed with: " << simdjson::error_message(parse_res).c_str() << std::endl;
102+
exit(1);
103+
}
104+
}
105+
std::cout << i << "\t\t" << batch_size_res.at(i) << "\t\t\t\t" << count << std::endl;
106+
107+
}
108+
}
109+
if(test_best_batch) {
110+
size_t optimal_batch_size;
111+
if(test_per_batch)
112+
optimal_batch_size = (*min_element(batch_size_res.begin(), batch_size_res.end(), compare)).first;
113+
else
114+
optimal_batch_size = MIN_BATCH_SIZE;
115+
std::wclog << "Starting speed test... Best of " << NB_ITERATION << " iterations..." << std::endl;
116+
std::wclog << "Seemingly optimal batch_size: " << optimal_batch_size << "..." << std::endl;
117+
std::vector<double> res;
118+
for (int i = 0; i < NB_ITERATION; i++) {
119+
120+
//Actual test
121+
simdjson::ParsedJson pj;
122+
simdjson::JsonStream js{p.data(), p.size(), 4000000};
123+
int parse_res = simdjson::SUCCESS_AND_HAS_MORE;
124+
125+
auto start = std::chrono::steady_clock::now();
126+
127+
while (parse_res == simdjson::SUCCESS_AND_HAS_MORE) {
128+
parse_res = js.json_parse(pj);
129+
}
130+
131+
132+
auto end = std::chrono::steady_clock::now();
133+
134+
std::chrono::duration<double> secs = end - start;
135+
res.push_back(secs.count());
136+
137+
if (parse_res != simdjson::SUCCESS) {
138+
std::cerr << "Parsing failed" << std::endl;
139+
exit(1);
140+
}
141+
142+
}
143+
144+
std::min(res.begin(), res.end());
145+
146+
double min_result = *min_element(res.begin(), res.end());
147+
double speedinGBs = (p.size()) / (min_result * 1000000000.0);
148+
149+
150+
std::cout << "Min: " << min_result << " bytes read: " << p.size()
151+
<< " Gigabytes/second: " << speedinGBs << std::endl;
152+
}
153+
154+
155+
156+
return 0;
157+
}

include/simdjson/jsonstream.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#ifndef SIMDJSON_JSONSTREAM_H
2+
#define SIMDJSON_JSONSTREAM_H
3+
4+
5+
#include <algorithm>
6+
#include "simdjson/stage1_find_marks.h"
7+
#include "simdjson/stage2_build_tape.h"
8+
#include "simdjson/simdjson.h"
9+
10+
namespace simdjson {
11+
12+
class JsonStream {
13+
public:
14+
JsonStream(const char *buf, size_t len, size_t batch_size = 1000000);
15+
16+
JsonStream(const std::string &s, size_t batch_size = 1000000) : JsonStream(s.data(), s.size(), batch_size) {};
17+
18+
int json_parse(ParsedJson &pj);
19+
20+
void set_new_buffer(const char *buf, size_t len);
21+
22+
void set_new_buffer(const std::string &s) { set_new_buffer(s.data(), s.size()); }
23+
24+
size_t get_current_buffer_loc() const;
25+
26+
size_t get_n_parsed_docs() const;
27+
28+
size_t get_n_bytes_parsed() const;
29+
30+
private:
31+
const char *_buf;
32+
size_t _len;
33+
size_t _batch_size;
34+
size_t next_json{0};
35+
bool error_on_last_attempt{false};
36+
bool load_next_batch{true};
37+
size_t current_buffer_loc{0};
38+
size_t n_parsed_docs{0};
39+
size_t n_bytes_parsed{0};
40+
};
41+
42+
}
43+
#endif //SIMDJSON_JSONSTREAM_H

include/simdjson/simdjson.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ enum class Architecture {
2222

2323
enum ErrorValues {
2424
SUCCESS = 0,
25+
SUCCESS_AND_HAS_MORE, //No errors and buffer still has more data
2526
CAPACITY, // This ParsedJson can't support a document that big
2627
MEMALLOC, // Error allocating memory, most likely out of memory
2728
TAPE_ERROR, // Something went wrong while writing to the tape (stage 2), this

include/simdjson/stage1_find_marks.h

100644100755
Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,21 @@
77
namespace simdjson {
88

99
template <Architecture T = Architecture::NATIVE>
10-
int find_structural_bits(const uint8_t *buf, size_t len, simdjson::ParsedJson &pj);
10+
int find_structural_bits(const uint8_t *buf, size_t len, simdjson::ParsedJson &pj, bool streaming);
11+
12+
template <Architecture T = Architecture::NATIVE>
13+
int find_structural_bits(const char *buf, size_t len, simdjson::ParsedJson &pj, bool streaming) {
14+
return find_structural_bits<T>((const uint8_t *)buf, len, pj, streaming);
15+
}
16+
17+
template <Architecture T = Architecture::NATIVE>
18+
int find_structural_bits(const uint8_t *buf, size_t len, simdjson::ParsedJson &pj){
19+
return find_structural_bits<T>((const uint8_t *)buf, len, pj, false);
20+
}
1121

1222
template <Architecture T = Architecture::NATIVE>
1323
int find_structural_bits(const char *buf, size_t len, simdjson::ParsedJson &pj) {
14-
return find_structural_bits((const uint8_t *)buf, len, pj);
24+
return find_structural_bits<T>((const uint8_t *)buf, len, pj, false);
1525
}
1626

1727
}; // namespace simdjson

include/simdjson/stage2_build_tape.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,19 @@ int unified_machine(const char *buf, size_t len, ParsedJson &pj) {
1818
return unified_machine<T>(reinterpret_cast<const uint8_t *>(buf), len, pj);
1919
}
2020

21+
22+
23+
// Streaming
24+
template <Architecture T = Architecture::NATIVE>
25+
WARN_UNUSED int
26+
unified_machine(const uint8_t *buf, size_t len, ParsedJson &pj, size_t &next_json);
27+
28+
template <Architecture T = Architecture::NATIVE>
29+
int unified_machine(const char *buf, size_t len, ParsedJson &pj, size_t &next_json) {
30+
return unified_machine<T>(reinterpret_cast<const uint8_t *>(buf), len, pj, next_json);
31+
}
32+
33+
2134
} // namespace simdjson
2235

2336
#endif

0 commit comments

Comments
 (0)