Skip to content

Commit

Permalink
ISSUE #703 changed RepoNodes to not inherit from RepoBSON and updated…
Browse files Browse the repository at this point in the history
… unit tests
  • Loading branch information
sebjf committed Oct 9, 2024
1 parent 7b3cf2d commit 1b08aa4
Show file tree
Hide file tree
Showing 71 changed files with 4,187 additions and 2,620 deletions.
2 changes: 0 additions & 2 deletions bouncer/src/repo/core/model/bson/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
set(SOURCES
${SOURCES}
${CMAKE_CURRENT_SOURCE_DIR}/repo_bson.cpp
${CMAKE_CURRENT_SOURCE_DIR}/repo_bson_binmapping_builder.cpp
${CMAKE_CURRENT_SOURCE_DIR}/repo_bson_builder.cpp
${CMAKE_CURRENT_SOURCE_DIR}/repo_bson_element.cpp
${CMAKE_CURRENT_SOURCE_DIR}/repo_bson_factory.cpp
Expand All @@ -31,7 +30,6 @@ set(HEADERS
${HEADERS}
${CMAKE_CURRENT_SOURCE_DIR}/repo_bson.h
${CMAKE_CURRENT_SOURCE_DIR}/repo_bson_assets.h
${CMAKE_CURRENT_SOURCE_DIR}/repo_bson_binmapping_builder.h
${CMAKE_CURRENT_SOURCE_DIR}/repo_bson_builder.h
${CMAKE_CURRENT_SOURCE_DIR}/repo_bson_element.h
${CMAKE_CURRENT_SOURCE_DIR}/repo_bson_factory.h
Expand Down
80 changes: 76 additions & 4 deletions bouncer/src/repo/core/model/bson/repo_bson.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#include <mongo/client/dbclient.h>

#include "../../../lib/repo_exception.h"

using namespace repo::core::model;

RepoBSON::RepoBSON(const RepoBSON &obj,
Expand Down Expand Up @@ -125,7 +127,77 @@ void RepoBSON::replaceBinaryWithReference(const repo::core::model::RepoBSON &fil
repo::lib::RepoUUID RepoBSON::getUUIDField(const std::string &label) const {
return hasField(label) ?
repo::lib::RepoUUID::fromBSONElement(getField(label)) :
repo::lib::RepoUUID::createUUID();
throw repo::lib::RepoException("UUID field does not exist on document");
}

std::vector<float> RepoBSON::getFloatVectorField(const std::string& label) const {
std::vector<float> results;
if (hasField(label))
{
RepoBSON array = getObjectField(label);
if (!array.isEmpty())
{
std::set<std::string> fields = array.getFieldNames();
std::set<std::string>::iterator it;
for (it = fields.begin(); it != fields.end(); ++it)
results.push_back(array.getDoubleField(*it));
}
else
{
repoDebug << "getFloatVectorField: field " << label << " is an empty bson or wrong type!";
}
}
return results;
}

repo::lib::RepoMatrix RepoBSON::getMatrixField(const std::string& label) const {

std::vector<mongo::BSONElement> rows;
std::vector<mongo::BSONElement> cols;

std::vector<float> transformationMatrix;

uint32_t rowInd = 0, colInd = 0;
transformationMatrix.resize(16);
float* transArr = &transformationMatrix.at(0);

// matrix is stored as array of arrays, row first

auto matrixObj = getField(label).embeddedObject();

matrixObj.elems(rows);
for (size_t rowInd = 0; rowInd < 4; rowInd++)
{
cols.clear();
rows[rowInd].embeddedObject().elems(cols);
for (size_t colInd = 0; colInd < 4; colInd++)
{
uint32_t index = rowInd * 4 + colInd;
transArr[index] = cols[colInd].number();
}
}

return repo::lib::RepoMatrix(transformationMatrix);
}

std::vector<double> RepoBSON::getDoubleVectorField(const std::string& label) const {
std::vector<double> results;
if (hasField(label))
{
RepoBSON array = getObjectField(label);
if (!array.isEmpty())
{
std::set<std::string> fields = array.getFieldNames();
std::set<std::string>::iterator it;
for (it = fields.begin(); it != fields.end(); ++it)
results.push_back(array.getDoubleField(*it));
}
else
{
repoDebug << "getVectorAsStdDouble: field " << label << " is an empty bson or wrong type!";
}
}
return results;
}

std::vector<repo::lib::RepoUUID> RepoBSON::getUUIDFieldArray(const std::string &label) const {
Expand Down Expand Up @@ -270,15 +342,15 @@ std::vector<std::string> RepoBSON::getStringArray(const std::string &label) cons
return results;
}

int64_t RepoBSON::getTimeStampField(const std::string &label) const
time_t RepoBSON::getTimeStampField(const std::string &label) const
{
int64_t time = -1;
time_t time = 0;

if (hasField(label))
{
auto field = getField(label);
if (field.type() == ElementType::DATE)
time = field.date().asInt64();
time = field.date().toTimeT();
else
{
repoError << "GetTimeStampField: field " << label << " is not of type Date!";
Expand Down
34 changes: 32 additions & 2 deletions bouncer/src/repo/core/model/bson/repo_bson.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@
#include "../../../lib/datastructure/repo_uuid.h"
#include "repo_bson_element.h"

#include "../../../lib/datastructure/repo_vector.h"
#include "../../../lib/datastructure/repo_matrix.h"


#define REPO_BSON_MAX_BYTE_SIZE 16770000 //max size is 16MB,but leave a bit for buffer

namespace repo {
Expand All @@ -54,7 +58,7 @@ namespace repo {
//TODO: Eventually we should inherit from a generic BSON object.
//work seems to have been started in here:https://github.com/jbenet/bson-cpp
//alternatively we can use a c++ wrapper on https://github.com/mongodb/libbson
class REPO_API_EXPORT RepoBSON : public mongo::BSONObj
class REPO_API_EXPORT RepoBSON : private mongo::BSONObj
{
friend class RepoBSONBuilder;
friend class repo::core::handler::MongoDatabaseHandler;
Expand Down Expand Up @@ -161,6 +165,32 @@ namespace repo {
return mongo::BSONObj::getObjectField(label);
}

std::vector<lib::RepoVector3D> getBounds3D(const std::string& label) {
auto field = getObjectField(label);
return std::vector< lib::RepoVector3D>({
lib::RepoVector3D(field.getFloatVectorField("0")),
lib::RepoVector3D(field.getFloatVectorField("1")),
});
}

repo::lib::RepoMatrix getMatrixField(const std::string& label) const;

std::vector<float> getFloatVectorField(const std::string& label) const;

std::vector<double> getDoubleVectorField(const std::string& label) const;

std::vector<std::string> getFileList(const std::string& label) const
{
std::vector<std::string> fileList;
RepoBSON arraybson = getObjectField(label);
std::set<std::string> fields = arraybson.getFieldNames();
for (const auto& field : fields)
{
fileList.push_back(arraybson.getStringField(field));
}
return fileList;
}

double getDoubleField(const std::string &label) const;

bool isEmpty() const {
Expand Down Expand Up @@ -259,7 +289,7 @@ namespace repo {
* @param label name of the element
* @return returns timestamp as int64, return -1 if not found
*/
int64_t getTimeStampField(const std::string &label) const;
time_t getTimeStampField(const std::string &label) const;

std::set<std::string> getFieldNames() const {
std::set<std::string> fieldNames;
Expand Down
37 changes: 0 additions & 37 deletions bouncer/src/repo/core/model/bson/repo_bson_binmapping_builder.cpp

This file was deleted.

55 changes: 0 additions & 55 deletions bouncer/src/repo/core/model/bson/repo_bson_binmapping_builder.h

This file was deleted.

18 changes: 17 additions & 1 deletion bouncer/src/repo/core/model/bson/repo_bson_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ void RepoBSONBuilder::appendArrayPair(
RepoBSON RepoBSONBuilder::obj()
{
mongo::BSONObjBuilder build;
return RepoBSON(mongo::BSONObjBuilder::obj());
return RepoBSON(mongo::BSONObjBuilder::obj(), binMapping);
}

template<> void repo::core::model::RepoBSONBuilder::append<repo::lib::RepoUUID>
Expand Down Expand Up @@ -121,3 +121,19 @@ void RepoBSONBuilder::appendVector3DObject(
objBuilder.append("z", vec.z);
append(label, objBuilder.obj());
}

void RepoBSONBuilder::appendLargeArray(std::string name, const void* data, size_t size)
{
auto obj = this->tempObj();
if (!obj.hasField(REPO_NODE_LABEL_ID))
{
throw std::invalid_argument("appendLargeArray called before the builder is assigned a unique Id. Ensure appendDefaults has been called before appending large arrays.");
}

std::string bName = obj.getUUIDField(REPO_NODE_LABEL_ID).toString() + "_" + name;

binMapping[name] =
std::pair<std::string, std::vector<uint8_t>>(bName, std::vector<uint8_t>());
binMapping[name].second.resize(size); //uint8_t will ensure it is a byte addrressing
memcpy(binMapping[name].second.data(), data, size);
}
24 changes: 24 additions & 0 deletions bouncer/src/repo/core/model/bson/repo_bson_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,30 @@ namespace repo {
RepoBSONBuilder();
~RepoBSONBuilder();

using BinMapping = std::unordered_map<std::string, std::pair<std::string, std::vector<uint8_t>>>;

BinMapping& mapping()
{
return binMapping;
}

private:
BinMapping binMapping;

public:

// (Keep the templated definition in the header so the compiler
// can create concrete classes with the templated types when they
// are used)

template<typename T>
void appendLargeArray(std::string name, const std::vector<T>& data)
{
appendLargeArray(name, &data[0], data.size() * sizeof(data[0]));
}

void appendLargeArray(std::string name, const void* data, size_t size);

/**
* Append a vector as object into the bson
* This function creates an embedded RepoBSON and append that object as an array into the builder
Expand Down
38 changes: 37 additions & 1 deletion bouncer/src/repo/core/model/bson/repo_bson_element.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "repo_bson_element.h"
#include "../../../lib/datastructure/repo_variant.h"
#include "../../../lib/repo_exception.h"

using namespace repo::core::model;

Expand Down Expand Up @@ -64,4 +66,38 @@ ElementType RepoBSONElement::type() const
}

return elementType;
}
}

repo::lib::RepoVariant RepoBSONElement::repoVariant() const
{
repo::lib::RepoVariant v;
switch (type())
{
case ElementType::BOOL:
v = Bool();
break;
case ElementType::DATE:
{
tm time;
auto d = date();
d.toTm(&time);
v = time;
}
break;
case ElementType::INT:
v = Int();
break;
case ElementType::LONG:
v = Long();
break;
case ElementType::DOUBLE:
v = Double();
break;
case ElementType::STRING:
v = String();
break;
default:
throw repo::lib::RepoException("Cannot convert BSONElement to Variant because Variant will not accept the type.");
}
return v;
}
Loading

0 comments on commit 1b08aa4

Please sign in to comment.