Skip to content

Commit

Permalink
feat(dto): add custom dto vector type
Browse files Browse the repository at this point in the history
This improves performances by avoiding conversion to oatpp::Vector<oatpp::Void>
  • Loading branch information
Bycob authored and mergify[bot] committed Aug 25, 2021
1 parent 4435540 commit 01222db
Show file tree
Hide file tree
Showing 8 changed files with 365 additions and 128 deletions.
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ set(ddetect_SOURCES deepdetect.h deepdetect.cc mllibstrategy.h mlmodel.h
svminputfileconn.h svminputfileconn.cc txtinputfileconn.h
txtinputfileconn.cc apidata.h apidata.cc chain_actions.h chain_actions.cc
service_stats.h service_stats.cc chain.h chain.cc ext/rmustache/mustache.h ext/rmustache/mustache.cc
utils/oatpp.cc dto/gpuid.cc utils/db.cpp utils/db_lmdb.cpp ${CMAKE_BINARY_DIR}/src/caffe.pb.cc)
utils/oatpp.cc dto/ddtypes.cc utils/db.cpp utils/db_lmdb.cpp ${CMAKE_BINARY_DIR}/src/caffe.pb.cc)

if (USE_JSON_API)
list(APPEND ddetect_SOURCES jsonapi.h jsonapi.cc)
Expand Down
8 changes: 7 additions & 1 deletion src/dto/gpuid.cc → src/dto/ddtypes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
* along with deepdetect. If not, see <http://www.gnu.org/licenses/>.
*/

#include "gpuid.hpp"
#include "ddtypes.hpp"

namespace dd
{
Expand All @@ -28,6 +28,12 @@ namespace dd
namespace __class
{
const oatpp::ClassId GpuIdsClass::CLASS_ID("GpuIds");

template <>
const oatpp::ClassId DTOVectorClass<double>::CLASS_ID("vector<double>");

template <>
const oatpp::ClassId DTOVectorClass<bool>::CLASS_ID("vector<bool>");
}
}
}
275 changes: 275 additions & 0 deletions src/dto/ddtypes.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
/**
* DeepDetect
* Copyright (c) 2021 Jolibrain SASU
* Author: Louis Jean <louis.jean@jolibrain.com>
*
* This file is part of deepdetect.
*
* deepdetect is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* deepdetect is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with deepdetect. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef DD_DTO_TYPES_HPP
#define DD_DTO_TYPES_HPP

#include "oatpp/core/Types.hpp"
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"

namespace dd
{
namespace DTO
{
struct VGpuIds
{
std::vector<int> _ids;

VGpuIds() : _ids({ 0 })
{
}
VGpuIds(const oatpp::Vector<oatpp::Int32> &vec)
: _ids(vec->begin(), vec->end())
{
}
VGpuIds(oatpp::Int32 i) : _ids({ i })
{
}
};

template <typename T> struct VVector
{
std::vector<T> _vec;

VVector() = default;

VVector(const std::vector<T> &vec) : _vec(vec)
{
}
VVector(std::vector<T> &&vec) : _vec(vec)
{
}
std::vector<T> &operator*()
{
return _vec;
}
const std::vector<T> &operator*() const
{
return _vec;
}
std::vector<T> *operator->()
{
return &_vec;
}
const std::vector<T> operator->() const
{
return &_vec;
}
};

namespace __class
{
class GpuIdsClass;
template <typename T> class DTOVectorClass;
}

typedef oatpp::data::mapping::type::Primitive<VGpuIds,
__class::GpuIdsClass>
GpuIds;
template <typename T>
using DTOVector
= oatpp::data::mapping::type::Primitive<VVector<T>,
__class::DTOVectorClass<T>>;

namespace __class
{
class GpuIdsClass
{
public:
static const oatpp::ClassId CLASS_ID;

static oatpp::Type *getType()
{
static oatpp::Type type(CLASS_ID, nullptr, nullptr);
return &type;
}
};

template <typename T> class DTOVectorClass
{
public:
static const oatpp::ClassId CLASS_ID;

static oatpp::Type *getType()
{
static oatpp::Type type(CLASS_ID, nullptr, nullptr);
return &type;
}
};

template class DTOVectorClass<double>;
template class DTOVectorClass<bool>;
}

// ==== Serialization methods

static inline oatpp::Void
gpuIdsDeserialize(oatpp::parser::json::mapping::Deserializer *deserializer,
oatpp::parser::Caret &caret,
const oatpp::Type *const type)
{
(void)type;
if (caret.isAtChar('['))
{
return GpuIds(VGpuIds{
deserializer
->deserialize(caret,
oatpp::Vector<oatpp::Int32>::Class::getType())
.staticCast<oatpp::Vector<oatpp::Int32>>() });
}
else
{
return GpuIds(VGpuIds{
deserializer->deserialize(caret, oatpp::Int32::Class::getType())
.staticCast<oatpp::Int32>() });
}
}

static inline void
gpuIdsSerialize(oatpp::parser::json::mapping::Serializer *serializer,
oatpp::data::stream::ConsistentOutputStream *stream,
const oatpp::Void &obj)
{
auto gpuid = obj.staticCast<GpuIds>();
if (gpuid->_ids.size() == 1)
{
oatpp::Int32 id = gpuid->_ids[0];
serializer->serializeToStream(stream, id);
}
else
{
oatpp::Vector<oatpp::Int32> ids;
for (auto i : gpuid->_ids)
{
ids->push_back(i);
}
serializer->serializeToStream(stream, ids);
}
}

// Inspired by oatpp json deserializer
template <typename T> inline T readVecElement(oatpp::parser::Caret &caret);

template <>
inline double readVecElement<double>(oatpp::parser::Caret &caret)
{
return caret.parseFloat64();
}

template <> inline bool readVecElement<bool>(oatpp::parser::Caret &caret)
{
if (caret.isAtText("true"))
{
return true;
}
else if (caret.isAtText("false"))
{
return false;
}
else
{
caret.setError("[readVecElement<bool>] expected 'true' or 'false'",
oatpp::parser::json::mapping::Deserializer::
ERROR_CODE_VALUE_BOOLEAN);
return false;
}
}

template <typename T>
static inline oatpp::Void
vectorDeserialize(oatpp::parser::json::mapping::Deserializer *deserializer,
oatpp::parser::Caret &caret,
const oatpp::Type *const type)
{
(void)deserializer;
(void)type;
if (caret.isAtText("null", true))
{
return oatpp::Void(type);
}

if (caret.canContinueAtChar('[', 1))
{
std::vector<T> vec;

while (!caret.isAtChar(']') && caret.canContinue())
{
caret.skipBlankChars();
vec.push_back(caret.parseFloat64());
if (caret.hasError())
{
return nullptr;
}
caret.skipBlankChars();
caret.canContinueAtChar(',', 1);
}

if (!caret.canContinueAtChar(']', 1))
{
if (!caret.hasError())
{
caret.setError(
"[oatpp::parser::json::mapping::Deserializer::"
"deserializeList()]: Error. ']' - expected",
oatpp::parser::json::mapping::Deserializer::
ERROR_CODE_ARRAY_SCOPE_CLOSE);
}
return nullptr;
};

return DTOVector<T>(std::move(vec));
}
else
{
caret.setError("[oatpp::parser::json::mapping::Deserializer::"
"deserializeList()]: Error. '[' - expected",
oatpp::parser::json::mapping::Deserializer::
ERROR_CODE_ARRAY_SCOPE_OPEN);
return nullptr;
}
}

template <typename T>
static inline void
vectorSerialize(oatpp::parser::json::mapping::Serializer *serializer,
oatpp::data::stream::ConsistentOutputStream *stream,
const oatpp::Void &obj)
{
(void)serializer;
auto vec = obj.staticCast<DTOVector<T>>();
stream->writeCharSimple('[');
bool first = true;

for (auto val : vec->_vec)
{
if (first)
first = false;
else
stream->writeCharSimple(',');
stream->writeAsString(val);
}

stream->writeCharSimple(']');
}
}
}

#endif // DD_DTO_TYPES_HPP
Loading

0 comments on commit 01222db

Please sign in to comment.