Introduce LazyStringMap

This commit is contained in:
lganzzzo 2019-10-12 18:42:42 +03:00
parent 9e9b5dc904
commit d67fa0ff53
7 changed files with 228 additions and 5 deletions

View File

@ -84,6 +84,7 @@ add_library(oatpp
oatpp/core/data/mapping/type/Primitive.hpp
oatpp/core/data/mapping/type/Type.cpp
oatpp/core/data/mapping/type/Type.hpp
oatpp/core/data/share/LazyStringMap.hpp
oatpp/core/data/share/MemoryLabel.cpp
oatpp/core/data/share/MemoryLabel.hpp
oatpp/core/data/stream/BufferStream.cpp

View File

@ -0,0 +1,106 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
*
* 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.
*
***************************************************************************/
#ifndef oatpp_data_share_LazyStringMap_hpp
#define oatpp_data_share_LazyStringMap_hpp
#include "./MemoryLabel.hpp"
#include <unordered_map>
namespace oatpp { namespace data { namespace share {
class LazyStringMap {
public:
typedef StringKeyLabelCI Key;
private:
bool m_fullyInitialized;
std::unordered_map<Key, StringKeyLabel> m_map;
public:
LazyStringMap()
: m_fullyInitialized(false)
{}
LazyStringMap(LazyStringMap&& other)
: m_fullyInitialized(false)
, m_map(std::move(other.m_map))
{}
LazyStringMap& operator = (LazyStringMap&& other){
m_fullyInitialized = false;
m_map = std::move(other.m_map);
return *this;
}
void put(const Key& key, const StringKeyLabel& value) {
m_map.insert({key, value});
}
bool putIfNotExists(const Key& key, const StringKeyLabel& value) {
auto it = m_map.find(key);
if(it == m_map.end()) {
m_map.insert({key, value});
return true;
}
return false;
}
oatpp::String get(const Key& key) {
auto it = m_map.find(key);
if(it != m_map.end()) {
it->second.captureToOwnMemory();
return it->second.getMemoryHandle();
}
return nullptr;
}
const std::unordered_map<Key, StringKeyLabel>& getAll() {
if(!m_fullyInitialized) {
for(auto& pair : m_map) {
pair.first.captureToOwnMemory();
pair.second.captureToOwnMemory();
}
m_fullyInitialized = true;
}
return m_map;
}
};
}}}
#endif //oatpp_data_share_LazyStringMap_hpp

View File

@ -37,8 +37,8 @@ namespace oatpp { namespace data { namespace share {
*/
class MemoryLabel {
protected:
std::shared_ptr<base::StrBuffer> m_memoryHandle;
p_char8 m_data;
mutable std::shared_ptr<base::StrBuffer> m_memoryHandle;
mutable p_char8 m_data;
v_int32 m_size;
public:
@ -89,6 +89,16 @@ public:
return m_memoryHandle;
}
/**
* Capture data referenced by memory label to its own memory.
*/
void captureToOwnMemory() const {
if(!m_memoryHandle || m_memoryHandle->getData() != m_data || m_memoryHandle->getSize() != m_size) {
m_memoryHandle.reset(new base::StrBuffer(m_data, m_size, true));
m_data = m_memoryHandle->getData();
}
}
/**
* Check if labeled data equals to data specified.
* Data is compared using &id:oatpp::base::StrBuffer::equals;.

View File

@ -15,6 +15,8 @@ add_executable(oatppAllTests
oatpp/core/base/memory/PerfTest.hpp
oatpp/core/data/mapping/type/TypeTest.cpp
oatpp/core/data/mapping/type/TypeTest.hpp
oatpp/core/data/share/LazyStringMapTest.cpp
oatpp/core/data/share/LazyStringMapTest.hpp
oatpp/core/data/share/MemoryLabelTest.cpp
oatpp/core/data/share/MemoryLabelTest.hpp
oatpp/core/data/stream/BufferStreamTest.cpp

View File

@ -18,6 +18,7 @@
#include "oatpp/core/data/stream/BufferStreamTest.hpp"
#include "oatpp/core/data/stream/ChunkedBufferTest.hpp"
#include "oatpp/core/data/share/LazyStringMapTest.hpp"
#include "oatpp/core/data/share/MemoryLabelTest.hpp"
#include "oatpp/parser/json/mapping/DeserializerTest.hpp"
@ -56,7 +57,7 @@ void runTests() {
OATPP_LOGD("aaa", "coroutine size=%d", sizeof(oatpp::async::AbstractCoroutine));
OATPP_LOGD("aaa", "action size=%d", sizeof(oatpp::async::Action));
/*
OATPP_RUN_TEST(oatpp::test::base::RegRuleTest);
OATPP_RUN_TEST(oatpp::test::base::CommandLineArgumentsTest);
@ -66,7 +67,9 @@ void runTests() {
OATPP_RUN_TEST(oatpp::test::collection::LinkedListTest);
OATPP_RUN_TEST(oatpp::test::core::data::share::MemoryLabelTest);
*/
OATPP_RUN_TEST(oatpp::test::core::data::share::LazyStringMapTest);
/*
OATPP_RUN_TEST(oatpp::test::core::data::stream::ChunkedBufferTest);
OATPP_RUN_TEST(oatpp::test::core::data::stream::BufferStreamTest);
@ -141,7 +144,7 @@ void runTests() {
test_port.run(1);
}
*/
}
}

View File

@ -0,0 +1,59 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
*
* 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.
*
***************************************************************************/
#include "LazyStringMapTest.hpp"
#include "oatpp/core/data/share/LazyStringMap.hpp"
namespace oatpp { namespace test { namespace core { namespace data { namespace share {
namespace {
typedef oatpp::data::share::LazyStringMap LazyStringMap;
typedef oatpp::data::share::StringKeyLabel StringKeyLabel;
}
void LazyStringMapTest::onRun() {
p_char8 text = (p_char8) "Hello World!";
LazyStringMap map;
map.put("key1", StringKeyLabel(nullptr, text, 5));
map.put("key2", StringKeyLabel(nullptr, text + 6, 6));
oatpp::String s1 = map.get("key1");
oatpp::String s2 = map.get("key2");
OATPP_ASSERT(s1 == "Hello");
OATPP_ASSERT(s2 == "World!");
oatpp::String s12 = map.get("key1");
oatpp::String s22 = map.get("key2");
OATPP_ASSERT(s1.get() == s12.get());
OATPP_ASSERT(s2.get() == s22.get());
}
}}}}}

View File

@ -0,0 +1,42 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
*
* 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.
*
***************************************************************************/
#ifndef oatpp_test_core_data_share_LazyStringMapTest_hpp
#define oatpp_test_core_data_share_LazyStringMapTest_hpp
#include "oatpp-test/UnitTest.hpp"
namespace oatpp { namespace test { namespace core { namespace data { namespace share {
class LazyStringMapTest : public UnitTest{
public:
LazyStringMapTest():UnitTest("TEST[core::data::share::LazyStringMapTest]"){}
void onRun() override;
};
}}}}}
#endif // oatpp_test_core_data_share_LazyStringMapTest_hpp