Example #1
0
static uint64_t FastHashJsonRecursive (uint64_t hash,
                                       TRI_json_t const* object) {
    if (nullptr == object) {
        return fasthash64(static_cast<const void*>("null"), 4, hash);
    }

    switch (object->_type) {
    case TRI_JSON_UNUSED: {
        return hash;
    }

    case TRI_JSON_NULL: {
        return fasthash64(static_cast<const void*>("null"), 4, hash);
    }

    case TRI_JSON_BOOLEAN: {
        if (object->_value._boolean) {
            return fasthash64(static_cast<const void*>("true"), 4, hash);
        }
        return fasthash64(static_cast<const void*>("false"), 5, hash);
    }

    case TRI_JSON_NUMBER: {
        return fasthash64(static_cast<const void*>(&object->_value._number), sizeof(object->_value._number), hash);
    }

    case TRI_JSON_STRING:
    case TRI_JSON_STRING_REFERENCE: {
        return fasthash64(static_cast<const void*>(object->_value._string.data), object->_value._string.length, hash);
    }

    case TRI_JSON_OBJECT: {
        hash = fasthash64(static_cast<const void*>("object"), 6, hash);
        size_t const n = TRI_LengthVector(&object->_value._objects);
        for (size_t i = 0;  i < n;  i += 2) {
            auto subjson = static_cast<TRI_json_t const*>(TRI_AddressVector(&object->_value._objects, i));
            TRI_ASSERT(TRI_IsStringJson(subjson));
            hash = FastHashJsonRecursive(hash, subjson);
            subjson = static_cast<TRI_json_t const*>(TRI_AddressVector(&object->_value._objects, i + 1));
            hash = FastHashJsonRecursive(hash, subjson);
        }
        return hash;
    }

    case TRI_JSON_ARRAY: {
        hash = fasthash64(static_cast<const void*>("array"), 5, hash);
        size_t const n = TRI_LengthVector(&object->_value._objects);
        for (size_t i = 0;  i < n;  ++i) {
            auto subjson = static_cast<TRI_json_t const*>(TRI_AddressVector(&object->_value._objects, i));
            hash = FastHashJsonRecursive(hash, subjson);
        }
    }
    }

    return hash;   // never reached
}
Example #2
0
void TRI_DestroyJson (TRI_memory_zone_t* zone, TRI_json_t* object) {
  switch (object->_type) {
    case TRI_JSON_UNUSED:
    case TRI_JSON_NULL:
    case TRI_JSON_BOOLEAN:
    case TRI_JSON_NUMBER:
    case TRI_JSON_STRING_REFERENCE:
      break;

    case TRI_JSON_STRING:
      TRI_DestroyBlob(zone, &object->_value._string);
      break;

    case TRI_JSON_OBJECT:
    case TRI_JSON_ARRAY: {
      size_t const n = TRI_LengthVector(&object->_value._objects);

      for (size_t i = 0;  i < n;  ++i) {
        auto v = static_cast<TRI_json_t*>(TRI_AddressVector(&object->_value._objects, i));
        TRI_DestroyJson(zone, v);
      }

      TRI_DestroyVector(&object->_value._objects);
      break;
    }
  }
}
Example #3
0
TRI_json_t* TRI_LookupObjectJson (TRI_json_t const* object, char const* name) {
  if (object == nullptr) {
    return nullptr;
  }

  TRI_ASSERT(object->_type == TRI_JSON_OBJECT);
  TRI_ASSERT(name != nullptr);

  size_t const n = TRI_LengthVector(&object->_value._objects);

  if (n >= 16) {
    // if we have many attributes, try an algorithm that compares string length first

    // calculate string length once
    size_t const length = strlen(name) + 1;

    for (size_t i = 0;  i < n;  i += 2) {
      auto key = static_cast<TRI_json_t const*>(TRI_AddressVector(&object->_value._objects, i));

      if (! IsString(key)) {
        continue;
      }
 
      // check string length first, and contents only if string lengths are equal
      if (key->_value._string.length == length && 
          strcmp(key->_value._string.data, name) == 0) {
        return static_cast<TRI_json_t*>(TRI_AddressVector(&object->_value._objects, i + 1));
      }
    }
  }
  else {
    // simple case for smaller objects
    for (size_t i = 0;  i < n;  i += 2) {
      auto key = static_cast<TRI_json_t const*>(TRI_AddressVector(&object->_value._objects, i));

      if (! IsString(key)) {
        continue;
      }

      if (strcmp(key->_value._string.data, name) == 0) {
        return static_cast<TRI_json_t*>(TRI_AddressVector(&object->_value._objects, i + 1));
      }
    }
  }

  return nullptr;
}
Example #4
0
static uint64_t HashJsonRecursive (uint64_t hash,
                                   TRI_json_t const* object) {
    if (nullptr == object) {
        return HashBlock(hash, "null", 4);   // strlen("null")
    }

    switch (object->_type) {
    case TRI_JSON_UNUSED: {
        return hash;
    }

    case TRI_JSON_NULL: {
        return HashBlock(hash, "null", 4);   // strlen("null")
    }

    case TRI_JSON_BOOLEAN: {
        if (object->_value._boolean) {
            return HashBlock(hash, "true", 4);  // strlen("true")
        }
        else {
            return HashBlock(hash, "false", 5);  // strlen("true")
        }
    }

    case TRI_JSON_NUMBER: {
        return HashBlock(hash, (char const*) &(object->_value._number), sizeof(object->_value._number));
    }

    case TRI_JSON_STRING:
    case TRI_JSON_STRING_REFERENCE: {
        return HashBlock(hash,
                         object->_value._string.data,
                         object->_value._string.length);
    }

    case TRI_JSON_OBJECT: {
        hash = HashBlock(hash, "array", 5);   // strlen("array")
        size_t const n = TRI_LengthVector(&object->_value._objects);
        uint64_t tmphash = hash;
        for (size_t i = 0;  i < n;  i += 2) {
            auto subjson = static_cast<TRI_json_t const*>(TRI_AddressVector(&object->_value._objects, i));
            TRI_ASSERT(TRI_IsStringJson(subjson));
            tmphash ^= HashJsonRecursive(hash, subjson);
            subjson = static_cast<TRI_json_t const*>(TRI_AddressVector(&object->_value._objects, i + 1));
            tmphash ^= HashJsonRecursive(hash, subjson);
        }
        return tmphash;
    }

    case TRI_JSON_ARRAY: {
        hash = HashBlock(hash, "list", 4);   // strlen("list")
        size_t const n = TRI_LengthVector(&object->_value._objects);
        for (size_t i = 0;  i < n;  ++i) {
            auto subjson = static_cast<TRI_json_t const*>(TRI_AddressVector(&object->_value._objects, i));
            hash = HashJsonRecursive(hash, subjson);
        }
        return hash;
    }
    }
    return hash;   // never reached
}