Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add caching for versions infos #900

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (C) 2020 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
* License-Filename: LICENSE
*/

#pragma once

#include <olp/core/cache/KeyValueCache.h>
#include <rapidjson/document.h>

namespace olp {
namespace parser {
template <typename T>
inline T parse(const cache::KeyValueCache::ValueType& cached_json) {
rapidjson::Document doc;
T result{};
if (!cached_json.empty()) {
auto* data = static_cast<const void*>(cached_json.data());
doc.Parse(static_cast<const char*>(data), cached_json.size());
if (doc.IsObject() || doc.IsArray()) {
from_json(doc, result);
}
}
return result;
}

} // namespace parser
} // namespace olp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright (C) 2020 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
* License-Filename: LICENSE
*/

#include "VersionInfosSerializer.h"

#include <olp/core/generated/serializer/SerializerWrapper.h>

namespace olp {
namespace serializer {

void to_json(const dataservice::read::model::VersionDependency& x,
rapidjson::Value& value,
rapidjson::Document::AllocatorType& allocator) {
value.SetObject();
serialize("hrn", x.GetHrn(), value, allocator);
serialize("version", x.GetVersion(), value, allocator);
serialize("direct", x.GetDirect(), value, allocator);
}

void to_json(const dataservice::read::model::VersionInfo& x,
rapidjson::Value& value,
rapidjson::Document::AllocatorType& allocator) {
value.SetObject();
serialize("dependencies", x.GetDependencies(), value, allocator);
serialize("timestamp", x.GetTimestamp(), value, allocator);
serialize("version", x.GetVersion(), value, allocator);
serialize("partitionCounts", x.GetPartitionCounts(), value, allocator);
}

void to_json(const dataservice::read::model::VersionInfos& x,
rapidjson::Value& value,
rapidjson::Document::AllocatorType& allocator) {
value.SetObject();
serialize("versions", x.GetVersions(), value, allocator);
}
} // namespace serializer
} // namespace olp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (C) 2020 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
* License-Filename: LICENSE
*/

#pragma once

#include <rapidjson/document.h>
#include "olp/dataservice/read/model/VersionInfos.h"

namespace olp {
namespace serializer {

void to_json(const dataservice::read::model::VersionDependency& x,
rapidjson::Value& value,
rapidjson::Document::AllocatorType& allocator);

void to_json(const dataservice::read::model::VersionInfo& x,
rapidjson::Value& value,
rapidjson::Document::AllocatorType& allocator);

void to_json(const dataservice::read::model::VersionInfos& x,
rapidjson::Value& value,
rapidjson::Document::AllocatorType& allocator);
} // namespace serializer
} // namespace olp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 HERE Europe B.V.
* Copyright (C) 2019-2020 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,17 +19,22 @@

#include "CatalogCacheRepository.h"

#include <limits>
#include <string>
#include <vector>

#include <olp/core/cache/KeyValueCache.h>
#include <olp/core/logging/Log.h>

// clang-format off
#include "generated/parser/CatalogParser.h"
#include "generated/parser/VersionInfosParser.h"
#include "generated/parser/VersionResponseParser.h"
#include "generated/parser/JsonParserCacheValue.h"
#include <olp/core/generated/parser/JsonParser.h>
#include "generated/serializer/CatalogSerializer.h"
#include "generated/serializer/VersionResponseSerializer.h"
#include "generated/serializer/VersionInfosSerializer.h"
#include "generated/serializer/JsonSerializer.h"
// clang-format on

Expand All @@ -46,6 +51,11 @@ std::string CreateKey(const std::string& hrn) { return hrn + "::catalog"; }
std::string VersionKey(const std::string& hrn) {
return hrn + "::latestVersion";
}
std::string VersionInfosKey(const std::string& hrn, std::int64_t start,
std::int64_t end) {
return hrn + "::" + std::to_string(start) + "::" + std::to_string(end) +
"::versionInfos";
}

time_t ConvertTime(std::chrono::seconds time) {
return time == kChronoSecondsMax ? kTimetMax : time.count();
Expand Down Expand Up @@ -111,6 +121,32 @@ boost::optional<model::VersionResponse> CatalogCacheRepository::GetVersion() {
return boost::any_cast<model::VersionResponse>(cached_version);
}

void CatalogCacheRepository::PutVersionInfos(
std::int64_t start, std::int64_t end, const model::VersionInfos& versions) {
std::string hrn(hrn_.ToCatalogHRNString());
auto key = VersionInfosKey(hrn, start, end);
OLP_SDK_LOG_DEBUG_F(kLogTag, "PutVersionInfos -> '%s'", key.c_str());
auto list_versions = olp::serializer::serialize(versions);

auto versions_data = std::make_shared<cache::KeyValueCache::ValueType>(
list_versions.data(), list_versions.data() + list_versions.size());
cache_->Put(VersionInfosKey(hrn, start, end), versions_data, default_expiry_);
}

boost::optional<model::VersionInfos> CatalogCacheRepository::GetVersionInfos(
std::int64_t start, std::int64_t end) {
std::string hrn(hrn_.ToCatalogHRNString());
auto key = VersionInfosKey(hrn, start, end);
OLP_SDK_LOG_DEBUG_F(kLogTag, "GetVersionInfos -> '%s'", key.c_str());

auto value = cache_->Get(key);
if (!value) {
return boost::none;
}

return parser::parse<model::VersionInfos>(*value);
}

void CatalogCacheRepository::Clear() {
std::string hrn(hrn_.ToCatalogHRNString());
OLP_SDK_LOG_INFO_F(kLogTag, "Clear -> '%s'", CreateKey(hrn).c_str());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 HERE Europe B.V.
* Copyright (C) 2019-2020 HERE Europe B.V.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -24,6 +24,7 @@

#include <olp/core/client/HRN.h>
#include <olp/dataservice/read/model/Catalog.h>
#include <olp/dataservice/read/model/VersionInfos.h>
#include <olp/dataservice/read/model/VersionResponse.h>
#include <boost/optional.hpp>

Expand Down Expand Up @@ -51,6 +52,12 @@ class CatalogCacheRepository final {

boost::optional<model::VersionResponse> GetVersion();

void PutVersionInfos(std::int64_t start, std::int64_t end,
const model::VersionInfos& versions);

boost::optional<model::VersionInfos> GetVersionInfos(std::int64_t start,
std::int64_t end);

void Clear();

private:
Expand Down
61 changes: 55 additions & 6 deletions olp-cpp-sdk-dataservice-read/tests/CatalogCacheRepositoryTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,25 @@

namespace {

using namespace olp;
using namespace olp::dataservice::read;
namespace read = olp::dataservice::read;
namespace client = olp::client;
namespace cache = olp::cache;

constexpr auto kCatalog = "hrn:here:data::olp-here-test:catalog";

TEST(PartitionsCacheRepositoryTest, DefaultExpiry) {
TEST(CatalogCacheRepositoryTest, DefaultExpiry) {
const auto hrn = client::HRN::FromString(kCatalog);

model::Catalog model_catalog;
read::model::Catalog model_catalog;

{
SCOPED_TRACE("Disable expiration");

const auto default_expiry = std::chrono::seconds::max();
std::shared_ptr<cache::KeyValueCache> cache =
olp::client::OlpClientSettingsFactory::CreateDefaultCache({});
repository::CatalogCacheRepository repository(hrn, cache, default_expiry);
read::repository::CatalogCacheRepository repository(hrn, cache,
default_expiry);

repository.Put(model_catalog);
const auto result = repository.Get();
Expand All @@ -56,7 +58,8 @@ TEST(PartitionsCacheRepositoryTest, DefaultExpiry) {
const auto default_expiry = std::chrono::seconds(-1);
std::shared_ptr<cache::KeyValueCache> cache =
olp::client::OlpClientSettingsFactory::CreateDefaultCache({});
repository::CatalogCacheRepository repository(hrn, cache, default_expiry);
read::repository::CatalogCacheRepository repository(hrn, cache,
default_expiry);

repository.Put(model_catalog);
const auto result = repository.Get();
Expand All @@ -65,4 +68,50 @@ TEST(PartitionsCacheRepositoryTest, DefaultExpiry) {
}
}

TEST(CatalogCacheRepositoryTest, VersionsList) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also add a test case for start_version = -1 as specified by the documentation:

startVersion
The beginning of the range of versions you want to get (exclusive). By convention -1 indicates the initial version before the first publication. After the first publication, the catalog version is 0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test will be added to CatalogRepositoryTest

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But why in CatalogRepositoryTest as this will have direct implication upon the key generation, which needs to be tested that it works correctly, means that not by mistake the -1 startVersion is converted to 0 as we do not support -1 while converting to string.

const auto hrn = client::HRN::FromString(kCatalog);

read::model::VersionInfos model_versions;
model_versions.SetVersions(
std::vector<olp::dataservice::read::model::VersionInfo>(1));
const auto default_expiry = std::chrono::seconds::max();
std::shared_ptr<cache::KeyValueCache> cache =
olp::client::OlpClientSettingsFactory::CreateDefaultCache({});
read::repository::CatalogCacheRepository repository(hrn, cache,
default_expiry);

{
SCOPED_TRACE("Put/get versions list");

repository.PutVersionInfos(3, 4, model_versions);
const auto result = repository.GetVersionInfos(3, 4);

EXPECT_TRUE(result);
EXPECT_EQ(1u, result->GetVersions().size());
}

{
SCOPED_TRACE("Get versions list wrong key");

const auto result = repository.GetVersionInfos(300, 3001);

EXPECT_FALSE(result);
}

{
SCOPED_TRACE("List versions expired");

const auto default_expiry = std::chrono::seconds(-1);
std::shared_ptr<cache::KeyValueCache> cache_expiration =
olp::client::OlpClientSettingsFactory::CreateDefaultCache({});
read::repository::CatalogCacheRepository repository_expiration(
hrn, cache_expiration, default_expiry);

repository_expiration.PutVersionInfos(3, 4, model_versions);
const auto result = repository_expiration.GetVersionInfos(3, 4);

EXPECT_FALSE(result);
}
}

} // namespace