diff options
author | Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com> | 2017-09-04 04:33:15 +0300 |
---|---|---|
committer | Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com) <spamtrap@nedprod.com> | 2017-09-04 04:33:15 +0300 |
commit | 22417f35fdc10142a1bb18e6ecbc5e3ae1df021b (patch) | |
tree | 81c28047b9835b4196c4d1f75b9829cd2128431e | |
parent | 6476e05c0e2dfb41ba0274683dc8d5a06015c5a8 (diff) |
Append-only mode didn't actually work on POSIX, fixed :)
Toy key-value store now working on Linux. Was quite surprised at the causes of failure, all platform-specific quirks.
-rw-r--r-- | .travis.yml | 2 | ||||
-rw-r--r-- | include/afio/v2.0/detail/impl/posix/import.hpp | 2 | ||||
-rw-r--r-- | programs/key-value-store/Readme.md | 16 | ||||
-rw-r--r-- | programs/key-value-store/include/key_value_store.hpp | 36 |
4 files changed, 38 insertions, 18 deletions
diff --git a/.travis.yml b/.travis.yml index d66002a3..86ad733c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -74,7 +74,7 @@ script: if [ "$__" = "cmake tests" ]; then if [ "$CXX" = "g++" ]; then export CXX=g++-7; export NAME=TravisLinuxWorkerGCC; fi; if [ "$CXX" = "clang++" ]; then export CXX=clang++-4.0; export NAME=TravisLinuxWorkerClang; fi; - ctest -S .ci.cmake -V --timeout 300; + ctest -S .ci.cmake -V --timeout 600; fi - if [ "$__" = "Documentation" ]; then diff --git a/include/afio/v2.0/detail/impl/posix/import.hpp b/include/afio/v2.0/detail/impl/posix/import.hpp index a4dd435d..49ed702c 100644 --- a/include/afio/v2.0/detail/impl/posix/import.hpp +++ b/include/afio/v2.0/detail/impl/posix/import.hpp @@ -56,7 +56,7 @@ inline result<int> attribs_from_handle_mode_caching_and_flags(native_handle_type nativeh.behaviour |= native_handle_type::disposition::seekable | native_handle_type::disposition::readable | native_handle_type::disposition::writable; break; case handle::mode::append: - attribs = O_APPEND; + attribs = O_WRONLY | O_APPEND; nativeh.behaviour |= native_handle_type::disposition::writable | native_handle_type::disposition::append_only; break; } diff --git a/programs/key-value-store/Readme.md b/programs/key-value-store/Readme.md index 2767ad7c..bc6dfd3e 100644 --- a/programs/key-value-store/Readme.md +++ b/programs/key-value-store/Readme.md @@ -27,10 +27,24 @@ index update. Retrieving 1M key-value pairs ... Fetched at 612745 items per sec ``` -- 64 byte values Windows with NTFS, no integrity, no durability: +- 1Kb values Linux with ext4, no integrity, no durability: + ``` + Inserting 1M key-value pairs ... + Inserted at 656598 items per sec + Retrieving 1M key-value pairs ... + Fetched at 1945525 items per sec + ``` +- 16 byte values Windows with NTFS, no integrity, no durability: ``` Inserting 1M key-value pairs ... Inserted at 259201 items per sec Retrieving 1M key-value pairs ... Fetched at 700770 items per sec + ``` +- 16 byte values Linux with ext4, no integrity, no durability: + ``` + Inserting 1M key-value pairs ... + Inserted at 1118568 items per sec + Retrieving 1M key-value pairs ... + Fetched at 2898550 items per sec ```
\ No newline at end of file diff --git a/programs/key-value-store/include/key_value_store.hpp b/programs/key-value-store/include/key_value_store.hpp index 403d4952..111e0e04 100644 --- a/programs/key-value-store/include/key_value_store.hpp +++ b/programs/key-value-store/include/key_value_store.hpp @@ -181,6 +181,14 @@ namespace key_value_store } void _openfiles(const afio::path_handle &dir, afio::file_handle::mode mode, afio::file_handle::caching caching) { + const afio::file_handle::mode smallfilemode = +#ifdef _WIN32 + afio::file_handle::mode::read +#else + // Linux won't allow taking an exclusive lock on a read only file + afio::file_handle::mode::write +#endif + ; if(_smallfiles.read.empty()) { // Open the small files, choosing the first unclaimed small file as "mine" @@ -189,10 +197,11 @@ namespace key_value_store for(size_t n = 0; n < 48; n++) { name = std::to_string(n); - auto fh = afio::file_handle::file(dir, name, afio::file_handle::mode::read); + auto fh = afio::file_handle::file(dir, name, smallfilemode); if(fh) { - retry: + retry: + bool claimed=false; if(mode == afio::file_handle::mode::write && !_mysmallfile.is_valid()) { // Try to claim this small file @@ -200,26 +209,23 @@ namespace key_value_store if(smallfileclaimed) { _mysmallfile = afio::file_handle::file(dir, name, afio::file_handle::mode::append, afio::file_handle::creation::open_existing, caching).value(); - smallfileclaimed.value().unlock(); - smallfileclaimed = _mysmallfile.try_lock(_indexinuseoffset, 1, true); - if(smallfileclaimed) - { - _smallfileguard = std::move(smallfileclaimed).value(); - _mysmallfileidx = n; - } - else - { - _mysmallfile.close().value(); - } + _smallfileguard = std::move(smallfileclaimed).value(); + _mysmallfileidx = n; + _smallfiles.read.push_back(std::move(fh).value()); + _smallfileguard.set_handle(&_smallfiles.read.back()); + claimed=true; } } - _smallfiles.read.push_back(std::move(fh).value()); + if(!claimed) + { + _smallfiles.read.push_back(std::move(fh).value()); + } continue; } else if(mode == afio::file_handle::mode::write && !_mysmallfile.is_valid()) { // Going to need a new smallfile - fh = afio::file_handle::file(dir, name, afio::file_handle::mode::read, afio::file_handle::creation::only_if_not_exist, caching); + fh = afio::file_handle::file(dir, name, smallfilemode, afio::file_handle::creation::only_if_not_exist, caching); if(fh) { goto retry; |