Skip to content

Commit d93af11

Browse files
committed
Remove set_capacity, replace with allocate
Makes allocation point more predictable
1 parent 434776d commit d93af11

10 files changed

+135
-149
lines changed

benchmark/bench_dom_api.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,6 @@ static void print_json(State& state) noexcept {
256256
// Prints the number of results in twitter.json
257257
padded_string json = get_corpus(JSON_TEST_PATH);
258258
dom::parser parser;
259-
if (!parser.allocate_capacity(json.length())) { cerr << "allocation failed" << endl; return; }
260259
if (int error = json_parse(json, parser); error != SUCCESS) { cerr << error_message(error) << endl; return; }
261260
for (auto _ : state) {
262261
std::stringstream s;

benchmark/bench_parse_call.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,18 @@ const padded_string EMPTY_ARRAY("[]", 2);
99
SIMDJSON_PUSH_DISABLE_WARNINGS
1010
SIMDJSON_DISABLE_DEPRECATED_WARNING
1111
static void json_parse(State& state) {
12-
dom::parser parser;
13-
if (parser.set_capacity(EMPTY_ARRAY.length())) { return; }
12+
ParsedJson pj;
13+
if (!pj.allocate_capacity(EMPTY_ARRAY.length())) { return; }
1414
for (auto _ : state) {
15-
auto error = simdjson::json_parse(EMPTY_ARRAY, parser);
15+
auto error = json_parse(EMPTY_ARRAY, pj);
1616
if (error) { return; }
1717
}
1818
}
1919
SIMDJSON_POP_DISABLE_WARNINGS
2020
BENCHMARK(json_parse);
2121
static void parser_parse_error_code(State& state) {
2222
dom::parser parser;
23-
if (parser.set_capacity(EMPTY_ARRAY.length())) { return; }
23+
if (parser.allocate(EMPTY_ARRAY.length())) { return; }
2424
for (auto _ : state) {
2525
auto [doc, error] = parser.parse(EMPTY_ARRAY);
2626
if (error) { return; }
@@ -29,7 +29,7 @@ static void parser_parse_error_code(State& state) {
2929
BENCHMARK(parser_parse_error_code);
3030
static void parser_parse_exception(State& state) {
3131
dom::parser parser;
32-
if (parser.set_capacity(EMPTY_ARRAY.length())) { return; }
32+
if (parser.allocate(EMPTY_ARRAY.length())) { return; }
3333
for (auto _ : state) {
3434
try {
3535
UNUSED dom::element doc = parser.parse(EMPTY_ARRAY);

benchmark/benchmarker.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,10 @@ struct benchmarker {
294294
// Allocate dom::parser
295295
collector.start();
296296
dom::parser parser;
297-
error_code alloc_error = parser.set_capacity(json.size());
297+
error_code error = parser.allocate(json.size());
298+
if (error) {
299+
exit_error(string("Unable to allocate_stage ") + to_string(json.size()) + " bytes for the JSON result: " + error_message(error));
300+
}
298301
event_count allocate_count = collector.end();
299302
allocate_stage << allocate_count;
300303
// Run it once to get hot buffers
@@ -305,14 +308,11 @@ struct benchmarker {
305308
}
306309
}
307310

308-
if (alloc_error) {
309-
exit_error(string("Unable to allocate_stage ") + to_string(json.size()) + " bytes for the JSON result: " + error_message(alloc_error));
310-
}
311311
verbose() << "[verbose] allocated memory for parsed JSON " << endl;
312312

313313
// Stage 1 (find structurals)
314314
collector.start();
315-
error_code error = active_implementation->stage1((const uint8_t *)json.data(), json.size(), parser, false);
315+
error = active_implementation->stage1((const uint8_t *)json.data(), json.size(), parser, false);
316316
event_count stage1_count = collector.end();
317317
stage1 << stage1_count;
318318
if (error) {

benchmark/linux/linux-perf-events.h

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,25 +56,29 @@ template <int TYPE = PERF_TYPE_HARDWARE> class LinuxEvents {
5656
temp_result_vec.resize(num_events * 2 + 1);
5757
}
5858

59-
~LinuxEvents() { close(fd); }
59+
~LinuxEvents() { if (fd != -1) { close(fd); } }
6060

6161
inline void start() {
62-
if (ioctl(fd, PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP) == -1) {
63-
report_error("ioctl(PERF_EVENT_IOC_RESET)");
64-
}
62+
if (fd != -1) {
63+
if (ioctl(fd, PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP) == -1) {
64+
report_error("ioctl(PERF_EVENT_IOC_RESET)");
65+
}
6566

66-
if (ioctl(fd, PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP) == -1) {
67-
report_error("ioctl(PERF_EVENT_IOC_ENABLE)");
67+
if (ioctl(fd, PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP) == -1) {
68+
report_error("ioctl(PERF_EVENT_IOC_ENABLE)");
69+
}
6870
}
6971
}
7072

7173
inline void end(std::vector<unsigned long long> &results) {
72-
if (ioctl(fd, PERF_EVENT_IOC_DISABLE, PERF_IOC_FLAG_GROUP) == -1) {
73-
report_error("ioctl(PERF_EVENT_IOC_DISABLE)");
74-
}
74+
if (fd != -1) {
75+
if (ioctl(fd, PERF_EVENT_IOC_DISABLE, PERF_IOC_FLAG_GROUP) == -1) {
76+
report_error("ioctl(PERF_EVENT_IOC_DISABLE)");
77+
}
7578

76-
if (read(fd, temp_result_vec.data(), temp_result_vec.size() * 8) == -1) {
77-
report_error("read");
79+
if (read(fd, temp_result_vec.data(), temp_result_vec.size() * 8) == -1) {
80+
report_error("read");
81+
}
7882
}
7983
// our actual results are in slots 1,3,5, ... of this structure
8084
// we really should be checking our ids obtained earlier to be safe

benchmark/parse_stream.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ int main (int argc, char *argv[]){
3636
for (auto i = 0; i < 3; i++) {
3737
//Actual test
3838
simdjson::dom::parser parser;
39-
simdjson::error_code alloc_error = parser.set_capacity(p.size());
39+
simdjson::error_code alloc_error = parser.allocate(p.size());
4040
if (alloc_error) {
4141
std::cerr << alloc_error << std::endl;
4242
return EXIT_FAILURE;

benchmark/statisticalmodel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ int main(int argc, char *argv[]) {
161161
#ifdef __linux__
162162
simdjson::dom::parser parser;
163163
const simdjson::implementation &stage_parser = *simdjson::active_implementation;
164-
simdjson::error_code alloc_error = parser.set_capacity(p.size());
164+
simdjson::error_code alloc_error = parser.allocate(p.size());
165165
if (alloc_error) {
166166
std::cerr << alloc_error << std::endl;
167167
return EXIT_FAILURE;

doc/performance.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ without bound:
7777
7878
```c++
7979
dom::parser parser(0); // This parser will refuse to automatically grow capacity
80-
simdjson::error_code allocate_error = parser.set_capacity(1024*1024); // This allocates enough capacity to handle documents <= 1MB
80+
simdjson::error_code allocate_error = parser.allocate(1024*1024); // This allocates enough capacity to handle documents <= 1MB
8181
if (allocate_error) { cerr << allocate_error << endl; exit(1); }
8282
8383
for (web_request request : listen()) {

include/simdjson/document.h

Lines changed: 35 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ class document {
350350
std::unique_ptr<uint8_t[]> string_buf;
351351

352352
private:
353-
inline error_code set_capacity(size_t len) noexcept;
353+
inline error_code allocate(size_t len) noexcept;
354354
template<typename T>
355355
friend class simdjson::minify;
356356
friend class parser;
@@ -609,13 +609,10 @@ class parser {
609609
* @param max_capacity The maximum document length the parser can automatically handle. The parser
610610
* will allocate more capacity on an as needed basis (when it sees documents too big to handle)
611611
* up to this amount. The parser still starts with zero capacity no matter what this number is:
612-
* to allocate an initial capacity, call set_capacity() after constructing the parser. Defaults
613-
* to SIMDJSON_MAXSIZE_BYTES (the largest single document simdjson can process).
614-
* @param max_depth The maximum depth--number of nested objects and arrays--this parser can handle.
615-
* This will not be allocated until parse() is called for the first time. Defaults to
616-
* DEFAULT_MAX_DEPTH.
612+
* to allocate an initial capacity, call allocate() after constructing the parser.
613+
* Defaults to SIMDJSON_MAXSIZE_BYTES (the largest single document simdjson can process).
617614
*/
618-
really_inline parser(size_t max_capacity = SIMDJSON_MAXSIZE_BYTES, size_t max_depth = DEFAULT_MAX_DEPTH) noexcept;
615+
really_inline parser(size_t max_capacity = SIMDJSON_MAXSIZE_BYTES) noexcept;
619616

620617
/**
621618
* Take another parser's buffers and state.
@@ -835,6 +832,30 @@ class parser {
835832
/** @private We do not want to allow implicit conversion from C string to std::string. */
836833
really_inline simdjson_result<element> parse_many(const char *buf, size_t batch_size = DEFAULT_BATCH_SIZE) noexcept = delete;
837834

835+
/**
836+
* Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length
837+
* and `max_depth` depth.
838+
*
839+
* @param capacity The new capacity.
840+
* @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH.
841+
* @return The error, if there is one.
842+
*/
843+
WARN_UNUSED inline error_code allocate(size_t capacity, size_t max_depth = DEFAULT_MAX_DEPTH) noexcept;
844+
845+
/**
846+
* @private deprecated because it returns bool instead of error_code, which is our standard for
847+
* failures. Use allocate() instead.
848+
*
849+
* Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length
850+
* and `max_depth` depth.
851+
*
852+
* @param capacity The new capacity.
853+
* @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH.
854+
* @return true if successful, false if allocation failed.
855+
*/
856+
[[deprecated("Use allocate() instead.")]]
857+
WARN_UNUSED inline bool allocate_capacity(size_t capacity, size_t max_depth = DEFAULT_MAX_DEPTH) noexcept;
858+
838859
/**
839860
* The largest document this parser can support without reallocating.
840861
*
@@ -858,17 +879,6 @@ class parser {
858879
*/
859880
really_inline size_t max_depth() const noexcept;
860881

861-
/**
862-
* Set capacity. This is the largest document this parser can support without reallocating.
863-
*
864-
* This will allocate or deallocate as necessary.
865-
*
866-
* @param capacity The new capacity, in bytes.
867-
*
868-
* @return MEMALLOC if unsuccessful, SUCCESS otherwise.
869-
*/
870-
WARN_UNUSED inline error_code set_capacity(size_t capacity) noexcept;
871-
872882
/**
873883
* Set max_capacity. This is the largest document this parser can automatically support.
874884
*
@@ -880,32 +890,6 @@ class parser {
880890
*/
881891
really_inline void set_max_capacity(size_t max_capacity) noexcept;
882892

883-
/**
884-
* Set the maximum level of nested object and arrays supported by this parser.
885-
*
886-
* This will allocate or deallocate as necessary.
887-
*
888-
* @param max_depth The new maximum depth, in bytes.
889-
*
890-
* @return MEMALLOC if unsuccessful, SUCCESS otherwise.
891-
*/
892-
WARN_UNUSED inline error_code set_max_depth(size_t max_depth) noexcept;
893-
894-
/**
895-
* @private @deprecated Use set_capacity() instead.
896-
*
897-
* Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length
898-
* and `max_depth` depth.
899-
*
900-
* Equivalent to calling set_capacity() and set_max_depth().
901-
*
902-
* @param capacity The new capacity.
903-
* @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH.
904-
* @return true if successful, false if allocation failed.
905-
*/
906-
[[deprecated("Use set_capacity() instead.")]]
907-
WARN_UNUSED inline bool allocate_capacity(size_t capacity, size_t max_depth = DEFAULT_MAX_DEPTH) noexcept;
908-
909893
/** @private Use the new DOM API instead */
910894
class Iterator;
911895
/** @private Use simdjson_error instead */
@@ -988,25 +972,25 @@ class parser {
988972

989973
private:
990974
/**
991-
* The maximum document length this parser supports.
975+
* The maximum document length this parser will automatically support.
992976
*
993-
* Buffers are large enough to handle any document up to this length.
977+
* The parser will not be automatically allocated above this amount.
994978
*/
995-
size_t _capacity{0};
979+
size_t _max_capacity;
996980

997981
/**
998-
* The maximum document length this parser will automatically support.
982+
* The maximum document length this parser supports.
999983
*
1000-
* The parser will not be automatically allocated above this amount.
984+
* Buffers are large enough to handle any document up to this length.
1001985
*/
1002-
size_t _max_capacity;
986+
size_t _capacity{0};
1003987

1004988
/**
1005989
* The maximum depth (number of nested objects and arrays) supported by this parser.
1006990
*
1007991
* Defaults to DEFAULT_MAX_DEPTH.
1008992
*/
1009-
size_t _max_depth;
993+
size_t _max_depth{0};
1010994

1011995
/**
1012996
* The loaded buffer (reused each time load() is called)

0 commit comments

Comments
 (0)