Moving iterator functions in the header file (#189)

We want the compiler to inline hot functions in the iterators. Let us leave them in the header file. Please.
This commit is contained in:
Daniel Lemire
2019-06-11 21:09:58 -04:00
committed by GitHub
parent 463ef9b08f
commit b1e8990654
3 changed files with 266 additions and 188 deletions
-164
View File
@@ -51,170 +51,6 @@ ParsedJson::iterator::iterator(iterator &&o):
o.depthindex = nullptr;// we take ownership
}
WARN_UNUSED
bool ParsedJson::iterator::isOk() const {
return location < tape_length;
}
// useful for debuging purposes
size_t ParsedJson::iterator::get_tape_location() const {
return location;
}
// useful for debuging purposes
size_t ParsedJson::iterator::get_tape_length() const {
return tape_length;
}
// returns the current depth (start at 1 with 0 reserved for the fictitious root node)
size_t ParsedJson::iterator::get_depth() const {
return depth;
}
// A scope is a series of nodes at the same depth, typically it is either an object ({) or an array ([).
// The root node has type 'r'.
uint8_t ParsedJson::iterator::get_scope_type() const {
return depthindex[depth].scope_type;
}
bool ParsedJson::iterator::move_forward() {
if(location + 1 >= tape_length) {
return false; // we are at the end!
}
if ((current_type == '[') || (current_type == '{')){
// We are entering a new scope
depth++;
depthindex[depth].start_of_scope = location;
depthindex[depth].scope_type = current_type;
} else if ((current_type == ']') || (current_type == '}')) {
// Leaving a scope.
depth--;
if(depth == 0) {
// Should not be necessary
return false;
}
} else if ((current_type == 'd') || (current_type == 'l')) {
// d and l types use 2 locations on the tape, not just one.
location += 1;
}
location += 1;
current_val = pj.tape[location];
current_type = (current_val >> 56);
return true;
}
bool ParsedJson::iterator::move_to_key(const char * key) {
if(down()) {
do {
assert(is_string());
bool rightkey = (strcmp(get_string(),key)==0);// null chars would fool this
next();
if(rightkey) {
return true;
}
} while(next());
assert(up());// not found
}
return false;
}
bool ParsedJson::iterator::next() {
if ((current_type == '[') || (current_type == '{')){
// we need to jump
size_t npos = ( current_val & JSONVALUEMASK);
if(npos >= tape_length) {
return false; // shoud never happen unless at the root
}
uint64_t nextval = pj.tape[npos];
uint8_t nexttype = (nextval >> 56);
if((nexttype == ']') || (nexttype == '}')) {
return false; // we reached the end of the scope
}
location = npos;
current_val = nextval;
current_type = nexttype;
return true;
}
size_t increment = (current_type == 'd' || current_type == 'l') ? 2 : 1;
if(location + increment >= tape_length) {
return false;
}
uint64_t nextval = pj.tape[location + increment];
uint8_t nexttype = (nextval >> 56);
if((nexttype == ']') || (nexttype == '}')) {
return false; // we reached the end of the scope
}
location = location + increment;
current_val = nextval;
current_type = nexttype;
return true;
}
bool ParsedJson::iterator::prev() {
if(location - 1 < depthindex[depth].start_of_scope) {
return false;
}
location -= 1;
current_val = pj.tape[location];
current_type = (current_val >> 56);
if ((current_type == ']') || (current_type == '}')){
// we need to jump
size_t new_location = ( current_val & JSONVALUEMASK);
if(new_location < depthindex[depth].start_of_scope) {
return false; // shoud never happen
}
location = new_location;
current_val = pj.tape[location];
current_type = (current_val >> 56);
}
return true;
}
bool ParsedJson::iterator::up() {
if(depth == 1) {
return false; // don't allow moving back to root
}
to_start_scope();
// next we just move to the previous value
depth--;
location -= 1;
current_val = pj.tape[location];
current_type = (current_val >> 56);
return true;
}
bool ParsedJson::iterator::down() {
if(location + 1 >= tape_length) {
return false;
}
if ((current_type == '[') || (current_type == '{')) {
size_t npos = (current_val & JSONVALUEMASK);
if(npos == location + 2) {
return false; // we have an empty scope
}
depth++;
location = location + 1;
depthindex[depth].start_of_scope = location;
depthindex[depth].scope_type = current_type;
current_val = pj.tape[location];
current_type = (current_val >> 56);
return true;
}
return false;
}
void ParsedJson::iterator::to_start_scope() {
location = depthindex[depth].start_of_scope;
current_val = pj.tape[location];
current_type = (current_val >> 56);
}
bool ParsedJson::iterator::print(std::ostream &os, bool escape_strings) const {
if(!isOk()) {
return false;