94 lines
2.8 KiB
C++
94 lines
2.8 KiB
C++
#pragma once
|
|
|
|
#if SIMDJSON_EXCEPTIONS
|
|
|
|
#include "partial_tweets.h"
|
|
|
|
namespace partial_tweets {
|
|
|
|
using namespace simdjson;
|
|
using namespace simdjson::builtin;
|
|
|
|
class Iter {
|
|
public:
|
|
simdjson_really_inline bool Run(const padded_string &json);
|
|
|
|
simdjson_really_inline const std::vector<tweet> &Result() { return tweets; }
|
|
simdjson_really_inline size_t ItemCount() { return tweets.size(); }
|
|
|
|
private:
|
|
ondemand::parser parser{};
|
|
std::vector<tweet> tweets{};
|
|
|
|
simdjson_really_inline uint64_t nullable_int(ondemand::value && value) {
|
|
if (value.is_null()) { return 0; }
|
|
return std::move(value);
|
|
}
|
|
|
|
simdjson_really_inline twitter_user read_user(ondemand::object && user) {
|
|
// Move user into a local object so it gets destroyed (and moves the iterator)
|
|
ondemand::object u = std::move(user);
|
|
return { u["id"], u["screen_name"] };
|
|
}
|
|
};
|
|
|
|
simdjson_really_inline bool Iter::Run(const padded_string &json) {
|
|
tweets.clear();
|
|
|
|
// Walk the document, parsing the tweets as we go
|
|
|
|
// { "statuses":
|
|
auto iter = parser.iterate_raw(json).value();
|
|
if (!iter.start_object() || !iter.find_field_raw("statuses")) { return false; }
|
|
// { "statuses": [
|
|
if (!iter.start_array()) { return false; }
|
|
|
|
do {
|
|
tweet tweet;
|
|
|
|
if (!iter.start_object() || !iter.find_field_raw("created_at")) { return false; }
|
|
tweet.created_at = iter.consume_string();
|
|
|
|
if (!iter.has_next_field() || !iter.find_field_raw("id")) { return false; }
|
|
tweet.id = iter.consume_uint64();
|
|
|
|
if (!iter.has_next_field() || !iter.find_field_raw("text")) { return false; }
|
|
tweet.text = iter.consume_string();
|
|
|
|
if (!iter.has_next_field() || !iter.find_field_raw("in_reply_to_status_id")) { return false; }
|
|
if (!iter.is_null()) {
|
|
tweet.in_reply_to_status_id = iter.consume_uint64();
|
|
}
|
|
|
|
if (!iter.has_next_field() || !iter.find_field_raw("user")) { return false; }
|
|
{
|
|
if (!iter.start_object() || !iter.find_field_raw("id")) { return false; }
|
|
tweet.user.id = iter.consume_uint64();
|
|
|
|
if (!iter.has_next_field() || !iter.find_field_raw("screen_name")) { return false; }
|
|
tweet.user.screen_name = iter.consume_string();
|
|
|
|
if (iter.skip_container()) { return false; } // Skip the rest of the user object
|
|
}
|
|
|
|
if (!iter.has_next_field() || !iter.find_field_raw("retweet_count")) { return false; }
|
|
tweet.retweet_count = iter.consume_uint64();
|
|
|
|
if (!iter.has_next_field() || !iter.find_field_raw("favorite_count")) { return false; }
|
|
tweet.favorite_count = iter.consume_uint64();
|
|
|
|
tweets.push_back(tweet);
|
|
|
|
if (iter.skip_container()) { return false; } // Skip the rest of the tweet object
|
|
|
|
} while (iter.has_next_element());
|
|
|
|
return true;
|
|
}
|
|
|
|
BENCHMARK_TEMPLATE(PartialTweets, Iter);
|
|
|
|
} // namespace partial_tweets
|
|
|
|
#endif // SIMDJSON_EXCEPTIONS
|