Sorted Vector & binary search functionality.

Bug: 16659276
Tested: on Linux & Windows.

Change-Id: Ie7a73810345fad4cf0a3ad03dfaa5464e3ed5ac8
This commit is contained in:
Wouter van Oortmerssen
2015-01-07 17:51:31 -08:00
parent 73582b145c
commit 3550899987
11 changed files with 166 additions and 30 deletions

View File

@@ -288,6 +288,31 @@ public:
return reinterpret_cast<const uint8_t *>(&length_ + 1);
}
template<typename K> return_type LookupByKey(K key) const {
auto span = size();
uoffset_t start = 0;
// Perform binary search for key.
while (span) {
// Compare against middle element of current span.
auto middle = span / 2;
auto table = Get(start + middle);
auto comp = table->KeyCompareWithValue(key);
if (comp > 0) {
// Greater than. Adjust span and try again.
span = middle;
} else if (comp < 0) {
// Less than. Adjust span and try again.
middle++;
start += middle;
span -= middle;
} else {
// Found element.
return table;
}
}
return nullptr; // Key not found.
}
protected:
// This class is only used to access pre-existing data. Don't ever
// try to construct these manually.
@@ -304,6 +329,10 @@ template<typename T> static inline size_t VectorLength(const Vector<T> *v) {
struct String : public Vector<char> {
const char *c_str() const { return reinterpret_cast<const char *>(Data()); }
bool operator <(const String &o) const {
return strcmp(c_str(), o.c_str()) < 0;
}
};
// Simple indirection for buffer allocation, to allow this to be overridden
@@ -646,6 +675,40 @@ class FlatBufferBuilder FLATBUFFERS_FINAL_CLASS {
return Offset<Vector<T>>(EndVector(len));
}
template<typename T> Offset<Vector<T>> CreateVector(const std::vector<T> &v) {
return CreateVector(v.data(), v.size());
}
template<typename T> Offset<Vector<const T *>> CreateVectorOfStructs(
const T *v, size_t len) {
NotNested();
StartVector(len * sizeof(T) / AlignOf<T>(), AlignOf<T>());
PushBytes(reinterpret_cast<const uint8_t *>(v), sizeof(T) * len);
return Offset<Vector<const T *>>(EndVector(len));
}
template<typename T> Offset<Vector<const T *>> CreateVectorOfStructs(
const std::vector<T> &v) {
return CreateVectorOfStructs(v.data(), v.size());
}
template<typename T> Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(
Offset<T> *v, size_t len) {
std::sort(v, v + len,
[this](const Offset<T> &a, const Offset<T> &b) -> bool {
auto table_a = reinterpret_cast<T *>(buf_.data_at(a.o));
auto table_b = reinterpret_cast<T *>(buf_.data_at(b.o));
return table_a->KeyCompareLessThan(table_b);
}
);
return CreateVector(v, len);
}
template<typename T> Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(
std::vector<T> *v) {
return CreateVectorOfSortedTables(v->data(), v->size());
}
// Specialized version for non-copying use cases. Write the data any time
// later to the returned buffer pointer `buf`.
uoffset_t CreateUninitializedVector(size_t len, size_t elemsize,
@@ -662,23 +725,6 @@ class FlatBufferBuilder FLATBUFFERS_FINAL_CLASS {
reinterpret_cast<uint8_t **>(buf));
}
template<typename T> Offset<Vector<T>> CreateVector(const std::vector<T> &v) {
return CreateVector(v.data(), v.size());
}
template<typename T> Offset<Vector<const T *>> CreateVectorOfStructs(
const T *v, size_t len) {
NotNested();
StartVector(len * sizeof(T) / AlignOf<T>(), AlignOf<T>());
PushBytes(reinterpret_cast<const uint8_t *>(v), sizeof(T) * len);
return Offset<Vector<const T *>>(EndVector(len));
}
template<typename T> Offset<Vector<const T *>> CreateVectorOfStructs(
const std::vector<T> &v) {
return CreateVectorOfStructs(v.data(), v.size());
}
static const size_t kFileIdentifierLength = 4;
// Finish serializing a buffer by writing the root offset.

View File

@@ -186,11 +186,14 @@ struct Definition {
};
struct FieldDef : public Definition {
FieldDef() : deprecated(false), required(false), padding(0), used(false) {}
FieldDef() : deprecated(false), required(false), key(false), padding(0),
used(false) {}
Value value;
bool deprecated;
bool required;
bool deprecated; // Field is allowed to be present in old data, but can't be
// written in new data nor accessed in new code.
bool required; // Field must always be present.
bool key; // Field functions as a key for creating sorted vectors.
size_t padding; // Bytes to always pad after this field.
bool used; // Used during JSON parsing to check for repeated fields.
};
@@ -200,6 +203,7 @@ struct StructDef : public Definition {
: fixed(false),
predecl(true),
sortbysize(true),
has_key(false),
minalign(1),
bytesize(0)
{}
@@ -214,6 +218,7 @@ struct StructDef : public Definition {
bool fixed; // If it's struct, not a table.
bool predecl; // If it's used before it was defined.
bool sortbysize; // Whether fields come in the declaration or size order.
bool has_key; // It has a key field.
size_t minalign; // What the whole object needs to be aligned to.
size_t bytesize; // Size if fixed.
};
@@ -271,6 +276,7 @@ class Parser {
namespaces_.push_back(new Namespace());
known_attributes_.insert("deprecated");
known_attributes_.insert("required");
known_attributes_.insert("key");
known_attributes_.insert("id");
known_attributes_.insert("force_align");
known_attributes_.insert("bit_flags");