From 5578af39480a9f99ed6f40c633a3289ed5ed0515 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Me=C3=9Fmer?= Date: Thu, 2 Apr 2015 11:39:44 -0400 Subject: [PATCH 01/44] Initial version --- .travis.yml | 24 ++++++++ CMakeLists.txt | 91 ++++++++++++++++++++++++++++ CachingStore.h | 146 +++++++++++++++++++++++++++++++++++++++++++++ biicode.conf | 49 +++++++++++++++ test/DummyTest.cpp | 5 ++ test/main.cpp | 6 ++ 6 files changed, 321 insertions(+) create mode 100644 .travis.yml create mode 100644 CMakeLists.txt create mode 100644 CachingStore.h create mode 100644 biicode.conf create mode 100644 test/DummyTest.cpp create mode 100644 test/main.cpp diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..279afadd --- /dev/null +++ b/.travis.yml @@ -0,0 +1,24 @@ +language: cpp +compiler: +- gcc +before_install: +- wget https://raw.githubusercontent.com/smessmer/travis-utils/master/update_gcc_version.sh + && chmod +x update_gcc_version.sh + && ./update_gcc_version.sh 4.9 + && rm update_gcc_version.sh +before_script: +- wget https://raw.githubusercontent.com/smessmer/travis-utils/master/setup_biicode_project.sh + && chmod +x setup_biicode_project.sh + && ./setup_biicode_project.sh + && rm setup_biicode_project.sh +script: +- bii cpp:build --target messmer_cachingstore_test_main -- -j2 +- "./bin/messmer_cachingstore_test_main" +deploy: + provider: biicode + user: ${BII_USERNAME} + password: + secure: ${BII_PASSWORD} + on: + branch: develop + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..63322e29 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,91 @@ +INCLUDE(messmer/cmake/tools) + +ADD_BIICODE_TARGETS() + +ACTIVATE_CPP14() + +# You can safely delete lines from here... + +############################################################################### +# REFERENCE # +############################################################################### +# +# This CMakeLists.txt file helps defining your block building and compiling +# To learn more about the CMake use with biicode, visit http://docs.biicode.com/c++.html +# +# ---------------------------------------------------- +# NEW FEATURE! Include cmake files from remote blocks: +# ----------------------------------------------------- +# Now you can handle cmake dependencies alike you do with c/c++: +# +# INCLUDE(user/block/myrecipe) # include myrecipe.cmake from remote user/block +# +# > EXAMPLE: Include our recipes and activate C++11 in your block (http://www.biicode.com/biicode/cmake) +# +# INCLUDE(biicode/cmake/tools) # Include tools.cmake file from cmake block from the "biicode" user +# ACTIVATE_CPP11(INTERFACE ${BII_BLOCK_TARGET}) +# +# Remember to run "bii find" to download out cmake tools file +# +# --------------------- +# INIT_BIICODE_BLOCK() +# --------------------- +# This function creates several helper variables as ${BII_BLOCK_NAME} and ${BII_BLOCK_USER} +# Also it loads variables from the cmake/bii_user_block_vars.cmake +# ${BII_LIB_SRC} File list to create the library +# ${BII_LIB_TYPE} Empty (default, STATIC most casess) STATIC or SHARED +# ${BII_LIB_DEPS} Dependencies to other libraries (user2_block2, user3_blockX) +# ${BII_LIB_SYSTEM_HEADERS} System linking requirements as windows.h, pthread.h, etc +# +# You can use or modify them here, for example, to add or remove files from targets based on OS +# Or use typical cmake configurations done BEFORE defining targets. Examples: +# ADD_DEFINITIONS(-DFOO) +# FIND_PACKAGE(OpenGL QUIET) +# You can add INCLUDE_DIRECTORIES here too +# +# --------------------- +# ADD_BIICODE_TARGETS() +# --------------------- +# +# This function creates the following variables: +# ${BII_BLOCK_TARGET} Interface (no files) target for convenient configuration of all +# targets in this block, as the rest of targets always depend on it +# has name in the form "user_block_interface" +# ${BII_LIB_TARGET} Target library name, usually in the form "user_block". May not exist +# if BII_LIB_SRC is empty +# ${BII_BLOCK_TARGETS} List of all targets defined in this block +# ${BII_BLOCK_EXES} List of executables targets defined in this block +# ${BII_exe_name_TARGET}: Executable target (e.g. ${BII_main_TARGET}. You can also use +# directly the name of the executable target (e.g. user_block_main) +# +# > EXAMPLE: Add include directories to all targets of this block +# +# TARGET_INCLUDE_DIRECTORIES(${BII_BLOCK_TARGET} INTERFACE myincludedir) +# +# You can add private include directories to the Lib (if existing) +# +# > EXAMPLE: Link with pthread: +# +# TARGET_LINK_LIBRARIES(${BII_BLOCK_TARGET} INTERFACE pthread) +# or link against library: +# TARGET_LINK_LIBRARIES(${BII_LIB_TARGET} PUBLIC pthread) +# or directly use the library target name: +# TARGET_LINK_LIBRARIES(user_block PUBLIC pthread) +# +# NOTE: This can be also done adding pthread to ${BII_LIB_DEPS} +# BEFORE calling ADD_BIICODE_TARGETS() +# +# > EXAMPLE: how to activate C++11 +# +# IF(APPLE) +# TARGET_COMPILE_OPTIONS(${BII_BLOCK_TARGET} INTERFACE "-std=c++11 -stdlib=libc++") +# ELSEIF (WIN32 OR UNIX) +# TARGET_COMPILE_OPTIONS(${BII_BLOCK_TARGET} INTERFACE "-std=c++11") +# ENDIF(APPLE) +# +# > EXAMPLE: Set properties to target +# +# SET_TARGET_PROPERTIES(${BII_BLOCK_TARGET} PROPERTIES COMPILE_DEFINITIONS "IOV_MAX=255") +# + + diff --git a/CachingStore.h b/CachingStore.h new file mode 100644 index 00000000..0fa01921 --- /dev/null +++ b/CachingStore.h @@ -0,0 +1,146 @@ +#ifndef MESSMER_BLOCKSTORE_IMPLEMENTATIONS_CACHING_CACHINGSTORE_H_ +#define MESSMER_BLOCKSTORE_IMPLEMENTATIONS_CACHING_CACHINGSTORE_H_ + +#include +#include +#include +#include +#include +#include + +//TODO Test CachingStore + +template +class CachingStore { +public: + CachingStore(): _mutex(), _openResources(), _resourcesToRemove() {} + + //TODO Enforce CachedResourceRef inherits from CachedResource + class CachedResource { + public: + //TODO Better way to initialize + CachedResource(): _cachingStore(nullptr), _key(Key::CreateRandomKey()) {} + void init(CachingStore *cachingStore, const Key &key) { + _cachingStore = cachingStore; + _key = key; + } + virtual ~CachedResource() { + _cachingStore->release(_key); + } + private: + CachingStore *_cachingStore; + //TODO We're storing Key twice (here and in the base resource). Rather use getKey() on the base resource if possible somehow. + Key _key; + }; + + std::unique_ptr add(const Key &key, std::unique_ptr resource); + std::unique_ptr load(const Key &key); + void remove(const Key &key, std::unique_ptr block); + +protected: + virtual std::unique_ptr loadFromBaseStore(const Key &key) = 0; + virtual void removeFromBaseStore(std::unique_ptr resource) = 0; + +private: + class OpenResource { + public: + OpenResource(std::unique_ptr resource): _resource(std::move(resource)), _refCount(0) {} + + Resource *getReference() { + ++_refCount; + return _resource.get(); + } + + void releaseReference() { + --_refCount; + } + + bool refCountIsZero() const { + return 0 == _refCount; + } + + std::unique_ptr moveResourceOut() { + return std::move(_resource); + } + private: + std::unique_ptr _resource; + uint32_t _refCount; + }; + + std::mutex _mutex; + std::map _openResources; + std::map>> _resourcesToRemove; + + std::unique_ptr _add(const Key &key, std::unique_ptr resource); + std::unique_ptr _createCachedResourceRef(Resource *resource, const Key &key); + + void release(const Key &key); + friend class CachedResource; + + DISALLOW_COPY_AND_ASSIGN(CachingStore); +}; + +template +std::unique_ptr CachingStore::add(const Key &key, std::unique_ptr resource) { + std::lock_guard lock(_mutex); + return _add(key, std::move(resource)); +} + +template +std::unique_ptr CachingStore::_add(const Key &key, std::unique_ptr resource) { + auto insertResult = _openResources.emplace(key, std::move(resource)); + assert(true == insertResult.second); + return _createCachedResourceRef(insertResult.first->second.getReference(), key); +} + +template +std::unique_ptr CachingStore::_createCachedResourceRef(Resource *resource, const Key &key) { + auto resourceRef = std::make_unique(resource); + resourceRef->init(this, key); + return std::move(resourceRef); +} + +template +std::unique_ptr CachingStore::load(const Key &key) { + std::lock_guard lock(_mutex); + auto found = _openResources.find(key); + if (found == _openResources.end()) { + auto resource = loadFromBaseStore(key); + if (resource.get() == nullptr) { + return nullptr; + } + return _add(key, std::move(resource)); + } else { + return _createCachedResourceRef(found->second.getReference(), key); + } +} + +template +void CachingStore::remove(const Key &key, std::unique_ptr resource) { + auto insertResult = _resourcesToRemove.emplace(key, std::promise>()); + assert(true == insertResult.second); + resource.reset(); + + //Wait for last resource user to release it + auto resourceToRemove = insertResult.first->second.get_future().get(); + + removeFromBaseStore(std::move(resourceToRemove)); +} + +template +void CachingStore::release(const Key &key) { + std::lock_guard lock(_mutex); + auto found = _openResources.find(key); + assert (found != _openResources.end()); + found->second.releaseReference(); + if (found->second.refCountIsZero()) { + auto foundToRemove = _resourcesToRemove.find(key); + if (foundToRemove != _resourcesToRemove.end()) { + foundToRemove->second.set_value(found->second.moveResourceOut()); + } + _openResources.erase(found); + } +} + + +#endif diff --git a/biicode.conf b/biicode.conf new file mode 100644 index 00000000..2beadd49 --- /dev/null +++ b/biicode.conf @@ -0,0 +1,49 @@ +# Biicode configuration file + +[requirements] + google/gtest: 10 + messmer/cmake: 3 + messmer/cpp-utils: 2 + +[parent] + # The parent version of this block. Must match folder name. E.g. + # user/block # No version number means not published yet + # You can change it to publish to a different track, and change version, e.g. + # user/block(track): 7 + +[paths] + # Local directories to look for headers (within block) + # / + # include + +[dependencies] + # Manual adjust file implicit dependencies, add (+), remove (-), or overwrite (=) + # hello.h + hello_imp.cpp hello_imp2.cpp + # *.h + *.cpp + test/main.cpp + test/*.cpp + +[mains] + # Manual adjust of files that define an executable + # !main.cpp # Do not build executable from this file + # main2.cpp # Build it (it doesnt have a main() function, but maybe it includes it) + +[tests] + # Manual adjust of files that define a CTest test + # test/* pattern to evaluate this test/ folder sources like tests + test/* + +[hooks] + # These are defined equal to [dependencies],files names matching bii*stage*hook.py + # will be launched as python scripts at stage = {post_process, clean} + # CMakeLists.txt + bii/my_post_process1_hook.py bii_clean_hook.py + +[includes] + # Mapping of include patterns to external blocks + # hello*.h: user3/depblock # includes will be processed as user3/depblock/hello*.h + +[data] + # Manually define data files dependencies, that will be copied to bin for execution + # By default they are copied to bin/user/block/... which should be taken into account + # when loading from disk such data + # image.cpp + image.jpg # code should write open("user/block/image.jpg") + diff --git a/test/DummyTest.cpp b/test/DummyTest.cpp new file mode 100644 index 00000000..c0f770b3 --- /dev/null +++ b/test/DummyTest.cpp @@ -0,0 +1,5 @@ +#include + +TEST(Dummy, DummyTest) { +} + diff --git a/test/main.cpp b/test/main.cpp new file mode 100644 index 00000000..f7a14877 --- /dev/null +++ b/test/main.cpp @@ -0,0 +1,6 @@ +#include "google/gtest/gtest.h" + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} From 9de711b881c144e0ae37a32992807dcd9b0aec59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Me=C3=9Fmer?= Date: Thu, 2 Apr 2015 12:18:44 -0400 Subject: [PATCH 02/44] Refactoring --- CachingBaseStore.h | 18 +++++++++++++++++ CachingStore.h | 38 ++++++++++++++++++++++------------- test/CachingBaseStoreTest.cpp | 3 +++ 3 files changed, 45 insertions(+), 14 deletions(-) create mode 100644 CachingBaseStore.h create mode 100644 test/CachingBaseStoreTest.cpp diff --git a/CachingBaseStore.h b/CachingBaseStore.h new file mode 100644 index 00000000..3a7d1ed3 --- /dev/null +++ b/CachingBaseStore.h @@ -0,0 +1,18 @@ +#ifndef MESSMER_CACHINGSTORE_CACHINGBASESTORE_H_ +#define MESSMER_CACHINGSTORE_CACHINGBASESTORE_H_ + +#include + +namespace cachingstore { + +template +class CachingBaseStore { +public: + virtual ~CachingBaseStore() {} + virtual std::unique_ptr loadFromBaseStore(const Key &key) = 0; + virtual void removeFromBaseStore(std::unique_ptr block) = 0; +}; + +} + +#endif diff --git a/CachingStore.h b/CachingStore.h index 0fa01921..0e19159a 100644 --- a/CachingStore.h +++ b/CachingStore.h @@ -8,22 +8,33 @@ #include #include -//TODO Test CachingStore +#include "CachingBaseStore.h" + +//TODO Refactor +//TODO Test cases + +namespace cachingstore { template class CachingStore { public: - CachingStore(): _mutex(), _openResources(), _resourcesToRemove() {} + CachingStore(std::unique_ptr> baseStore) + : _mutex(), + _baseStore(std::move(baseStore)), + _openResources(), + _resourcesToRemove() { + } //TODO Enforce CachedResourceRef inherits from CachedResource + class CachedResource { public: - //TODO Better way to initialize - CachedResource(): _cachingStore(nullptr), _key(Key::CreateRandomKey()) {} - void init(CachingStore *cachingStore, const Key &key) { - _cachingStore = cachingStore; - _key = key; - } + //TODO Better way to initialize + CachedResource(): _cachingStore(nullptr), _key(Key::CreateRandomKey()) {} + void init(CachingStore *cachingStore, const Key &key) { + _cachingStore = cachingStore; + _key = key; + } virtual ~CachedResource() { _cachingStore->release(_key); } @@ -37,10 +48,6 @@ public: std::unique_ptr load(const Key &key); void remove(const Key &key, std::unique_ptr block); -protected: - virtual std::unique_ptr loadFromBaseStore(const Key &key) = 0; - virtual void removeFromBaseStore(std::unique_ptr resource) = 0; - private: class OpenResource { public: @@ -68,6 +75,8 @@ private: }; std::mutex _mutex; + std::unique_ptr> _baseStore; + std::map _openResources; std::map>> _resourcesToRemove; @@ -105,7 +114,7 @@ std::unique_ptr CachingStore::load(c std::lock_guard lock(_mutex); auto found = _openResources.find(key); if (found == _openResources.end()) { - auto resource = loadFromBaseStore(key); + auto resource = _baseStore->loadFromBaseStore(key); if (resource.get() == nullptr) { return nullptr; } @@ -124,7 +133,7 @@ void CachingStore::remove(const Key &key, std: //Wait for last resource user to release it auto resourceToRemove = insertResult.first->second.get_future().get(); - removeFromBaseStore(std::move(resourceToRemove)); + _baseStore->removeFromBaseStore(std::move(resourceToRemove)); } template @@ -142,5 +151,6 @@ void CachingStore::release(const Key &key) { } } +} #endif diff --git a/test/CachingBaseStoreTest.cpp b/test/CachingBaseStoreTest.cpp new file mode 100644 index 00000000..9e05e76b --- /dev/null +++ b/test/CachingBaseStoreTest.cpp @@ -0,0 +1,3 @@ +#include "../CachingBaseStore.h" + +// Test that CachingBaseStore.h can be included without errors From 2674a99d64bde9de75cd4ad8ee577f02cf69fe9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Me=C3=9Fmer?= Date: Sat, 4 Apr 2015 22:10:15 +0200 Subject: [PATCH 03/44] Initial commit --- .gitignore | 28 +++++++++ LICENSE | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 1 + 3 files changed, 195 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..b8bd0267 --- /dev/null +++ b/.gitignore @@ -0,0 +1,28 @@ +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..341c30bd --- /dev/null +++ b/LICENSE @@ -0,0 +1,166 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + diff --git a/README.md b/README.md new file mode 100644 index 00000000..48432d67 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# cachingstore From e3e3ce5835228c26e2675e36c8995b59beec13a7 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Wed, 8 Apr 2015 16:57:35 +0200 Subject: [PATCH 04/44] Dummy commit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 48432d67..1d47f2ee 100644 --- a/README.md +++ b/README.md @@ -1 +1,2 @@ # cachingstore + From c8fd900ff4a675dc8b8368da2ec6fb0904eebc5f Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Wed, 8 Apr 2015 17:00:43 +0200 Subject: [PATCH 05/44] Travis CI needs sudo --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 279afadd..74c2b504 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: cpp +sudo: required compiler: - gcc before_install: From f6eba426b70a60fea74e4a2b5cabdb8b254d2fad Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Wed, 8 Apr 2015 17:12:51 +0200 Subject: [PATCH 06/44] Published to biicode --- biicode.conf | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/biicode.conf b/biicode.conf index 2beadd49..b6d0173e 100644 --- a/biicode.conf +++ b/biicode.conf @@ -6,11 +6,7 @@ messmer/cpp-utils: 2 [parent] - # The parent version of this block. Must match folder name. E.g. - # user/block # No version number means not published yet - # You can change it to publish to a different track, and change version, e.g. - # user/block(track): 7 - + messmer/cachingstore: 0 [paths] # Local directories to look for headers (within block) # / From 38aa789a275fedf76ef908184550ce8882224a4d Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Wed, 8 Apr 2015 17:20:12 +0200 Subject: [PATCH 07/44] Workaround for broken travis biicode deployment --- .travis.yml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 74c2b504..7feccbeb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,11 +15,14 @@ before_script: script: - bii cpp:build --target messmer_cachingstore_test_main -- -j2 - "./bin/messmer_cachingstore_test_main" -deploy: - provider: biicode - user: ${BII_USERNAME} - password: - secure: ${BII_PASSWORD} - on: - branch: develop +after_success: +- bii user ${BII_USERNAME} -p ${BII_PASSWORD} +- bii publish +#deploy: +# provider: biicode +# user: ${BII_USERNAME} +# password: +# secure: ${BII_PASSWORD} +# on: +# branch: develop From dc0154ecd1209c1c96d3364e1d63ffa9bd347518 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Wed, 8 Apr 2015 17:44:20 +0200 Subject: [PATCH 08/44] Adapt to biicode 2.8 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 63322e29..ade6e6fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ INCLUDE(messmer/cmake/tools) -ADD_BIICODE_TARGETS() +ADD_BII_TARGETS() ACTIVATE_CPP14() From 8a8b306f3d9ff5991f96a9ba8796206e84da42a1 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Thu, 9 Apr 2015 15:39:32 +0200 Subject: [PATCH 09/44] Generalize a bit --- CachingStore.h | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/CachingStore.h b/CachingStore.h index 0e19159a..bfaeae87 100644 --- a/CachingStore.h +++ b/CachingStore.h @@ -44,9 +44,9 @@ public: Key _key; }; - std::unique_ptr add(const Key &key, std::unique_ptr resource); - std::unique_ptr load(const Key &key); - void remove(const Key &key, std::unique_ptr block); + std::unique_ptr add(const Key &key, std::unique_ptr resource); + std::unique_ptr load(const Key &key); + void remove(const Key &key, std::unique_ptr block); private: class OpenResource { @@ -80,8 +80,8 @@ private: std::map _openResources; std::map>> _resourcesToRemove; - std::unique_ptr _add(const Key &key, std::unique_ptr resource); - std::unique_ptr _createCachedResourceRef(Resource *resource, const Key &key); + std::unique_ptr _add(const Key &key, std::unique_ptr resource); + std::unique_ptr _createCachedResourceRef(Resource *resource, const Key &key); void release(const Key &key); friend class CachedResource; @@ -90,42 +90,42 @@ private: }; template -std::unique_ptr CachingStore::add(const Key &key, std::unique_ptr resource) { +std::unique_ptr CachingStore::add(const Key &key, std::unique_ptr resource) { std::lock_guard lock(_mutex); return _add(key, std::move(resource)); } template -std::unique_ptr CachingStore::_add(const Key &key, std::unique_ptr resource) { +std::unique_ptr CachingStore::_add(const Key &key, std::unique_ptr resource) { auto insertResult = _openResources.emplace(key, std::move(resource)); assert(true == insertResult.second); return _createCachedResourceRef(insertResult.first->second.getReference(), key); } template -std::unique_ptr CachingStore::_createCachedResourceRef(Resource *resource, const Key &key) { +std::unique_ptr CachingStore::_createCachedResourceRef(Resource *resource, const Key &key) { auto resourceRef = std::make_unique(resource); resourceRef->init(this, key); return std::move(resourceRef); } template -std::unique_ptr CachingStore::load(const Key &key) { +std::unique_ptr CachingStore::load(const Key &key) { std::lock_guard lock(_mutex); auto found = _openResources.find(key); if (found == _openResources.end()) { - auto resource = _baseStore->loadFromBaseStore(key); - if (resource.get() == nullptr) { - return nullptr; - } - return _add(key, std::move(resource)); + auto resource = _baseStore->loadFromBaseStore(key); + if (resource.get() == nullptr) { + return nullptr; + } + return _add(key, std::move(resource)); } else { - return _createCachedResourceRef(found->second.getReference(), key); + return _createCachedResourceRef(found->second.getReference(), key); } } template -void CachingStore::remove(const Key &key, std::unique_ptr resource) { +void CachingStore::remove(const Key &key, std::unique_ptr resource) { auto insertResult = _resourcesToRemove.emplace(key, std::promise>()); assert(true == insertResult.second); resource.reset(); @@ -143,11 +143,11 @@ void CachingStore::release(const Key &key) { assert (found != _openResources.end()); found->second.releaseReference(); if (found->second.refCountIsZero()) { - auto foundToRemove = _resourcesToRemove.find(key); - if (foundToRemove != _resourcesToRemove.end()) { - foundToRemove->second.set_value(found->second.moveResourceOut()); - } - _openResources.erase(found); + auto foundToRemove = _resourcesToRemove.find(key); + if (foundToRemove != _resourcesToRemove.end()) { + foundToRemove->second.set_value(found->second.moveResourceOut()); + } + _openResources.erase(found); } } From 698cc41db56da83dc65fb15340625d205cba385c Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Thu, 9 Apr 2015 19:09:39 +0200 Subject: [PATCH 10/44] TODOs --- CachingStore.h | 1 + 1 file changed, 1 insertion(+) diff --git a/CachingStore.h b/CachingStore.h index bfaeae87..b928de10 100644 --- a/CachingStore.h +++ b/CachingStore.h @@ -111,6 +111,7 @@ std::unique_ptr CachingStore std::unique_ptr CachingStore::load(const Key &key) { + //TODO This lock doesn't allow loading different blocks in parallel. Can we do something with futures maybe? std::lock_guard lock(_mutex); auto found = _openResources.find(key); if (found == _openResources.end()) { From 859703a67b963be1d77c94990a95893d8f44c389 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Thu, 9 Apr 2015 20:07:33 +0200 Subject: [PATCH 11/44] Work with new blockstore::Key --- CachingStore.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CachingStore.h b/CachingStore.h index b928de10..98e8d043 100644 --- a/CachingStore.h +++ b/CachingStore.h @@ -30,7 +30,7 @@ public: class CachedResource { public: //TODO Better way to initialize - CachedResource(): _cachingStore(nullptr), _key(Key::CreateRandomKey()) {} + CachedResource(): _cachingStore(nullptr), _key(Key::CreateRandom()) {} void init(CachingStore *cachingStore, const Key &key) { _cachingStore = cachingStore; _key = key; From 74381f2cddeb14164f7bb198a6eb7d86c7f952db Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Wed, 15 Apr 2015 21:44:35 +0200 Subject: [PATCH 12/44] Cleanup deleted blocks --- CachingStore.h | 1 + 1 file changed, 1 insertion(+) diff --git a/CachingStore.h b/CachingStore.h index 98e8d043..05940c26 100644 --- a/CachingStore.h +++ b/CachingStore.h @@ -133,6 +133,7 @@ void CachingStore::remove(const Key &key, std: //Wait for last resource user to release it auto resourceToRemove = insertResult.first->second.get_future().get(); + _resourcesToRemove.erase(key); //TODO Is this erase causing a race condition? _baseStore->removeFromBaseStore(std::move(resourceToRemove)); } From d15a35546445361daae61274992205d72bd8159d Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Thu, 16 Apr 2015 14:52:06 +0200 Subject: [PATCH 13/44] Renamed to ParallelAccessStore --- CachingBaseStore.h | 18 ---- CachingStore.h | 158 --------------------------------- ParallelAccessBaseStore.h | 18 ++++ ParallelAccessStore.h | 161 ++++++++++++++++++++++++++++++++++ README.md | 2 +- biicode.conf | 2 +- test/CachingBaseStoreTest.cpp | 2 +- 7 files changed, 182 insertions(+), 179 deletions(-) delete mode 100644 CachingBaseStore.h delete mode 100644 CachingStore.h create mode 100644 ParallelAccessBaseStore.h create mode 100644 ParallelAccessStore.h diff --git a/CachingBaseStore.h b/CachingBaseStore.h deleted file mode 100644 index 3a7d1ed3..00000000 --- a/CachingBaseStore.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef MESSMER_CACHINGSTORE_CACHINGBASESTORE_H_ -#define MESSMER_CACHINGSTORE_CACHINGBASESTORE_H_ - -#include - -namespace cachingstore { - -template -class CachingBaseStore { -public: - virtual ~CachingBaseStore() {} - virtual std::unique_ptr loadFromBaseStore(const Key &key) = 0; - virtual void removeFromBaseStore(std::unique_ptr block) = 0; -}; - -} - -#endif diff --git a/CachingStore.h b/CachingStore.h deleted file mode 100644 index 05940c26..00000000 --- a/CachingStore.h +++ /dev/null @@ -1,158 +0,0 @@ -#ifndef MESSMER_BLOCKSTORE_IMPLEMENTATIONS_CACHING_CACHINGSTORE_H_ -#define MESSMER_BLOCKSTORE_IMPLEMENTATIONS_CACHING_CACHINGSTORE_H_ - -#include -#include -#include -#include -#include -#include - -#include "CachingBaseStore.h" - -//TODO Refactor -//TODO Test cases - -namespace cachingstore { - -template -class CachingStore { -public: - CachingStore(std::unique_ptr> baseStore) - : _mutex(), - _baseStore(std::move(baseStore)), - _openResources(), - _resourcesToRemove() { - } - - //TODO Enforce CachedResourceRef inherits from CachedResource - - class CachedResource { - public: - //TODO Better way to initialize - CachedResource(): _cachingStore(nullptr), _key(Key::CreateRandom()) {} - void init(CachingStore *cachingStore, const Key &key) { - _cachingStore = cachingStore; - _key = key; - } - virtual ~CachedResource() { - _cachingStore->release(_key); - } - private: - CachingStore *_cachingStore; - //TODO We're storing Key twice (here and in the base resource). Rather use getKey() on the base resource if possible somehow. - Key _key; - }; - - std::unique_ptr add(const Key &key, std::unique_ptr resource); - std::unique_ptr load(const Key &key); - void remove(const Key &key, std::unique_ptr block); - -private: - class OpenResource { - public: - OpenResource(std::unique_ptr resource): _resource(std::move(resource)), _refCount(0) {} - - Resource *getReference() { - ++_refCount; - return _resource.get(); - } - - void releaseReference() { - --_refCount; - } - - bool refCountIsZero() const { - return 0 == _refCount; - } - - std::unique_ptr moveResourceOut() { - return std::move(_resource); - } - private: - std::unique_ptr _resource; - uint32_t _refCount; - }; - - std::mutex _mutex; - std::unique_ptr> _baseStore; - - std::map _openResources; - std::map>> _resourcesToRemove; - - std::unique_ptr _add(const Key &key, std::unique_ptr resource); - std::unique_ptr _createCachedResourceRef(Resource *resource, const Key &key); - - void release(const Key &key); - friend class CachedResource; - - DISALLOW_COPY_AND_ASSIGN(CachingStore); -}; - -template -std::unique_ptr CachingStore::add(const Key &key, std::unique_ptr resource) { - std::lock_guard lock(_mutex); - return _add(key, std::move(resource)); -} - -template -std::unique_ptr CachingStore::_add(const Key &key, std::unique_ptr resource) { - auto insertResult = _openResources.emplace(key, std::move(resource)); - assert(true == insertResult.second); - return _createCachedResourceRef(insertResult.first->second.getReference(), key); -} - -template -std::unique_ptr CachingStore::_createCachedResourceRef(Resource *resource, const Key &key) { - auto resourceRef = std::make_unique(resource); - resourceRef->init(this, key); - return std::move(resourceRef); -} - -template -std::unique_ptr CachingStore::load(const Key &key) { - //TODO This lock doesn't allow loading different blocks in parallel. Can we do something with futures maybe? - std::lock_guard lock(_mutex); - auto found = _openResources.find(key); - if (found == _openResources.end()) { - auto resource = _baseStore->loadFromBaseStore(key); - if (resource.get() == nullptr) { - return nullptr; - } - return _add(key, std::move(resource)); - } else { - return _createCachedResourceRef(found->second.getReference(), key); - } -} - -template -void CachingStore::remove(const Key &key, std::unique_ptr resource) { - auto insertResult = _resourcesToRemove.emplace(key, std::promise>()); - assert(true == insertResult.second); - resource.reset(); - - //Wait for last resource user to release it - auto resourceToRemove = insertResult.first->second.get_future().get(); - _resourcesToRemove.erase(key); //TODO Is this erase causing a race condition? - - _baseStore->removeFromBaseStore(std::move(resourceToRemove)); -} - -template -void CachingStore::release(const Key &key) { - std::lock_guard lock(_mutex); - auto found = _openResources.find(key); - assert (found != _openResources.end()); - found->second.releaseReference(); - if (found->second.refCountIsZero()) { - auto foundToRemove = _resourcesToRemove.find(key); - if (foundToRemove != _resourcesToRemove.end()) { - foundToRemove->second.set_value(found->second.moveResourceOut()); - } - _openResources.erase(found); - } -} - -} - -#endif diff --git a/ParallelAccessBaseStore.h b/ParallelAccessBaseStore.h new file mode 100644 index 00000000..033441da --- /dev/null +++ b/ParallelAccessBaseStore.h @@ -0,0 +1,18 @@ +#ifndef MESSMER_PARALLELACCESSSTORE_PARALLELACCESSBASESTORE_H_ +#define MESSMER_PARALLELACCESSSTORE_PARALLELACCESSBASESTORE_H_ + +#include + +namespace parallelaccessstore { + +template +class ParallelAccessBaseStore { +public: + virtual ~ParallelAccessBaseStore() {} + virtual std::unique_ptr loadFromBaseStore(const Key &key) = 0; + virtual void removeFromBaseStore(std::unique_ptr block) = 0; +}; + +} + +#endif diff --git a/ParallelAccessStore.h b/ParallelAccessStore.h new file mode 100644 index 00000000..acad7c37 --- /dev/null +++ b/ParallelAccessStore.h @@ -0,0 +1,161 @@ +#ifndef MESSMER_PARALLELACCESSSTORE_IMPLEMENTATIONS_PARALLELACCESS_PARALLELACCESSSTORE_H_ +#define MESSMER_PARALLELACCESSSTORE_IMPLEMENTATIONS_PARALLELACCESS_PARALLELACCESSSTORE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include "ParallelAccessBaseStore.h" + + +//TODO Refactor +//TODO Test cases + +namespace parallelaccessstore { + +template +class ParallelAccessStore { +public: + ParallelAccessStore(std::unique_ptr> baseStore); + + class ResourceRefBase { + public: + //TODO Better way to initialize + ResourceRefBase(): _cachingStore(nullptr), _key(Key::CreateRandom()) {} + void init(ParallelAccessStore *cachingStore, const Key &key) { + _cachingStore = cachingStore; + _key = key; + } + virtual ~ResourceRefBase() { + _cachingStore->release(_key); + } + private: + ParallelAccessStore *_cachingStore; + //TODO We're storing Key twice (here and in the base resource). Rather use getKey() on the base resource if possible somehow. + Key _key; + }; + + std::unique_ptr add(const Key &key, std::unique_ptr resource); + std::unique_ptr load(const Key &key); + void remove(const Key &key, std::unique_ptr block); + +private: + class OpenResource { + public: + OpenResource(std::unique_ptr resource): _resource(std::move(resource)), _refCount(0) {} + + Resource *getReference() { + ++_refCount; + return _resource.get(); + } + + void releaseReference() { + --_refCount; + } + + bool refCountIsZero() const { + return 0 == _refCount; + } + + std::unique_ptr moveResourceOut() { + return std::move(_resource); + } + private: + std::unique_ptr _resource; + uint32_t _refCount; + }; + + std::mutex _mutex; + std::unique_ptr> _baseStore; + + std::map _openResources; + std::map>> _resourcesToRemove; + + std::unique_ptr _add(const Key &key, std::unique_ptr resource); + std::unique_ptr _createResourceRef(Resource *resource, const Key &key); + + void release(const Key &key); + friend class CachedResource; + + DISALLOW_COPY_AND_ASSIGN(ParallelAccessStore); +}; + +template +ParallelAccessStore::ParallelAccessStore(std::unique_ptr> baseStore) + : _mutex(), + _baseStore(std::move(baseStore)), + _openResources(), + _resourcesToRemove() { + static_assert(std::is_base_of::value, "ResourceRef must inherit from ResourceRefBase"); +} + +template +std::unique_ptr ParallelAccessStore::add(const Key &key, std::unique_ptr resource) { + std::lock_guard lock(_mutex); + return _add(key, std::move(resource)); +} + +template +std::unique_ptr ParallelAccessStore::_add(const Key &key, std::unique_ptr resource) { + auto insertResult = _openResources.emplace(key, std::move(resource)); + assert(true == insertResult.second); + return _createResourceRef(insertResult.first->second.getReference(), key); +} + +template +std::unique_ptr ParallelAccessStore::_createResourceRef(Resource *resource, const Key &key) { + auto resourceRef = std::make_unique(resource); + resourceRef->init(this, key); + return std::move(resourceRef); +} + +template +std::unique_ptr ParallelAccessStore::load(const Key &key) { + //TODO This lock doesn't allow loading different blocks in parallel. Can we do something with futures maybe? + std::lock_guard lock(_mutex); + auto found = _openResources.find(key); + if (found == _openResources.end()) { + auto resource = _baseStore->loadFromBaseStore(key); + if (resource.get() == nullptr) { + return nullptr; + } + return _add(key, std::move(resource)); + } else { + return _createResourceRef(found->second.getReference(), key); + } +} + +template +void ParallelAccessStore::remove(const Key &key, std::unique_ptr resource) { + auto insertResult = _resourcesToRemove.emplace(key, std::promise>()); + assert(true == insertResult.second); + resource.reset(); + + //Wait for last resource user to release it + auto resourceToRemove = insertResult.first->second.get_future().get(); + _resourcesToRemove.erase(key); //TODO Is this erase causing a race condition? + + _baseStore->removeFromBaseStore(std::move(resourceToRemove)); +} + +template +void ParallelAccessStore::release(const Key &key) { + std::lock_guard lock(_mutex); + auto found = _openResources.find(key); + assert (found != _openResources.end()); + found->second.releaseReference(); + if (found->second.refCountIsZero()) { + auto foundToRemove = _resourcesToRemove.find(key); + if (foundToRemove != _resourcesToRemove.end()) { + foundToRemove->second.set_value(found->second.moveResourceOut()); + } + _openResources.erase(found); + } +} + +} + +#endif diff --git a/README.md b/README.md index 1d47f2ee..b1fa0047 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# cachingstore +# parallelaccessstore diff --git a/biicode.conf b/biicode.conf index b6d0173e..24ae36cd 100644 --- a/biicode.conf +++ b/biicode.conf @@ -6,7 +6,7 @@ messmer/cpp-utils: 2 [parent] - messmer/cachingstore: 0 + messmer/parallelaccessstore: 0 [paths] # Local directories to look for headers (within block) # / diff --git a/test/CachingBaseStoreTest.cpp b/test/CachingBaseStoreTest.cpp index 9e05e76b..edc0aece 100644 --- a/test/CachingBaseStoreTest.cpp +++ b/test/CachingBaseStoreTest.cpp @@ -1,3 +1,3 @@ -#include "../CachingBaseStore.h" +#include "../ParallelAccessBaseStore.h" // Test that CachingBaseStore.h can be included without errors From 5e753ae7064fca3ff913b6c46eb24dcb074d61b8 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Fri, 17 Apr 2015 17:39:07 +0200 Subject: [PATCH 14/44] Use unordered_map instead of map --- ParallelAccessStore.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ParallelAccessStore.h b/ParallelAccessStore.h index acad7c37..1ad05421 100644 --- a/ParallelAccessStore.h +++ b/ParallelAccessStore.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -71,7 +72,7 @@ private: std::mutex _mutex; std::unique_ptr> _baseStore; - std::map _openResources; + std::unordered_map _openResources; std::map>> _resourcesToRemove; std::unique_ptr _add(const Key &key, std::unique_ptr resource); From 82266b4ced7241e8d2452c9ba6589bc52460ef5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Me=C3=9Fmer?= Date: Sat, 18 Apr 2015 17:01:54 +0200 Subject: [PATCH 15/44] Fix travis --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7feccbeb..03a50966 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,8 +13,8 @@ before_script: && ./setup_biicode_project.sh && rm setup_biicode_project.sh script: -- bii cpp:build --target messmer_cachingstore_test_main -- -j2 -- "./bin/messmer_cachingstore_test_main" +- bii cpp:build --target messmer_parallelaccessstore_test_main -- -j2 +- "./bin/messmer_parallelaccessstore_test_main" after_success: - bii user ${BII_USERNAME} -p ${BII_PASSWORD} - bii publish From ea22156f3386e5ce4841005e19474e77d52eb967 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Sat, 25 Apr 2015 00:42:21 +0200 Subject: [PATCH 16/44] Upgrade dependencies --- biicode.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biicode.conf b/biicode.conf index 24ae36cd..6a085ea6 100644 --- a/biicode.conf +++ b/biicode.conf @@ -1,7 +1,7 @@ # Biicode configuration file [requirements] - google/gtest: 10 + google/gtest: 11 messmer/cmake: 3 messmer/cpp-utils: 2 From 0aabe10fe0399240517944c00ec9f6d40763867c Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Mon, 27 Apr 2015 18:21:44 +0200 Subject: [PATCH 17/44] Make constructors explicit where adequate --- ParallelAccessStore.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ParallelAccessStore.h b/ParallelAccessStore.h index 1ad05421..54285ebe 100644 --- a/ParallelAccessStore.h +++ b/ParallelAccessStore.h @@ -20,7 +20,7 @@ namespace parallelaccessstore { template class ParallelAccessStore { public: - ParallelAccessStore(std::unique_ptr> baseStore); + explicit ParallelAccessStore(std::unique_ptr> baseStore); class ResourceRefBase { public: From 64b9882ac82f24e1284afe03d2e6752a60108e72 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Fri, 8 May 2015 02:11:47 +0200 Subject: [PATCH 18/44] Enable extended compiler warnings --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ade6e6fe..b995d51b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,7 @@ INCLUDE(messmer/cmake/tools) ADD_BII_TARGETS() ACTIVATE_CPP14() +ENABLE_STYLE_WARNINGS() # You can safely delete lines from here... From 39e17b8015c3962606c4e5c8d887706994459926 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Tue, 16 Jun 2015 16:54:43 +0200 Subject: [PATCH 19/44] Block keys are drawn using pseudorandomness --- ParallelAccessStore.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ParallelAccessStore.h b/ParallelAccessStore.h index 54285ebe..99126562 100644 --- a/ParallelAccessStore.h +++ b/ParallelAccessStore.h @@ -25,7 +25,7 @@ public: class ResourceRefBase { public: //TODO Better way to initialize - ResourceRefBase(): _cachingStore(nullptr), _key(Key::CreateRandom()) {} + ResourceRefBase(): _cachingStore(nullptr), _key(Key::CreatePseudoRandom()) {} void init(ParallelAccessStore *cachingStore, const Key &key) { _cachingStore = cachingStore; _key = key; From 0faa63b7b4ab3e524451efcd6645fa7df398550c Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Fri, 26 Jun 2015 13:44:12 +0200 Subject: [PATCH 20/44] Replace unique_ptr with unique_ref --- ParallelAccessBaseStore.h | 7 +++--- ParallelAccessStore.h | 52 +++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/ParallelAccessBaseStore.h b/ParallelAccessBaseStore.h index 033441da..07a07953 100644 --- a/ParallelAccessBaseStore.h +++ b/ParallelAccessBaseStore.h @@ -1,7 +1,8 @@ #ifndef MESSMER_PARALLELACCESSSTORE_PARALLELACCESSBASESTORE_H_ #define MESSMER_PARALLELACCESSSTORE_PARALLELACCESSBASESTORE_H_ -#include +#include +#include namespace parallelaccessstore { @@ -9,8 +10,8 @@ template class ParallelAccessBaseStore { public: virtual ~ParallelAccessBaseStore() {} - virtual std::unique_ptr loadFromBaseStore(const Key &key) = 0; - virtual void removeFromBaseStore(std::unique_ptr block) = 0; + virtual boost::optional> loadFromBaseStore(const Key &key) = 0; + virtual void removeFromBaseStore(cpputils::unique_ref block) = 0; }; } diff --git a/ParallelAccessStore.h b/ParallelAccessStore.h index 99126562..f0cc078f 100644 --- a/ParallelAccessStore.h +++ b/ParallelAccessStore.h @@ -20,7 +20,7 @@ namespace parallelaccessstore { template class ParallelAccessStore { public: - explicit ParallelAccessStore(std::unique_ptr> baseStore); + explicit ParallelAccessStore(cpputils::unique_ref> baseStore); class ResourceRefBase { public: @@ -39,14 +39,14 @@ public: Key _key; }; - std::unique_ptr add(const Key &key, std::unique_ptr resource); - std::unique_ptr load(const Key &key); - void remove(const Key &key, std::unique_ptr block); + cpputils::unique_ref add(const Key &key, cpputils::unique_ref resource); + boost::optional> load(const Key &key); + void remove(const Key &key, cpputils::unique_ref block); private: class OpenResource { public: - OpenResource(std::unique_ptr resource): _resource(std::move(resource)), _refCount(0) {} + OpenResource(cpputils::unique_ref resource): _resource(std::move(resource)), _refCount(0) {} Resource *getReference() { ++_refCount; @@ -61,22 +61,22 @@ private: return 0 == _refCount; } - std::unique_ptr moveResourceOut() { + cpputils::unique_ref moveResourceOut() { return std::move(_resource); } private: - std::unique_ptr _resource; + cpputils::unique_ref _resource; uint32_t _refCount; }; std::mutex _mutex; - std::unique_ptr> _baseStore; + cpputils::unique_ref> _baseStore; std::unordered_map _openResources; - std::map>> _resourcesToRemove; + std::map>> _resourcesToRemove; - std::unique_ptr _add(const Key &key, std::unique_ptr resource); - std::unique_ptr _createResourceRef(Resource *resource, const Key &key); + cpputils::unique_ref _add(const Key &key, cpputils::unique_ref resource); + cpputils::unique_ref _createResourceRef(Resource *resource, const Key &key); void release(const Key &key); friend class CachedResource; @@ -85,7 +85,7 @@ private: }; template -ParallelAccessStore::ParallelAccessStore(std::unique_ptr> baseStore) +ParallelAccessStore::ParallelAccessStore(cpputils::unique_ref> baseStore) : _mutex(), _baseStore(std::move(baseStore)), _openResources(), @@ -94,46 +94,46 @@ ParallelAccessStore::ParallelAccessStore(std::unique } template -std::unique_ptr ParallelAccessStore::add(const Key &key, std::unique_ptr resource) { +cpputils::unique_ref ParallelAccessStore::add(const Key &key, cpputils::unique_ref resource) { std::lock_guard lock(_mutex); return _add(key, std::move(resource)); } template -std::unique_ptr ParallelAccessStore::_add(const Key &key, std::unique_ptr resource) { +cpputils::unique_ref ParallelAccessStore::_add(const Key &key, cpputils::unique_ref resource) { auto insertResult = _openResources.emplace(key, std::move(resource)); assert(true == insertResult.second); return _createResourceRef(insertResult.first->second.getReference(), key); } template -std::unique_ptr ParallelAccessStore::_createResourceRef(Resource *resource, const Key &key) { - auto resourceRef = std::make_unique(resource); +cpputils::unique_ref ParallelAccessStore::_createResourceRef(Resource *resource, const Key &key) { + auto resourceRef = cpputils::make_unique_ref(resource); resourceRef->init(this, key); return std::move(resourceRef); } template -std::unique_ptr ParallelAccessStore::load(const Key &key) { +boost::optional> ParallelAccessStore::load(const Key &key) { //TODO This lock doesn't allow loading different blocks in parallel. Can we do something with futures maybe? std::lock_guard lock(_mutex); auto found = _openResources.find(key); if (found == _openResources.end()) { - auto resource = _baseStore->loadFromBaseStore(key); - if (resource.get() == nullptr) { - return nullptr; - } - return _add(key, std::move(resource)); + auto resource = _baseStore->loadFromBaseStore(key); + if (resource == boost::none) { + return boost::none; + } + return _add(key, std::move(*resource)); } else { - return _createResourceRef(found->second.getReference(), key); + return _createResourceRef(found->second.getReference(), key); } } template -void ParallelAccessStore::remove(const Key &key, std::unique_ptr resource) { - auto insertResult = _resourcesToRemove.emplace(key, std::promise>()); +void ParallelAccessStore::remove(const Key &key, cpputils::unique_ref resource) { + auto insertResult = _resourcesToRemove.emplace(key, std::promise>()); assert(true == insertResult.second); - resource.reset(); + cpputils::to_unique_ptr(std::move(resource)).reset(); // Call destructor //Wait for last resource user to release it auto resourceToRemove = insertResult.first->second.get_future().get(); From ba4d619964d7d14c55a2f5834810430bb9249fe6 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Tue, 21 Jul 2015 18:23:20 +0200 Subject: [PATCH 21/44] Use cpputils::destruct() instead of cpputils::to_unique_ptr().reset() --- ParallelAccessStore.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ParallelAccessStore.h b/ParallelAccessStore.h index f0cc078f..5fee8445 100644 --- a/ParallelAccessStore.h +++ b/ParallelAccessStore.h @@ -133,7 +133,7 @@ template void ParallelAccessStore::remove(const Key &key, cpputils::unique_ref resource) { auto insertResult = _resourcesToRemove.emplace(key, std::promise>()); assert(true == insertResult.second); - cpputils::to_unique_ptr(std::move(resource)).reset(); // Call destructor + cpputils::destruct(std::move(resource)); //Wait for last resource user to release it auto resourceToRemove = insertResult.first->second.get_future().get(); From 14b6354d84cee1db59a9499804bc3a6765bbaf27 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Wed, 22 Jul 2015 13:48:01 +0200 Subject: [PATCH 22/44] Use the new assert that doesn't crash the program in a release build --- ParallelAccessStore.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ParallelAccessStore.h b/ParallelAccessStore.h index 5fee8445..bcaba4ef 100644 --- a/ParallelAccessStore.h +++ b/ParallelAccessStore.h @@ -10,6 +10,7 @@ #include #include #include "ParallelAccessBaseStore.h" +#include //TODO Refactor @@ -102,7 +103,7 @@ cpputils::unique_ref ParallelAccessStore cpputils::unique_ref ParallelAccessStore::_add(const Key &key, cpputils::unique_ref resource) { auto insertResult = _openResources.emplace(key, std::move(resource)); - assert(true == insertResult.second); + ASSERT(true == insertResult.second, "Inserting failed"); return _createResourceRef(insertResult.first->second.getReference(), key); } @@ -132,7 +133,7 @@ boost::optional> ParallelAccessStore void ParallelAccessStore::remove(const Key &key, cpputils::unique_ref resource) { auto insertResult = _resourcesToRemove.emplace(key, std::promise>()); - assert(true == insertResult.second); + ASSERT(true == insertResult.second, "Inserting failed"); cpputils::destruct(std::move(resource)); //Wait for last resource user to release it @@ -146,7 +147,7 @@ template void ParallelAccessStore::release(const Key &key) { std::lock_guard lock(_mutex); auto found = _openResources.find(key); - assert (found != _openResources.end()); + ASSERT(found != _openResources.end(), "Didn't find key"); found->second.releaseReference(); if (found->second.refCountIsZero()) { auto foundToRemove = _resourcesToRemove.find(key); From b4cc39aebb5f875be75e7b937be2a81125eb2d56 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Sat, 12 Sep 2015 21:01:02 +0200 Subject: [PATCH 23/44] Add travis CI build icon --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b1fa0047..c1637cbf 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ -# parallelaccessstore +# parallelaccessstore [![Build Status](https://travis-ci.org/cryfs/parallelaccessstore.svg)](https://travis-ci.org/cryfs/parallelaccessstore?branch=master) +This repository contains some concurrency primitives for [CryFS](https://github.com/cryfs/cryfs). From eb69965f9681381747cbbf3587e691b23345c140 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Sat, 12 Sep 2015 21:03:08 +0200 Subject: [PATCH 24/44] Fix travis build icon --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c1637cbf..26771c92 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -# parallelaccessstore [![Build Status](https://travis-ci.org/cryfs/parallelaccessstore.svg)](https://travis-ci.org/cryfs/parallelaccessstore?branch=master) +# parallelaccessstore [![Build Status](https://travis-ci.org/cryfs/parallelaccessstore.svg?branch=master)](https://travis-ci.org/cryfs/parallelaccessstore) This repository contains some concurrency primitives for [CryFS](https://github.com/cryfs/cryfs). From e873418477cb0019b493cd3e2672b71827b6f002 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Sun, 4 Oct 2015 17:27:26 +0200 Subject: [PATCH 25/44] Allow specifying own class for ResourceRef --- ParallelAccessStore.h | 48 +++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/ParallelAccessStore.h b/ParallelAccessStore.h index bcaba4ef..e60569e5 100644 --- a/ParallelAccessStore.h +++ b/ParallelAccessStore.h @@ -26,7 +26,7 @@ public: class ResourceRefBase { public: //TODO Better way to initialize - ResourceRefBase(): _cachingStore(nullptr), _key(Key::CreatePseudoRandom()) {} + ResourceRefBase(): _cachingStore(nullptr), _key(Key::Null()) {} void init(ParallelAccessStore *cachingStore, const Key &key) { _cachingStore = cachingStore; _key = key; @@ -41,7 +41,10 @@ public: }; cpputils::unique_ref add(const Key &key, cpputils::unique_ref resource); + template + cpputils::unique_ref add(const Key &key, cpputils::unique_ref resource, std::function(Resource*)> createResourceRef); boost::optional> load(const Key &key); + boost::optional> load(const Key &key, std::function(Resource*)> createResourceRef); void remove(const Key &key, cpputils::unique_ref block); private: @@ -76,8 +79,8 @@ private: std::unordered_map _openResources; std::map>> _resourcesToRemove; - cpputils::unique_ref _add(const Key &key, cpputils::unique_ref resource); - cpputils::unique_ref _createResourceRef(Resource *resource, const Key &key); + template + cpputils::unique_ref _add(const Key &key, cpputils::unique_ref resource, std::function(Resource*)> createResourceRef); void release(const Key &key); friend class CachedResource; @@ -96,26 +99,39 @@ ParallelAccessStore::ParallelAccessStore(cpputils::u template cpputils::unique_ref ParallelAccessStore::add(const Key &key, cpputils::unique_ref resource) { - std::lock_guard lock(_mutex); - return _add(key, std::move(resource)); + return add(key, std::move(resource), [] (Resource *resource) { + return cpputils::make_unique_ref(resource); + }); } template -cpputils::unique_ref ParallelAccessStore::_add(const Key &key, cpputils::unique_ref resource) { +template +cpputils::unique_ref ParallelAccessStore::add(const Key &key, cpputils::unique_ref resource, std::function(Resource*)> createResourceRef) { + static_assert(std::is_base_of::value, "Wrong ResourceRef type"); + std::lock_guard lock(_mutex); + return _add(key, std::move(resource), createResourceRef); +} + +template +template +cpputils::unique_ref ParallelAccessStore::_add(const Key &key, cpputils::unique_ref resource, std::function(Resource*)> createResourceRef) { + static_assert(std::is_base_of::value, "Wrong ResourceRef type"); auto insertResult = _openResources.emplace(key, std::move(resource)); ASSERT(true == insertResult.second, "Inserting failed"); - return _createResourceRef(insertResult.first->second.getReference(), key); -} - -template -cpputils::unique_ref ParallelAccessStore::_createResourceRef(Resource *resource, const Key &key) { - auto resourceRef = cpputils::make_unique_ref(resource); + auto resourceRef = createResourceRef(insertResult.first->second.getReference()); resourceRef->init(this, key); - return std::move(resourceRef); + return resourceRef; } template boost::optional> ParallelAccessStore::load(const Key &key) { + return load(key, [] (Resource *res) { + return cpputils::make_unique_ref(res); + }); +}; + +template +boost::optional> ParallelAccessStore::load(const Key &key, std::function(Resource*)> createResourceRef) { //TODO This lock doesn't allow loading different blocks in parallel. Can we do something with futures maybe? std::lock_guard lock(_mutex); auto found = _openResources.find(key); @@ -124,9 +140,11 @@ boost::optional> ParallelAccessStoresecond.getReference(), key); + auto resourceRef = createResourceRef(found->second.getReference()); + resourceRef->init(this, key); + return std::move(resourceRef); } } From cd5094ff920a80c0215294033e8701758620afde Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Mon, 5 Oct 2015 16:54:31 +0200 Subject: [PATCH 26/44] Added asserts that there are no open blocks when destructor runs --- ParallelAccessStore.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/ParallelAccessStore.h b/ParallelAccessStore.h index e60569e5..217ab1d1 100644 --- a/ParallelAccessStore.h +++ b/ParallelAccessStore.h @@ -22,20 +22,24 @@ template class ParallelAccessStore { public: explicit ParallelAccessStore(cpputils::unique_ref> baseStore); + ~ParallelAccessStore() { + ASSERT(_openResources.size() == 0, "Still resources open when trying to destruct"); + ASSERT(_resourcesToRemove.size() == 0, "Still resources to remove when trying to destruct"); + }; class ResourceRefBase { public: //TODO Better way to initialize - ResourceRefBase(): _cachingStore(nullptr), _key(Key::Null()) {} - void init(ParallelAccessStore *cachingStore, const Key &key) { - _cachingStore = cachingStore; + ResourceRefBase(): _parallelAccessStore(nullptr), _key(Key::Null()) {} + void init(ParallelAccessStore *parallelAccessStore, const Key &key) { + _parallelAccessStore = parallelAccessStore; _key = key; } virtual ~ResourceRefBase() { - _cachingStore->release(_key); + _parallelAccessStore->release(_key); } private: - ParallelAccessStore *_cachingStore; + ParallelAccessStore *_parallelAccessStore; //TODO We're storing Key twice (here and in the base resource). Rather use getKey() on the base resource if possible somehow. Key _key; }; From cc2f93af92ff0d95ea6f0c55a987f2e5c087f147 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Mon, 5 Oct 2015 16:54:41 +0200 Subject: [PATCH 27/44] Test cases print stack trace on sigsegv --- test/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/main.cpp b/test/main.cpp index f7a14877..ec4a5e33 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -1,6 +1,8 @@ #include "google/gtest/gtest.h" +#include int main(int argc, char **argv) { + cpputils::showBacktraceOnSigSegv(); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } From 5453627209c944416e59057a5cb8615110da678e Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Wed, 14 Oct 2015 15:01:52 +0200 Subject: [PATCH 28/44] Added ParallelAccessStore::isOpened() --- ParallelAccessStore.h | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/ParallelAccessStore.h b/ParallelAccessStore.h index 217ab1d1..ba74f8c1 100644 --- a/ParallelAccessStore.h +++ b/ParallelAccessStore.h @@ -44,6 +44,7 @@ public: Key _key; }; + bool isOpened(const Key &key) const; cpputils::unique_ref add(const Key &key, cpputils::unique_ref resource); template cpputils::unique_ref add(const Key &key, cpputils::unique_ref resource, std::function(Resource*)> createResourceRef); @@ -77,7 +78,7 @@ private: uint32_t _refCount; }; - std::mutex _mutex; + mutable std::mutex _mutex; cpputils::unique_ref> _baseStore; std::unordered_map _openResources; @@ -101,6 +102,12 @@ ParallelAccessStore::ParallelAccessStore(cpputils::u static_assert(std::is_base_of::value, "ResourceRef must inherit from ResourceRefBase"); } +template +bool ParallelAccessStore::isOpened(const Key &key) const { + std::lock_guard lock(_mutex); + return _openResources.find(key) != _openResources.end(); +}; + template cpputils::unique_ref ParallelAccessStore::add(const Key &key, cpputils::unique_ref resource) { return add(key, std::move(resource), [] (Resource *resource) { @@ -121,7 +128,7 @@ template cpputils::unique_ref ParallelAccessStore::_add(const Key &key, cpputils::unique_ref resource, std::function(Resource*)> createResourceRef) { static_assert(std::is_base_of::value, "Wrong ResourceRef type"); auto insertResult = _openResources.emplace(key, std::move(resource)); - ASSERT(true == insertResult.second, "Inserting failed"); + ASSERT(true == insertResult.second, "Inserting failed. Already exists."); auto resourceRef = createResourceRef(insertResult.first->second.getReference()); resourceRef->init(this, key); return resourceRef; @@ -136,7 +143,7 @@ boost::optional> ParallelAccessStore boost::optional> ParallelAccessStore::load(const Key &key, std::function(Resource*)> createResourceRef) { - //TODO This lock doesn't allow loading different blocks in parallel. Can we do something with futures maybe? + //TODO This lock doesn't allow loading different blocks in parallel. Can we only lock the requested key? std::lock_guard lock(_mutex); auto found = _openResources.find(key); if (found == _openResources.end()) { @@ -154,12 +161,18 @@ boost::optional> ParallelAccessStore void ParallelAccessStore::remove(const Key &key, cpputils::unique_ref resource) { - auto insertResult = _resourcesToRemove.emplace(key, std::promise>()); - ASSERT(true == insertResult.second, "Inserting failed"); + std::future> resourceToRemoveFuture; + { + std::lock_guard lock(_mutex); // TODO Lock needed for _resourcesToRemove? + auto insertResult = _resourcesToRemove.emplace(key, std::promise < cpputils::unique_ref < Resource >> ()); + ASSERT(true == insertResult.second, "Inserting failed"); + resourceToRemoveFuture = insertResult.first->second.get_future(); + } cpputils::destruct(std::move(resource)); - //Wait for last resource user to release it - auto resourceToRemove = insertResult.first->second.get_future().get(); + auto resourceToRemove = resourceToRemoveFuture.get(); + + std::lock_guard lock(_mutex); // TODO Just added this as a precaution on a whim, but I seriously need to rethink locking here. _resourcesToRemove.erase(key); //TODO Is this erase causing a race condition? _baseStore->removeFromBaseStore(std::move(resourceToRemove)); From 39b43aacfa174a42ce2aa39adbdfb3f19122e024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Me=C3=9Fmer?= Date: Thu, 15 Oct 2015 12:58:48 +0200 Subject: [PATCH 29/44] Unify (and fix) include guards --- ParallelAccessBaseStore.h | 1 + ParallelAccessStore.h | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ParallelAccessBaseStore.h b/ParallelAccessBaseStore.h index 07a07953..4d975502 100644 --- a/ParallelAccessBaseStore.h +++ b/ParallelAccessBaseStore.h @@ -1,3 +1,4 @@ +#pragma once #ifndef MESSMER_PARALLELACCESSSTORE_PARALLELACCESSBASESTORE_H_ #define MESSMER_PARALLELACCESSSTORE_PARALLELACCESSBASESTORE_H_ diff --git a/ParallelAccessStore.h b/ParallelAccessStore.h index ba74f8c1..9d1efdf4 100644 --- a/ParallelAccessStore.h +++ b/ParallelAccessStore.h @@ -1,5 +1,6 @@ -#ifndef MESSMER_PARALLELACCESSSTORE_IMPLEMENTATIONS_PARALLELACCESS_PARALLELACCESSSTORE_H_ -#define MESSMER_PARALLELACCESSSTORE_IMPLEMENTATIONS_PARALLELACCESS_PARALLELACCESSSTORE_H_ +#pragma once +#ifndef MESSMER_PARALLELACCESSSTORE_PARALLELACCESSSTORE_H_ +#define MESSMER_PARALLELACCESSSTORE_PARALLELACCESSSTORE_H_ #include #include From 7925d60bfd3e95f91352aee55b3842dde70eff39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Me=C3=9Fmer?= Date: Fri, 16 Oct 2015 04:29:08 +0200 Subject: [PATCH 30/44] Update dependency --- biicode.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biicode.conf b/biicode.conf index 6a085ea6..8d44e53c 100644 --- a/biicode.conf +++ b/biicode.conf @@ -3,7 +3,7 @@ [requirements] google/gtest: 11 messmer/cmake: 3 - messmer/cpp-utils: 2 + messmer/cpp-utils: 3 [parent] messmer/parallelaccessstore: 0 From d0a5a0b27d4573e3200f69b72f1d634d04f7ff07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Me=C3=9Fmer?= Date: Fri, 16 Oct 2015 04:29:55 +0200 Subject: [PATCH 31/44] Update biicode block ref --- biicode.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biicode.conf b/biicode.conf index 8d44e53c..6d254020 100644 --- a/biicode.conf +++ b/biicode.conf @@ -6,7 +6,7 @@ messmer/cpp-utils: 3 [parent] - messmer/parallelaccessstore: 0 + messmer/parallelaccessstore: 1 [paths] # Local directories to look for headers (within block) # / From 4c8e953ebeb65ec8a15efa177cf8c6731e14e950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Me=C3=9Fmer?= Date: Sat, 17 Oct 2015 18:00:41 +0200 Subject: [PATCH 32/44] Update dependencies --- biicode.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biicode.conf b/biicode.conf index 6d254020..68d879c4 100644 --- a/biicode.conf +++ b/biicode.conf @@ -3,7 +3,7 @@ [requirements] google/gtest: 11 messmer/cmake: 3 - messmer/cpp-utils: 3 + messmer/cpp-utils: 4 [parent] messmer/parallelaccessstore: 1 From 5a7ed220aace25e0276a9316de499f2681222346 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Me=C3=9Fmer?= Date: Sat, 17 Oct 2015 20:55:55 +0200 Subject: [PATCH 33/44] Fix -Weffc++ warning --- ParallelAccessStore.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ParallelAccessStore.h b/ParallelAccessStore.h index 9d1efdf4..5a1cb9c0 100644 --- a/ParallelAccessStore.h +++ b/ParallelAccessStore.h @@ -43,6 +43,8 @@ public: ParallelAccessStore *_parallelAccessStore; //TODO We're storing Key twice (here and in the base resource). Rather use getKey() on the base resource if possible somehow. Key _key; + + DISALLOW_COPY_AND_ASSIGN(ResourceRefBase); }; bool isOpened(const Key &key) const; From bcb89dc4e1b33957923f6b3c9f76a19998bf5944 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Thu, 12 Nov 2015 15:40:13 -0800 Subject: [PATCH 34/44] Use new cpp-utils dependency --- biicode.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biicode.conf b/biicode.conf index 68d879c4..7a0080eb 100644 --- a/biicode.conf +++ b/biicode.conf @@ -3,7 +3,7 @@ [requirements] google/gtest: 11 messmer/cmake: 3 - messmer/cpp-utils: 4 + messmer/cpp-utils: 5 [parent] messmer/parallelaccessstore: 1 From 9271f2c7e2ce4f7ce60578aeb5bef1edcdc3d38f Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Thu, 12 Nov 2015 15:41:22 -0800 Subject: [PATCH 35/44] Update biicode block version --- biicode.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biicode.conf b/biicode.conf index 7a0080eb..53a03319 100644 --- a/biicode.conf +++ b/biicode.conf @@ -6,7 +6,7 @@ messmer/cpp-utils: 5 [parent] - messmer/parallelaccessstore: 1 + messmer/parallelaccessstore: 2 [paths] # Local directories to look for headers (within block) # / From 55d6cb710ef60711c67e3df22fab00c6a70102d4 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Wed, 18 Nov 2015 11:07:31 +0100 Subject: [PATCH 36/44] Update dependencies --- biicode.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biicode.conf b/biicode.conf index 53a03319..304d4c46 100644 --- a/biicode.conf +++ b/biicode.conf @@ -3,7 +3,7 @@ [requirements] google/gtest: 11 messmer/cmake: 3 - messmer/cpp-utils: 5 + messmer/cpp-utils: 6 [parent] messmer/parallelaccessstore: 2 From ac05a8857058d6da738d1ee889a2f618ec87aca8 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Wed, 18 Nov 2015 11:08:07 +0100 Subject: [PATCH 37/44] Update biicode block ref --- biicode.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biicode.conf b/biicode.conf index 304d4c46..9a6de7b4 100644 --- a/biicode.conf +++ b/biicode.conf @@ -6,7 +6,7 @@ messmer/cpp-utils: 6 [parent] - messmer/parallelaccessstore: 2 + messmer/parallelaccessstore: 3 [paths] # Local directories to look for headers (within block) # / From 7c4ffdc134927034f88742194614295d417d68a7 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Tue, 24 Nov 2015 08:40:35 +0100 Subject: [PATCH 38/44] Update dependencies --- biicode.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/biicode.conf b/biicode.conf index 9a6de7b4..da856fd0 100644 --- a/biicode.conf +++ b/biicode.conf @@ -3,10 +3,10 @@ [requirements] google/gtest: 11 messmer/cmake: 3 - messmer/cpp-utils: 6 + messmer/cpp-utils: 7 [parent] - messmer/parallelaccessstore: 3 + messmer/parallelaccessstore: 4 [paths] # Local directories to look for headers (within block) # / From 321a1c90eac631f40ec50eba78336965c521ab49 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Tue, 24 Nov 2015 15:17:01 +0100 Subject: [PATCH 39/44] Use gcc 4.8 on travis to ensure compatibility --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 03a50966..b7db6400 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ compiler: before_install: - wget https://raw.githubusercontent.com/smessmer/travis-utils/master/update_gcc_version.sh && chmod +x update_gcc_version.sh - && ./update_gcc_version.sh 4.9 + && ./update_gcc_version.sh 4.8 && rm update_gcc_version.sh before_script: - wget https://raw.githubusercontent.com/smessmer/travis-utils/master/setup_biicode_project.sh From c7f9ffc6ef1848a52b5302a9652fa284323b3793 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Wed, 25 Nov 2015 16:43:41 +0100 Subject: [PATCH 40/44] Update dependencies --- biicode.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biicode.conf b/biicode.conf index da856fd0..6e9debab 100644 --- a/biicode.conf +++ b/biicode.conf @@ -3,7 +3,7 @@ [requirements] google/gtest: 11 messmer/cmake: 3 - messmer/cpp-utils: 7 + messmer/cpp-utils: 8 [parent] messmer/parallelaccessstore: 4 From 5865ad6ccb730046a9f1f2a4ed329ff2d7573fd4 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Wed, 25 Nov 2015 16:44:45 +0100 Subject: [PATCH 41/44] Update biicode block ref --- biicode.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biicode.conf b/biicode.conf index 6e9debab..bc990fd8 100644 --- a/biicode.conf +++ b/biicode.conf @@ -6,7 +6,7 @@ messmer/cpp-utils: 8 [parent] - messmer/parallelaccessstore: 4 + messmer/parallelaccessstore: 5 [paths] # Local directories to look for headers (within block) # / From b3391c88ae2bef60f5961f1e20ecba49515427f6 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Fri, 27 Nov 2015 14:06:00 +0100 Subject: [PATCH 42/44] Make classes final if they're not meant to be derived from --- ParallelAccessStore.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ParallelAccessStore.h b/ParallelAccessStore.h index 5a1cb9c0..f72408ae 100644 --- a/ParallelAccessStore.h +++ b/ParallelAccessStore.h @@ -20,7 +20,7 @@ namespace parallelaccessstore { template -class ParallelAccessStore { +class ParallelAccessStore final { public: explicit ParallelAccessStore(cpputils::unique_ref> baseStore); ~ParallelAccessStore() { @@ -56,9 +56,10 @@ public: void remove(const Key &key, cpputils::unique_ref block); private: - class OpenResource { + class OpenResource final { public: OpenResource(cpputils::unique_ref resource): _resource(std::move(resource)), _refCount(0) {} + OpenResource(OpenResource &&rhs) = default; Resource *getReference() { ++_refCount; @@ -79,6 +80,8 @@ private: private: cpputils::unique_ref _resource; uint32_t _refCount; + + DISALLOW_COPY_AND_ASSIGN(OpenResource); }; mutable std::mutex _mutex; From 3113f8c84bef36ef1321ead082d178867d893db7 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Mon, 25 Jan 2016 22:43:21 +0100 Subject: [PATCH 43/44] Update biicode block ref --- biicode.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biicode.conf b/biicode.conf index bc990fd8..d288c019 100644 --- a/biicode.conf +++ b/biicode.conf @@ -3,7 +3,7 @@ [requirements] google/gtest: 11 messmer/cmake: 3 - messmer/cpp-utils: 8 + messmer/cpp-utils: 9 [parent] messmer/parallelaccessstore: 5 From a6b1f93225f0ba3877e8468927a6c276acbd9896 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Mon, 25 Jan 2016 22:43:54 +0100 Subject: [PATCH 44/44] Update biicode block ref --- biicode.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biicode.conf b/biicode.conf index d288c019..ada9a579 100644 --- a/biicode.conf +++ b/biicode.conf @@ -6,7 +6,7 @@ messmer/cpp-utils: 9 [parent] - messmer/parallelaccessstore: 5 + messmer/parallelaccessstore: 6 [paths] # Local directories to look for headers (within block) # /