aboutsummaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
authorAlexey Salmin <alexey.salmin@gmail.com>2022-02-10 16:49:37 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:49:37 +0300
commit71af077a5dfe7e9f932a508422c2dac81a57ebc0 (patch)
tree5d5cb817648f650d76cf1076100726fd9b8448e8 /util
parent3c5b1607b38f637d2f3313791ed25c2e080d2647 (diff)
downloadydb-71af077a5dfe7e9f932a508422c2dac81a57ebc0.tar.gz
Restoring authorship annotation for Alexey Salmin <alexey.salmin@gmail.com>. Commit 2 of 2.
Diffstat (limited to 'util')
-rw-r--r--util/generic/string.h112
-rw-r--r--util/network/sock_ut.cpp10
-rw-r--r--util/network/socket.cpp78
-rw-r--r--util/network/socket.h8
-rw-r--r--util/network/socket_ut.cpp62
-rw-r--r--util/stream/buffer.cpp16
-rw-r--r--util/stream/buffer.h2
-rw-r--r--util/stream/buffer_ut.cpp26
-rw-r--r--util/stream/buffered.cpp34
-rw-r--r--util/stream/buffered.h2
-rw-r--r--util/stream/buffered_ut.cpp26
-rw-r--r--util/stream/mem.cpp8
-rw-r--r--util/stream/mem.h2
-rw-r--r--util/stream/mem_ut.cpp28
-rw-r--r--util/stream/output.cpp8
-rw-r--r--util/stream/output.h16
-rw-r--r--util/stream/str.cpp6
-rw-r--r--util/stream/str.h2
-rw-r--r--util/stream/str_ut.cpp24
-rw-r--r--util/string/benchmark/join/main.cpp160
-rw-r--r--util/string/benchmark/join/metrics/main.py8
-rw-r--r--util/string/benchmark/join/metrics/ya.make28
-rw-r--r--util/string/benchmark/join/ya.make22
-rw-r--r--util/string/benchmark/ya.make4
-rw-r--r--util/string/cast.h8
-rw-r--r--util/string/join.h158
-rw-r--r--util/string/join_ut.cpp56
-rw-r--r--util/system/direct_io.cpp8
-rw-r--r--util/system/direct_io_ut.cpp8
-rw-r--r--util/system/filemap.cpp120
-rw-r--r--util/system/filemap.h12
-rw-r--r--util/system/filemap_ut.cpp126
-rw-r--r--util/system/mincore.cpp60
-rw-r--r--util/system/mincore.h76
-rw-r--r--util/system/mincore_ut.cpp90
-rw-r--r--util/system/unaligned_mem.h8
-rw-r--r--util/system/unaligned_mem_ut.cpp146
-rw-r--r--util/system/ut/ya.make8
-rw-r--r--util/ya.make2
39 files changed, 789 insertions, 789 deletions
diff --git a/util/generic/string.h b/util/generic/string.h
index 4e1650ef35..8cd8aa6917 100644
--- a/util/generic/string.h
+++ b/util/generic/string.h
@@ -842,93 +842,93 @@ public:
return this->MutRef();
}
- /*
- * Following overloads of "operator+" aim to choose the cheapest implementation depending on
- * summand types: lvalues, detached rvalues, shared rvalues.
- *
- * General idea is to use the detached-rvalue argument (left of right) to store the result
- * wherever possible. If a buffer in rvalue is large enough this saves a re-allocation. If
- * both arguments are rvalues we check which one is detached. If both of them are detached then
- * the left argument is obviously preferrable because you won't need to shift the data.
- *
- * If an rvalue is shared then it's basically the same as lvalue because you cannot use its
- * buffer to store the sum. However, we rely on the fact that append() and prepend() are already
- * optimized for the shared case and detach the string into the buffer large enough to store
- * the sum (compared to the detach+reallocation). This way, if we have only one rvalue argument
- * (left or right) then we simply append/prepend into it, without checking if it's detached or
- * not. This will be checked inside ReserveAndResize anyway.
- *
- * If both arguments cannot be used to store the sum (e.g. two lvalues) then we fall back to the
- * Join function that constructs a resulting string in the new buffer with the minimum overhead:
- * malloc + memcpy + memcpy.
- */
-
+ /*
+ * Following overloads of "operator+" aim to choose the cheapest implementation depending on
+ * summand types: lvalues, detached rvalues, shared rvalues.
+ *
+ * General idea is to use the detached-rvalue argument (left of right) to store the result
+ * wherever possible. If a buffer in rvalue is large enough this saves a re-allocation. If
+ * both arguments are rvalues we check which one is detached. If both of them are detached then
+ * the left argument is obviously preferrable because you won't need to shift the data.
+ *
+ * If an rvalue is shared then it's basically the same as lvalue because you cannot use its
+ * buffer to store the sum. However, we rely on the fact that append() and prepend() are already
+ * optimized for the shared case and detach the string into the buffer large enough to store
+ * the sum (compared to the detach+reallocation). This way, if we have only one rvalue argument
+ * (left or right) then we simply append/prepend into it, without checking if it's detached or
+ * not. This will be checked inside ReserveAndResize anyway.
+ *
+ * If both arguments cannot be used to store the sum (e.g. two lvalues) then we fall back to the
+ * Join function that constructs a resulting string in the new buffer with the minimum overhead:
+ * malloc + memcpy + memcpy.
+ */
+
friend TBasicString operator+(TBasicString&& s1, const TBasicString& s2) Y_WARN_UNUSED_RESULT {
s1 += s2;
- return std::move(s1);
+ return std::move(s1);
}
friend TBasicString operator+(const TBasicString& s1, TBasicString&& s2) Y_WARN_UNUSED_RESULT {
- s2.prepend(s1);
- return std::move(s2);
- }
-
+ s2.prepend(s1);
+ return std::move(s2);
+ }
+
friend TBasicString operator+(TBasicString&& s1, TBasicString&& s2) Y_WARN_UNUSED_RESULT {
#if 0 && !defined(TSTRING_IS_STD_STRING)
- if (!s1.IsDetached() && s2.IsDetached()) {
- s2.prepend(s1);
- return std::move(s2);
- }
+ if (!s1.IsDetached() && s2.IsDetached()) {
+ s2.prepend(s1);
+ return std::move(s2);
+ }
#endif
s1 += s2;
- return std::move(s1);
+ return std::move(s1);
}
friend TBasicString operator+(TBasicString&& s1, const TBasicStringBuf<TCharType, TTraits> s2) Y_WARN_UNUSED_RESULT {
s1 += s2;
- return std::move(s1);
+ return std::move(s1);
}
friend TBasicString operator+(TBasicString&& s1, const TCharType* s2) Y_WARN_UNUSED_RESULT {
s1 += s2;
- return std::move(s1);
+ return std::move(s1);
}
friend TBasicString operator+(TBasicString&& s1, TCharType s2) Y_WARN_UNUSED_RESULT {
- s1 += s2;
- return std::move(s1);
- }
-
+ s1 += s2;
+ return std::move(s1);
+ }
+
friend TBasicString operator+(TExplicitType<TCharType> ch, const TBasicString& s) Y_WARN_UNUSED_RESULT {
return Join(TCharType(ch), s);
}
friend TBasicString operator+(const TBasicString& s1, const TBasicString& s2) Y_WARN_UNUSED_RESULT {
- return Join(s1, s2);
- }
-
+ return Join(s1, s2);
+ }
+
friend TBasicString operator+(const TBasicString& s1, const TBasicStringBuf<TCharType, TTraits> s2) Y_WARN_UNUSED_RESULT {
- return Join(s1, s2);
- }
-
+ return Join(s1, s2);
+ }
+
friend TBasicString operator+(const TBasicString& s1, const TCharType* s2) Y_WARN_UNUSED_RESULT {
- return Join(s1, s2);
- }
-
+ return Join(s1, s2);
+ }
+
friend TBasicString operator+(const TBasicString& s1, TCharType s2) Y_WARN_UNUSED_RESULT {
return Join(s1, TBasicStringBuf<TCharType, TTraits>(&s2, 1));
- }
-
+ }
+
friend TBasicString operator+(const TCharType* s1, TBasicString&& s2) Y_WARN_UNUSED_RESULT {
- s2.prepend(s1);
- return std::move(s2);
- }
-
+ s2.prepend(s1);
+ return std::move(s2);
+ }
+
friend TBasicString operator+(const TBasicStringBuf<TCharType, TTraits> s1, TBasicString&& s2) Y_WARN_UNUSED_RESULT {
- s2.prepend(s1);
- return std::move(s2);
- }
-
+ s2.prepend(s1);
+ return std::move(s2);
+ }
+
friend TBasicString operator+(const TBasicStringBuf<TCharType, TTraits> s1, const TBasicString& s2) Y_WARN_UNUSED_RESULT {
return Join(s1, s2);
}
diff --git a/util/network/sock_ut.cpp b/util/network/sock_ut.cpp
index 232aeca2e5..fd8c783747 100644
--- a/util/network/sock_ut.cpp
+++ b/util/network/sock_ut.cpp
@@ -3,8 +3,8 @@
#include <library/cpp/testing/unittest/registar.h>
#include <library/cpp/threading/future/legacy_future.h>
-#include <util/system/fs.h>
-
+#include <util/system/fs.h>
+
Y_UNIT_TEST_SUITE(TSocketTest) {
Y_UNIT_TEST(InetDgramTest) {
char buf[256];
@@ -68,8 +68,8 @@ Y_UNIT_TEST_SUITE(TSocketTest) {
const char* localServerSockName = "./serv_sock";
const char* localClientSockName = "./cli_sock";
RunLocalDgramTest(localServerSockName, localClientSockName);
- NFs::Remove(localServerSockName);
- NFs::Remove(localClientSockName);
+ NFs::Remove(localServerSockName);
+ NFs::Remove(localClientSockName);
}
template <class A, class S>
@@ -162,7 +162,7 @@ Y_UNIT_TEST_SUITE(TSocketTest) {
Y_UNIT_TEST(LocalStreamTest) {
const char* localServerSockName = "./serv_sock2";
RunLocalStreamTest(localServerSockName);
- NFs::Remove(localServerSockName);
+ NFs::Remove(localServerSockName);
}
}
diff --git a/util/network/socket.cpp b/util/network/socket.cpp
index 32756f503e..4f6e804346 100644
--- a/util/network/socket.cpp
+++ b/util/network/socket.cpp
@@ -1255,43 +1255,43 @@ void ShutDown(SOCKET s, int mode) {
ythrow TSystemError() << "shutdown socket error";
}
}
-
+
extern "C" bool IsReusePortAvailable() {
-// SO_REUSEPORT is always defined for linux builds, see SetReusePort() implementation above
-#if defined(SO_REUSEPORT)
-
- class TCtx {
- public:
- TCtx() {
- TSocketHolder sock(::socket(AF_INET, SOCK_STREAM, 0));
- const int e1 = errno;
- if (sock == INVALID_SOCKET) {
- ythrow TSystemError(e1) << "Cannot create AF_INET socket";
- }
- int val;
- const int ret = GetSockOpt(sock, SOL_SOCKET, SO_REUSEPORT, val);
- const int e2 = errno;
- if (ret == 0) {
- Flag_ = true;
- } else {
- if (e2 == ENOPROTOOPT) {
- Flag_ = false;
- } else {
- ythrow TSystemError(e2) << "Unexpected error in getsockopt";
- }
- }
- }
-
- static inline const TCtx* Instance() noexcept {
- return Singleton<TCtx>();
- }
-
- public:
- bool Flag_;
- };
-
- return TCtx::Instance()->Flag_;
-#else
- return false;
-#endif
-}
+// SO_REUSEPORT is always defined for linux builds, see SetReusePort() implementation above
+#if defined(SO_REUSEPORT)
+
+ class TCtx {
+ public:
+ TCtx() {
+ TSocketHolder sock(::socket(AF_INET, SOCK_STREAM, 0));
+ const int e1 = errno;
+ if (sock == INVALID_SOCKET) {
+ ythrow TSystemError(e1) << "Cannot create AF_INET socket";
+ }
+ int val;
+ const int ret = GetSockOpt(sock, SOL_SOCKET, SO_REUSEPORT, val);
+ const int e2 = errno;
+ if (ret == 0) {
+ Flag_ = true;
+ } else {
+ if (e2 == ENOPROTOOPT) {
+ Flag_ = false;
+ } else {
+ ythrow TSystemError(e2) << "Unexpected error in getsockopt";
+ }
+ }
+ }
+
+ static inline const TCtx* Instance() noexcept {
+ return Singleton<TCtx>();
+ }
+
+ public:
+ bool Flag_;
+ };
+
+ return TCtx::Instance()->Flag_;
+#else
+ return false;
+#endif
+}
diff --git a/util/network/socket.h b/util/network/socket.h
index b560e47391..40c8648b40 100644
--- a/util/network/socket.h
+++ b/util/network/socket.h
@@ -136,11 +136,11 @@ ESocketReadStatus HasSocketDataToRead(SOCKET s);
**/
bool HasLocalAddress(SOCKET socket);
-/**
- * Runtime check if current kernel supports SO_REUSEPORT option.
- **/
+/**
+ * Runtime check if current kernel supports SO_REUSEPORT option.
+ **/
extern "C" bool IsReusePortAvailable();
-
+
bool IsNonBlock(SOCKET fd);
void SetNonBlock(SOCKET fd, bool nonBlock = true);
diff --git a/util/network/socket_ut.cpp b/util/network/socket_ut.cpp
index 5406312fe9..6b20e11f70 100644
--- a/util/network/socket_ut.cpp
+++ b/util/network/socket_ut.cpp
@@ -9,11 +9,11 @@
#include <ctime>
-#ifdef _linux_
+#ifdef _linux_
#include <linux/version.h>
#include <sys/utsname.h>
-#endif
-
+#endif
+
class TSockTest: public TTestBase {
UNIT_TEST_SUITE(TSockTest);
UNIT_TEST(TestSock);
@@ -25,7 +25,7 @@ class TSockTest: public TTestBase {
UNIT_TEST(TestNetworkResolutionErrorMessage);
UNIT_TEST(TestBrokenPipe);
UNIT_TEST(TestClose);
- UNIT_TEST(TestReusePortAvailCheck);
+ UNIT_TEST(TestReusePortAvailCheck);
UNIT_TEST_SUITE_END();
public:
@@ -36,7 +36,7 @@ public:
void TestNetworkResolutionErrorMessage();
void TestBrokenPipe();
void TestClose();
- void TestReusePortAvailCheck();
+ void TestReusePortAvailCheck();
};
UNIT_TEST_SUITE_REGISTRATION(TSockTest);
@@ -186,32 +186,32 @@ void TSockTest::TestClose() {
}
void TSockTest::TestReusePortAvailCheck() {
-#if defined _linux_
- utsname sysInfo;
- Y_VERIFY(!uname(&sysInfo), "Error while call uname: %s", LastSystemErrorText());
- TStringBuf release(sysInfo.release);
- release = release.substr(0, release.find_first_not_of(".0123456789"));
- int v1 = FromString<int>(release.NextTok('.'));
- int v2 = FromString<int>(release.NextTok('.'));
- int v3 = FromString<int>(release.NextTok('.'));
- int linuxVersionCode = KERNEL_VERSION(v1, v2, v3);
- if (linuxVersionCode >= KERNEL_VERSION(3, 9, 1)) {
- // new kernels support SO_REUSEPORT
- UNIT_ASSERT(true == IsReusePortAvailable());
- UNIT_ASSERT(true == IsReusePortAvailable());
- } else {
- // older kernels may or may not support SO_REUSEPORT
- // just check that it doesn't crash or throw
- (void)IsReusePortAvailable();
- (void)IsReusePortAvailable();
- }
-#else
- // check that it doesn't crash or throw
- (void)IsReusePortAvailable();
- (void)IsReusePortAvailable();
-#endif
-}
-
+#if defined _linux_
+ utsname sysInfo;
+ Y_VERIFY(!uname(&sysInfo), "Error while call uname: %s", LastSystemErrorText());
+ TStringBuf release(sysInfo.release);
+ release = release.substr(0, release.find_first_not_of(".0123456789"));
+ int v1 = FromString<int>(release.NextTok('.'));
+ int v2 = FromString<int>(release.NextTok('.'));
+ int v3 = FromString<int>(release.NextTok('.'));
+ int linuxVersionCode = KERNEL_VERSION(v1, v2, v3);
+ if (linuxVersionCode >= KERNEL_VERSION(3, 9, 1)) {
+ // new kernels support SO_REUSEPORT
+ UNIT_ASSERT(true == IsReusePortAvailable());
+ UNIT_ASSERT(true == IsReusePortAvailable());
+ } else {
+ // older kernels may or may not support SO_REUSEPORT
+ // just check that it doesn't crash or throw
+ (void)IsReusePortAvailable();
+ (void)IsReusePortAvailable();
+ }
+#else
+ // check that it doesn't crash or throw
+ (void)IsReusePortAvailable();
+ (void)IsReusePortAvailable();
+#endif
+}
+
class TPollTest: public TTestBase {
UNIT_TEST_SUITE(TPollTest);
UNIT_TEST(TestPollInOut);
diff --git a/util/stream/buffer.cpp b/util/stream/buffer.cpp
index ad4212f0cd..2facece4ea 100644
--- a/util/stream/buffer.cpp
+++ b/util/stream/buffer.cpp
@@ -30,10 +30,10 @@ public:
Data_.Append((const char*)buf, len);
}
- inline void DoWriteC(char c) {
- Data_.Append(c);
- }
-
+ inline void DoWriteC(char c) {
+ Data_.Append(c);
+ }
+
inline TBuffer& Buffer() const noexcept {
return Data_;
}
@@ -87,10 +87,10 @@ void TBufferOutput::DoWrite(const void* buf, size_t len) {
Impl_->DoWrite(buf, len);
}
-void TBufferOutput::DoWriteC(char c) {
- Impl_->DoWriteC(c);
-}
-
+void TBufferOutput::DoWriteC(char c) {
+ Impl_->DoWriteC(c);
+}
+
TBufferInput::TBufferInput(const TBuffer& buffer)
: Buf_(buffer)
, Readed_(0)
diff --git a/util/stream/buffer.h b/util/stream/buffer.h
index 2e0ba9144f..9dc99dbe49 100644
--- a/util/stream/buffer.h
+++ b/util/stream/buffer.h
@@ -49,7 +49,7 @@ private:
size_t DoNext(void** ptr) override;
void DoUndo(size_t len) override;
void DoWrite(const void* buf, size_t len) override;
- void DoWriteC(char c) override;
+ void DoWriteC(char c) override;
private:
THolder<TImpl> Impl_;
diff --git a/util/stream/buffer_ut.cpp b/util/stream/buffer_ut.cpp
index 84ba5d3f48..3494696190 100644
--- a/util/stream/buffer_ut.cpp
+++ b/util/stream/buffer_ut.cpp
@@ -4,8 +4,8 @@
#include <util/generic/buffer.h>
-#include <cstring>
-
+#include <cstring>
+
#include "str.h"
Y_UNIT_TEST_SUITE(TBufferTest) {
@@ -32,7 +32,7 @@ Y_UNIT_TEST_SUITE(TBufferTest) {
UNIT_ASSERT_VALUES_EQUAL(input.ReadTo(tmp, 'z'), 7);
UNIT_ASSERT_VALUES_EQUAL(tmp, "4567890");
}
-
+
Y_UNIT_TEST(WriteViaNextAndUndo) {
TBuffer buffer;
TBufferOutput output(buffer);
@@ -59,27 +59,27 @@ Y_UNIT_TEST_SUITE(TBufferTest) {
}
Y_UNIT_TEST(Write) {
- TBuffer buffer;
- TBufferOutput output(buffer);
+ TBuffer buffer;
+ TBufferOutput output(buffer);
output << "1"
<< "22"
<< "333"
<< "4444"
<< "55555";
-
+
UNIT_ASSERT(0 == memcmp(buffer.data(), "1"
"22"
"333"
"4444"
"55555",
buffer.size()));
- }
-
+ }
+
Y_UNIT_TEST(WriteChars) {
- TBuffer buffer;
- TBufferOutput output(buffer);
- output << '1' << '2' << '3' << '4' << '5' << '6' << '7' << '8' << '9' << '0';
-
+ TBuffer buffer;
+ TBufferOutput output(buffer);
+ output << '1' << '2' << '3' << '4' << '5' << '6' << '7' << '8' << '9' << '0';
+
UNIT_ASSERT(0 == memcmp(buffer.data(), "1234567890", buffer.size()));
- }
+ }
}
diff --git a/util/stream/buffered.cpp b/util/stream/buffered.cpp
index 229cb78423..a00e592e1c 100644
--- a/util/stream/buffered.cpp
+++ b/util/stream/buffered.cpp
@@ -193,16 +193,16 @@ public:
using TPart = IOutputStream::TPart;
- alignas(TPart) char data[2 * sizeof(TPart)];
- TPart* parts = reinterpret_cast<TPart*>(data);
+ alignas(TPart) char data[2 * sizeof(TPart)];
+ TPart* parts = reinterpret_cast<TPart*>(data);
TPart* end = parts;
if (stored) {
- new (end++) TPart(Buf(), stored);
+ new (end++) TPart(Buf(), stored);
}
if (write_from_buf) {
- new (end++) TPart(buf, write_from_buf);
+ new (end++) TPart(buf, write_from_buf);
}
Slave_->Write(parts, end - parts);
@@ -217,16 +217,16 @@ public:
}
}
- inline void Write(char c) {
- if (Y_UNLIKELY(MemOut_.Avail() == 0)) {
- Slave_->Write(Buf(), Stored());
- OnBufferExhausted();
- Reset();
- }
-
- MemOut_.Write(c);
- }
-
+ inline void Write(char c) {
+ if (Y_UNLIKELY(MemOut_.Avail() == 0)) {
+ Slave_->Write(Buf(), Stored());
+ OnBufferExhausted();
+ Reset();
+ }
+
+ MemOut_.Write(c);
+ }
+
inline void SetFlushPropagateMode(bool mode) noexcept {
PropagateFlush_ = mode;
}
@@ -382,11 +382,11 @@ void TBufferedOutputBase::DoWrite(const void* data, size_t len) {
Impl_->Write(data, len);
}
-void TBufferedOutputBase::DoWriteC(char c) {
+void TBufferedOutputBase::DoWriteC(char c) {
Y_ENSURE(Impl_.Get(), "cannot write to finished stream");
Impl_->Write(c);
-}
-
+}
+
void TBufferedOutputBase::DoFlush() {
if (Impl_.Get()) {
Impl_->Flush();
diff --git a/util/stream/buffered.h b/util/stream/buffered.h
index f7e4c03262..0847186141 100644
--- a/util/stream/buffered.h
+++ b/util/stream/buffered.h
@@ -114,7 +114,7 @@ protected:
size_t DoNext(void** ptr) override;
void DoUndo(size_t len) override;
void DoWrite(const void* data, size_t len) override;
- void DoWriteC(char c) override;
+ void DoWriteC(char c) override;
void DoFlush() override;
void DoFinish() override;
diff --git a/util/stream/buffered_ut.cpp b/util/stream/buffered_ut.cpp
index 075a388477..41d2fc3030 100644
--- a/util/stream/buffered_ut.cpp
+++ b/util/stream/buffered_ut.cpp
@@ -55,24 +55,24 @@ Y_UNIT_TEST_SUITE(TestBufferedIO) {
b.Write("1", 1);
b.Write("12", 2);
- b.Finish();
+ b.Finish();
UNIT_ASSERT_VALUES_EQUAL(s, "112");
}
Y_UNIT_TEST(Test4) {
- TString s;
-
- auto&& b = TBuffered<TStringOutput>(1, s);
-
- b.Write('1');
- b.Write('2');
- b.Write('3');
- b.Finish();
-
- UNIT_ASSERT_VALUES_EQUAL(s, "123");
- }
-
+ TString s;
+
+ auto&& b = TBuffered<TStringOutput>(1, s);
+
+ b.Write('1');
+ b.Write('2');
+ b.Write('3');
+ b.Finish();
+
+ UNIT_ASSERT_VALUES_EQUAL(s, "123");
+ }
+
template <class TOut>
inline void DoGenAndWrite(TOut&& output, TString& str) {
TMersenne<ui64> r;
diff --git a/util/stream/mem.cpp b/util/stream/mem.cpp
index 996e58b188..22a3339e27 100644
--- a/util/stream/mem.cpp
+++ b/util/stream/mem.cpp
@@ -58,8 +58,8 @@ void TMemoryOutput::DoWrite(const void* buf, size_t len) {
memcpy(Buf_, buf, len);
Buf_ = end;
}
-
-void TMemoryOutput::DoWriteC(char c) {
+
+void TMemoryOutput::DoWriteC(char c) {
Y_ENSURE(Buf_ < End_, TStringBuf("memory output stream exhausted"));
- *Buf_++ = c;
-}
+ *Buf_++ = c;
+}
diff --git a/util/stream/mem.h b/util/stream/mem.h
index 5d887f4842..18a5d46772 100644
--- a/util/stream/mem.h
+++ b/util/stream/mem.h
@@ -177,7 +177,7 @@ private:
size_t DoNext(void** ptr) override;
void DoUndo(size_t len) override;
void DoWrite(const void* buf, size_t len) override;
- void DoWriteC(char c) override;
+ void DoWriteC(char c) override;
protected:
char* Buf_;
diff --git a/util/stream/mem_ut.cpp b/util/stream/mem_ut.cpp
index 398db6598b..f388ae66ac 100644
--- a/util/stream/mem_ut.cpp
+++ b/util/stream/mem_ut.cpp
@@ -13,7 +13,7 @@ Y_UNIT_TEST_SUITE(TestMemIO) {
UNIT_ASSERT_VALUES_EQUAL(in.ReadTo(t, 'z'), 5);
UNIT_ASSERT_VALUES_EQUAL(t, "89abc");
}
-
+
Y_UNIT_TEST(NextAndUndo) {
char buffer[20];
TMemoryOutput output(buffer, sizeof(buffer));
@@ -51,28 +51,28 @@ Y_UNIT_TEST_SUITE(TestMemIO) {
}
Y_UNIT_TEST(Write) {
- char buffer[20];
- TMemoryOutput output(buffer, sizeof(buffer));
+ char buffer[20];
+ TMemoryOutput output(buffer, sizeof(buffer));
output << "1"
<< "22"
<< "333"
<< "4444"
<< "55555";
-
+
const char* const result = "1"
"22"
"333"
"4444"
"55555";
- UNIT_ASSERT(0 == memcmp(buffer, result, strlen(result)));
- }
-
+ UNIT_ASSERT(0 == memcmp(buffer, result, strlen(result)));
+ }
+
Y_UNIT_TEST(WriteChars) {
- char buffer[20];
- TMemoryOutput output(buffer, sizeof(buffer));
- output << '1' << '2' << '3' << '4' << '5' << '6' << '7' << '8' << '9' << '0';
-
- const char* const result = "1234567890";
- UNIT_ASSERT(0 == memcmp(buffer, result, strlen(result)));
- }
+ char buffer[20];
+ TMemoryOutput output(buffer, sizeof(buffer));
+ output << '1' << '2' << '3' << '4' << '5' << '6' << '7' << '8' << '9' << '0';
+
+ const char* const result = "1234567890";
+ UNIT_ASSERT(0 == memcmp(buffer, result, strlen(result)));
+ }
}
diff --git a/util/stream/output.cpp b/util/stream/output.cpp
index 82dd81a207..db81b81b70 100644
--- a/util/stream/output.cpp
+++ b/util/stream/output.cpp
@@ -48,10 +48,10 @@ void IOutputStream::DoWriteV(const TPart* parts, size_t count) {
}
}
-void IOutputStream::DoWriteC(char ch) {
- DoWrite(&ch, 1);
-}
-
+void IOutputStream::DoWriteC(char ch) {
+ DoWrite(&ch, 1);
+}
+
template <>
void Out<wchar16>(IOutputStream& o, wchar16 ch) {
const wchar32 w32ch = ReadSymbol(&ch, &ch + 1);
diff --git a/util/stream/output.h b/util/stream/output.h
index da6f052d5d..00eef50b95 100644
--- a/util/stream/output.h
+++ b/util/stream/output.h
@@ -104,7 +104,7 @@ public:
* @param ch Character to write.
*/
inline void Write(char ch) {
- DoWriteC(ch);
+ DoWriteC(ch);
}
/**
@@ -148,13 +148,13 @@ protected:
virtual void DoWriteV(const TPart* parts, size_t count);
/**
- * Writes a single character into this stream. Can be overridden with a faster implementation.
- *
- * @param ch Character to write.
- */
- virtual void DoWriteC(char ch);
-
- /**
+ * Writes a single character into this stream. Can be overridden with a faster implementation.
+ *
+ * @param ch Character to write.
+ */
+ virtual void DoWriteC(char ch);
+
+ /**
* Flushes this stream's buffer, if any.
*
* @throws yexception If IO error occurs.
diff --git a/util/stream/str.cpp b/util/stream/str.cpp
index 2d441db2f6..13f0e8ef28 100644
--- a/util/stream/str.cpp
+++ b/util/stream/str.cpp
@@ -37,8 +37,8 @@ void TStringOutput::DoWrite(const void* buf, size_t len) {
S_->append((const char*)buf, len);
}
-void TStringOutput::DoWriteC(char c) {
+void TStringOutput::DoWriteC(char c) {
S_->push_back(c);
-}
-
+}
+
TStringStream::~TStringStream() = default;
diff --git a/util/stream/str.h b/util/stream/str.h
index 651bab19ce..028bd572c0 100644
--- a/util/stream/str.h
+++ b/util/stream/str.h
@@ -98,7 +98,7 @@ protected:
size_t DoNext(void** ptr) override;
void DoUndo(size_t len) override;
void DoWrite(const void* buf, size_t len) override;
- void DoWriteC(char c) override;
+ void DoWriteC(char c) override;
private:
TString* S_;
diff --git a/util/stream/str_ut.cpp b/util/stream/str_ut.cpp
index cde603b86b..fc6b46c31a 100644
--- a/util/stream/str_ut.cpp
+++ b/util/stream/str_ut.cpp
@@ -87,7 +87,7 @@ Y_UNIT_TEST_SUITE(TStringInputOutputTest) {
UNIT_ASSERT_VALUES_EQUAL(in0.ReadTo(t, 'z'), 5);
UNIT_ASSERT_VALUES_EQUAL(t, "89abc");
}
-
+
Y_UNIT_TEST(WriteViaNextAndUndo) {
TString str1;
TStringOutput output(str1);
@@ -114,28 +114,28 @@ Y_UNIT_TEST_SUITE(TStringInputOutputTest) {
}
Y_UNIT_TEST(Write) {
- TString str;
- TStringOutput output(str);
+ TString str;
+ TStringOutput output(str);
output << "1"
<< "22"
<< "333"
<< "4444"
<< "55555";
-
+
UNIT_ASSERT_STRINGS_EQUAL(str, "1"
"22"
"333"
"4444"
"55555");
- }
-
+ }
+
Y_UNIT_TEST(WriteChars) {
- TString str;
- TStringOutput output(str);
- output << '1' << '2' << '3' << '4' << '5' << '6' << '7' << '8' << '9' << '0';
-
- UNIT_ASSERT_STRINGS_EQUAL(str, "1234567890");
- }
+ TString str;
+ TStringOutput output(str);
+ output << '1' << '2' << '3' << '4' << '5' << '6' << '7' << '8' << '9' << '0';
+
+ UNIT_ASSERT_STRINGS_EQUAL(str, "1234567890");
+ }
Y_UNIT_TEST(MoveConstructor) {
TString str;
diff --git a/util/string/benchmark/join/main.cpp b/util/string/benchmark/join/main.cpp
index 94466069d4..1a8633d3a8 100644
--- a/util/string/benchmark/join/main.cpp
+++ b/util/string/benchmark/join/main.cpp
@@ -1,70 +1,70 @@
#include <library/cpp/testing/benchmark/bench.h>
-
-#include <util/generic/function.h>
-#include <util/generic/singleton.h>
-#include <util/generic/vector.h>
-#include <util/generic/xrange.h>
-#include <util/random/fast.h>
-#include <util/string/cast.h>
-#include <util/string/join.h>
-
-namespace {
- // This class assigns random values to variadic lists of variables of different types.
- // It can be used to randomize a tuple via Apply() (arcadia version of std::apply).
- class TRandomizer {
- public:
- TRandomizer(ui64 seed)
- : Prng(seed)
- {
- }
-
- void Randomize(ui16& i) {
- i = static_cast<ui16>(Prng.GenRand());
- }
-
- void Randomize(ui32& i) {
- i = static_cast<ui32>(Prng.GenRand());
- }
-
- void Randomize(double& d) {
- d = Prng.GenRandReal4() + Prng.Uniform(Max<ui16>());
- }
-
- void Randomize(TString& s) {
- s = ::ToString(Prng.GenRand());
- }
-
+
+#include <util/generic/function.h>
+#include <util/generic/singleton.h>
+#include <util/generic/vector.h>
+#include <util/generic/xrange.h>
+#include <util/random/fast.h>
+#include <util/string/cast.h>
+#include <util/string/join.h>
+
+namespace {
+ // This class assigns random values to variadic lists of variables of different types.
+ // It can be used to randomize a tuple via Apply() (arcadia version of std::apply).
+ class TRandomizer {
+ public:
+ TRandomizer(ui64 seed)
+ : Prng(seed)
+ {
+ }
+
+ void Randomize(ui16& i) {
+ i = static_cast<ui16>(Prng.GenRand());
+ }
+
+ void Randomize(ui32& i) {
+ i = static_cast<ui32>(Prng.GenRand());
+ }
+
+ void Randomize(double& d) {
+ d = Prng.GenRandReal4() + Prng.Uniform(Max<ui16>());
+ }
+
+ void Randomize(TString& s) {
+ s = ::ToString(Prng.GenRand());
+ }
+
template <typename T, typename... TArgs>
- void Randomize(T& t, TArgs&... args) {
- Randomize(t);
- Randomize(args...);
- }
-
- private:
- TFastRng<ui64> Prng;
- };
-
+ void Randomize(T& t, TArgs&... args) {
+ Randomize(t);
+ Randomize(args...);
+ }
+
+ private:
+ TFastRng<ui64> Prng;
+ };
+
template <size_t N, typename... T>
- struct TExamplesHolder {
+ struct TExamplesHolder {
using TExamples = TVector<std::tuple<T...>>;
- TExamples Examples;
-
- TExamplesHolder()
- : Examples(N)
- {
- TRandomizer r{N * sizeof(typename TExamples::value_type) * 42};
- for (auto& x : Examples) {
+ TExamples Examples;
+
+ TExamplesHolder()
+ : Examples(N)
+ {
+ TRandomizer r{N * sizeof(typename TExamples::value_type) * 42};
+ for (auto& x : Examples) {
Apply([&r](T&... t) { r.Randomize(t...); }, x);
- }
- }
- };
-
+ }
+ }
+ };
+
template <typename... TArgs>
- TString JoinTuple(std::tuple<TArgs...> t) {
- return Apply([](TArgs... x) -> TString { return Join("-", x...); }, t);
- }
-}
-
+ TString JoinTuple(std::tuple<TArgs...> t) {
+ return Apply([](TArgs... x) -> TString { return Join("-", x...); }, t);
+ }
+}
+
#define DEFINE_BENCHMARK(count, types, ...) \
Y_CPU_BENCHMARK(Join_##count##_##types, iface) { \
const auto& examples = Default<TExamplesHolder<count, __VA_ARGS__>>().Examples; \
@@ -74,22 +74,22 @@ namespace {
Y_DO_NOT_OPTIMIZE_AWAY(JoinTuple(e)); \
} \
} \
- }
-
-DEFINE_BENCHMARK(100, SS, TString, TString);
-DEFINE_BENCHMARK(100, SSS, TString, TString, TString);
-DEFINE_BENCHMARK(100, SSSSS, TString, TString, TString, TString, TString);
-
-DEFINE_BENCHMARK(100, ss, ui16, ui16);
-DEFINE_BENCHMARK(100, SsS, TString, ui16, TString);
-DEFINE_BENCHMARK(100, SsSsS, TString, ui16, TString, ui16, TString);
-
-DEFINE_BENCHMARK(100, ii, ui32, ui32);
-DEFINE_BENCHMARK(100, SiS, TString, ui32, TString);
-DEFINE_BENCHMARK(100, SiSiS, TString, ui32, TString, ui32, TString);
-
-DEFINE_BENCHMARK(100, dd, double, double);
-DEFINE_BENCHMARK(100, SdS, TString, double, TString);
-DEFINE_BENCHMARK(100, SdSdS, TString, double, TString, double, TString);
-
-#undef DEFINE_BENCHMARK
+ }
+
+DEFINE_BENCHMARK(100, SS, TString, TString);
+DEFINE_BENCHMARK(100, SSS, TString, TString, TString);
+DEFINE_BENCHMARK(100, SSSSS, TString, TString, TString, TString, TString);
+
+DEFINE_BENCHMARK(100, ss, ui16, ui16);
+DEFINE_BENCHMARK(100, SsS, TString, ui16, TString);
+DEFINE_BENCHMARK(100, SsSsS, TString, ui16, TString, ui16, TString);
+
+DEFINE_BENCHMARK(100, ii, ui32, ui32);
+DEFINE_BENCHMARK(100, SiS, TString, ui32, TString);
+DEFINE_BENCHMARK(100, SiSiS, TString, ui32, TString, ui32, TString);
+
+DEFINE_BENCHMARK(100, dd, double, double);
+DEFINE_BENCHMARK(100, SdS, TString, double, TString);
+DEFINE_BENCHMARK(100, SdSdS, TString, double, TString, double, TString);
+
+#undef DEFINE_BENCHMARK
diff --git a/util/string/benchmark/join/metrics/main.py b/util/string/benchmark/join/metrics/main.py
index 60eb0e470f..1ed5014808 100644
--- a/util/string/benchmark/join/metrics/main.py
+++ b/util/string/benchmark/join/metrics/main.py
@@ -1,5 +1,5 @@
-import yatest.common as yc
-
-
-def test_export_metrics(metrics):
+import yatest.common as yc
+
+
+def test_export_metrics(metrics):
metrics.set_benchmark(yc.execute_benchmark('util/string/benchmark/join/join', threads=8))
diff --git a/util/string/benchmark/join/metrics/ya.make b/util/string/benchmark/join/metrics/ya.make
index bdbf806aa2..08ff3a149f 100644
--- a/util/string/benchmark/join/metrics/ya.make
+++ b/util/string/benchmark/join/metrics/ya.make
@@ -1,21 +1,21 @@
-OWNER(
- salmin
- g:util
-)
+OWNER(
+ salmin
+ g:util
+)
SUBSCRIBER(g:util-subscribers)
-
+
PY2TEST()
-
+
SIZE(LARGE)
-
-TAG(
+
+TAG(
ya:force_sandbox
- sb:intel_e5_2660v1
+ sb:intel_e5_2660v1
ya:fat
-)
-
+)
+
TEST_SRCS(main.py)
-
+
DEPENDS(util/string/benchmark/join)
-
-END()
+
+END()
diff --git a/util/string/benchmark/join/ya.make b/util/string/benchmark/join/ya.make
index 6ba2d2dadb..dfcc1d264e 100644
--- a/util/string/benchmark/join/ya.make
+++ b/util/string/benchmark/join/ya.make
@@ -1,13 +1,13 @@
Y_BENCHMARK()
-
-OWNER(
- salmin
- g:util
-)
+
+OWNER(
+ salmin
+ g:util
+)
SUBSCRIBER(g:util-subscribers)
-
-SRCS(
- main.cpp
-)
-
-END()
+
+SRCS(
+ main.cpp
+)
+
+END()
diff --git a/util/string/benchmark/ya.make b/util/string/benchmark/ya.make
index e6ab78b6f6..266b53c7b3 100644
--- a/util/string/benchmark/ya.make
+++ b/util/string/benchmark/ya.make
@@ -9,8 +9,8 @@ RECURSE(
cast
float_to_string
float_to_string/metrics
- join
- join/metrics
+ join
+ join/metrics
subst_global
subst_global/metrics
)
diff --git a/util/string/cast.h b/util/string/cast.h
index 9c230d1095..90e925c194 100644
--- a/util/string/cast.h
+++ b/util/string/cast.h
@@ -69,10 +69,10 @@ namespace NPrivate {
template <class T>
struct TToString<T, false> {
static inline TString Cvt(const T& t) {
- TString s;
- TStringOutput o(s);
- o << t;
- return s;
+ TString s;
+ TStringOutput o(s);
+ o << t;
+ return s;
}
};
}
diff --git a/util/string/join.h b/util/string/join.h
index a49e6dfe50..b166fad1f3 100644
--- a/util/string/join.h
+++ b/util/string/join.h
@@ -5,31 +5,31 @@
#include <util/string/cast.h>
#include "cast.h"
-/*
- * Default implementation of AppendToString uses a temporary TString object which is inefficient. You can overload it
- * for your type to speed up string joins. If you already have an Out() or operator<<() implementation you can simply
- * do the following:
- *
- * inline void AppendToString(TString& dst, const TMyType& t) {
- * TStringOutput o(dst);
- * o << t;
- * }
- *
- * Unfortunately we can't do this by default because for some types ToString() is defined while Out() is not.
- * For standard types (strings of all kinds and arithmetic types) we don't use a temporary TString in AppendToString().
- */
-
+/*
+ * Default implementation of AppendToString uses a temporary TString object which is inefficient. You can overload it
+ * for your type to speed up string joins. If you already have an Out() or operator<<() implementation you can simply
+ * do the following:
+ *
+ * inline void AppendToString(TString& dst, const TMyType& t) {
+ * TStringOutput o(dst);
+ * o << t;
+ * }
+ *
+ * Unfortunately we can't do this by default because for some types ToString() is defined while Out() is not.
+ * For standard types (strings of all kinds and arithmetic types) we don't use a temporary TString in AppendToString().
+ */
+
template <typename TCharType, typename T>
-inline std::enable_if_t<!std::is_arithmetic<std::remove_cv_t<T>>::value, void>
+inline std::enable_if_t<!std::is_arithmetic<std::remove_cv_t<T>>::value, void>
AppendToString(TBasicString<TCharType>& dst, const T& t) {
dst.AppendNoAlias(ToString(t));
-}
+}
template <typename TCharType, typename T>
-inline std::enable_if_t<std::is_arithmetic<std::remove_cv_t<T>>::value, void>
+inline std::enable_if_t<std::is_arithmetic<std::remove_cv_t<T>>::value, void>
AppendToString(TBasicString<TCharType>& dst, const T& t) {
- char buf[512];
- dst.append(buf, ToString<std::remove_cv_t<T>>(t, buf, sizeof(buf)));
+ char buf[512];
+ dst.append(buf, ToString<std::remove_cv_t<T>>(t, buf, sizeof(buf)));
}
template <typename TCharType>
@@ -42,59 +42,59 @@ inline void AppendToString(TBasicString<TCharType>& dst, TBasicStringBuf<TCharTy
dst.append(t);
}
-namespace NPrivate {
- template <typename T>
- inline size_t GetLength(const T&) {
- // By default don't pre-allocate space when joining and appending non-string types.
- // This code can be extended by estimating stringified length for specific types (e.g. 10 for ui32).
- return 0;
- }
-
- template <>
- inline size_t GetLength(const TString& s) {
- return s.length();
- }
-
- template <>
- inline size_t GetLength(const TStringBuf& s) {
- return s.length();
- }
-
- template <>
- inline size_t GetLength(const char* const& s) {
+namespace NPrivate {
+ template <typename T>
+ inline size_t GetLength(const T&) {
+ // By default don't pre-allocate space when joining and appending non-string types.
+ // This code can be extended by estimating stringified length for specific types (e.g. 10 for ui32).
+ return 0;
+ }
+
+ template <>
+ inline size_t GetLength(const TString& s) {
+ return s.length();
+ }
+
+ template <>
+ inline size_t GetLength(const TStringBuf& s) {
+ return s.length();
+ }
+
+ template <>
+ inline size_t GetLength(const char* const& s) {
return (s ? std::char_traits<char>::length(s) : 0);
- }
-
- inline size_t GetAppendLength(const TStringBuf /*delim*/) {
- return 0;
- }
-
- template <typename TFirst, typename... TRest>
- size_t GetAppendLength(const TStringBuf delim, const TFirst& f, const TRest&... r) {
- return delim.length() + ::NPrivate::GetLength(f) + ::NPrivate::GetAppendLength(delim, r...);
- }
+ }
+
+ inline size_t GetAppendLength(const TStringBuf /*delim*/) {
+ return 0;
+ }
+
+ template <typename TFirst, typename... TRest>
+ size_t GetAppendLength(const TStringBuf delim, const TFirst& f, const TRest&... r) {
+ return delim.length() + ::NPrivate::GetLength(f) + ::NPrivate::GetAppendLength(delim, r...);
+ }
}
template <typename TCharType>
inline void AppendJoinNoReserve(TBasicString<TCharType>&, TBasicStringBuf<TCharType>) {
-}
-
+}
+
template <typename TCharType, typename TFirst, typename... TRest>
inline void AppendJoinNoReserve(TBasicString<TCharType>& dst, TBasicStringBuf<TCharType> delim, const TFirst& f, const TRest&... r) {
AppendToString(dst, delim);
AppendToString(dst, f);
- AppendJoinNoReserve(dst, delim, r...);
+ AppendJoinNoReserve(dst, delim, r...);
+}
+
+template <typename... TValues>
+inline void AppendJoin(TString& dst, const TStringBuf delim, const TValues&... values) {
+ const size_t appendLength = ::NPrivate::GetAppendLength(delim, values...);
+ if (appendLength > 0) {
+ dst.reserve(dst.length() + appendLength);
+ }
+ AppendJoinNoReserve(dst, delim, values...);
}
-template <typename... TValues>
-inline void AppendJoin(TString& dst, const TStringBuf delim, const TValues&... values) {
- const size_t appendLength = ::NPrivate::GetAppendLength(delim, values...);
- if (appendLength > 0) {
- dst.reserve(dst.length() + appendLength);
- }
- AppendJoinNoReserve(dst, delim, values...);
-}
-
template <typename TFirst, typename... TRest>
inline TString Join(const TStringBuf delim, const TFirst& f, const TRest&... r) {
TString ret = ToString(f);
@@ -127,8 +127,8 @@ namespace NPrivate {
for (TIter pos = beg; ++pos != end;) {
AppendJoinNoReserve(out, delim, *pos);
}
- }
-
+ }
+
return out;
}
@@ -241,25 +241,25 @@ constexpr auto MakeRangeJoiner(TStringBuf delim, const std::initializer_list<TVa
return MakeRangeJoiner(delim, std::cbegin(data), std::cend(data));
}
-/* We force (std::initializer_list<TStringBuf>) input type for (TString) and (const char*) types because:
- * # When (std::initializer_list<TString>) is used, TString objects are copied into the initializer_list object.
- * Storing TStringBufs instead is faster, even with COW-enabled strings.
- * # For (const char*) we calculate length only once and store it in TStringBuf. Otherwise strlen scan would be executed
- * in both GetAppendLength and AppendToString. For string literals constant lengths get propagated in compile-time.
- *
- * This way JoinSeq(",", { s1, s2 }) always does the right thing whatever types s1 and s2 have.
- *
- * If someone needs to join std::initializer_list<TString> -- it still works because of the TContainer template above.
-*/
-
+/* We force (std::initializer_list<TStringBuf>) input type for (TString) and (const char*) types because:
+ * # When (std::initializer_list<TString>) is used, TString objects are copied into the initializer_list object.
+ * Storing TStringBufs instead is faster, even with COW-enabled strings.
+ * # For (const char*) we calculate length only once and store it in TStringBuf. Otherwise strlen scan would be executed
+ * in both GetAppendLength and AppendToString. For string literals constant lengths get propagated in compile-time.
+ *
+ * This way JoinSeq(",", { s1, s2 }) always does the right thing whatever types s1 and s2 have.
+ *
+ * If someone needs to join std::initializer_list<TString> -- it still works because of the TContainer template above.
+*/
+
template <typename T>
inline std::enable_if_t<
!std::is_same<std::decay_t<T>, TString>::value && !std::is_same<std::decay_t<T>, const char*>::value,
TString>
-JoinSeq(const TStringBuf delim, const std::initializer_list<T>& data) {
+JoinSeq(const TStringBuf delim, const std::initializer_list<T>& data) {
+ return JoinRange(delim, data.begin(), data.end());
+}
+
+inline TString JoinSeq(const TStringBuf delim, const std::initializer_list<TStringBuf>& data) {
return JoinRange(delim, data.begin(), data.end());
}
-
-inline TString JoinSeq(const TStringBuf delim, const std::initializer_list<TStringBuf>& data) {
- return JoinRange(delim, data.begin(), data.end());
-}
diff --git a/util/string/join_ut.cpp b/util/string/join_ut.cpp
index 74ff515da9..3ed2b2459c 100644
--- a/util/string/join_ut.cpp
+++ b/util/string/join_ut.cpp
@@ -39,18 +39,18 @@ Y_UNIT_TEST_SUITE(JoinStringTest) {
}
Y_UNIT_TEST(StrContainerItems) {
- // try various overloads and template type arguments
- static const char* const result = "1 22 333";
- static const char* const v[] = {"1", "22", "333"};
+ // try various overloads and template type arguments
+ static const char* const result = "1 22 333";
+ static const char* const v[] = {"1", "22", "333"};
TVector<const char*> vchar(v, v + sizeof(v) / sizeof(v[0]));
TVector<TStringBuf> vbuf(v, v + sizeof(v) / sizeof(v[0]));
TVector<TString> vstring(v, v + sizeof(v) / sizeof(v[0]));
-
- // ranges
- UNIT_ASSERT_EQUAL(JoinRange(" ", v, v + 3), result);
- UNIT_ASSERT_EQUAL(JoinRange(" ", vchar.begin(), vchar.end()), result);
- UNIT_ASSERT_EQUAL(JoinRange(" ", vbuf.begin(), vbuf.end()), result);
- UNIT_ASSERT_EQUAL(JoinRange(" ", vstring.begin(), vstring.end()), result);
+
+ // ranges
+ UNIT_ASSERT_EQUAL(JoinRange(" ", v, v + 3), result);
+ UNIT_ASSERT_EQUAL(JoinRange(" ", vchar.begin(), vchar.end()), result);
+ UNIT_ASSERT_EQUAL(JoinRange(" ", vbuf.begin(), vbuf.end()), result);
+ UNIT_ASSERT_EQUAL(JoinRange(" ", vstring.begin(), vstring.end()), result);
{
TStringStream stream;
stream << MakeRangeJoiner(" ", v, v + 3);
@@ -71,11 +71,11 @@ Y_UNIT_TEST_SUITE(JoinStringTest) {
stream << MakeRangeJoiner(" ", vstring.begin(), vstring.end());
UNIT_ASSERT_EQUAL(stream.Str(), result);
}
-
- // vectors
- UNIT_ASSERT_EQUAL(JoinSeq(" ", vchar), result);
- UNIT_ASSERT_EQUAL(JoinSeq(" ", vbuf), result);
- UNIT_ASSERT_EQUAL(JoinSeq(" ", vstring), result);
+
+ // vectors
+ UNIT_ASSERT_EQUAL(JoinSeq(" ", vchar), result);
+ UNIT_ASSERT_EQUAL(JoinSeq(" ", vbuf), result);
+ UNIT_ASSERT_EQUAL(JoinSeq(" ", vstring), result);
{
TStringStream stream;
stream << MakeRangeJoiner(" ", vchar);
@@ -91,12 +91,12 @@ Y_UNIT_TEST_SUITE(JoinStringTest) {
stream << MakeRangeJoiner(" ", vstring);
UNIT_ASSERT_EQUAL(stream.Str(), result);
}
-
- // initializer lists with type deduction
- UNIT_ASSERT_EQUAL(JoinSeq(" ", {v[0], v[1], v[2]}), result);
- UNIT_ASSERT_EQUAL(JoinSeq(" ", {vchar[0], vchar[1], vchar[2]}), result);
- UNIT_ASSERT_EQUAL(JoinSeq(" ", {vbuf[0], vbuf[1], vbuf[2]}), result);
- UNIT_ASSERT_EQUAL(JoinSeq(" ", {vstring[0], vstring[1], vstring[2]}), result);
+
+ // initializer lists with type deduction
+ UNIT_ASSERT_EQUAL(JoinSeq(" ", {v[0], v[1], v[2]}), result);
+ UNIT_ASSERT_EQUAL(JoinSeq(" ", {vchar[0], vchar[1], vchar[2]}), result);
+ UNIT_ASSERT_EQUAL(JoinSeq(" ", {vbuf[0], vbuf[1], vbuf[2]}), result);
+ UNIT_ASSERT_EQUAL(JoinSeq(" ", {vstring[0], vstring[1], vstring[2]}), result);
{
TStringStream stream;
stream << MakeRangeJoiner(" ", {v[0], v[1], v[2]});
@@ -117,12 +117,12 @@ Y_UNIT_TEST_SUITE(JoinStringTest) {
stream << MakeRangeJoiner(" ", {vstring[0], vstring[1], vstring[2]});
UNIT_ASSERT_EQUAL(stream.Str(), result);
}
-
- // initializer lists with explicit types
- UNIT_ASSERT_EQUAL(JoinSeq(" ", std::initializer_list<const char*>{v[0], v[1], v[2]}), result);
- UNIT_ASSERT_EQUAL(JoinSeq(" ", std::initializer_list<const char*>{vchar[0], vchar[1], vchar[2]}), result);
- UNIT_ASSERT_EQUAL(JoinSeq(" ", std::initializer_list<TStringBuf>{vbuf[0], vbuf[1], vbuf[2]}), result);
- UNIT_ASSERT_EQUAL(JoinSeq(" ", std::initializer_list<TString>{vstring[0], vstring[1], vstring[2]}), result);
+
+ // initializer lists with explicit types
+ UNIT_ASSERT_EQUAL(JoinSeq(" ", std::initializer_list<const char*>{v[0], v[1], v[2]}), result);
+ UNIT_ASSERT_EQUAL(JoinSeq(" ", std::initializer_list<const char*>{vchar[0], vchar[1], vchar[2]}), result);
+ UNIT_ASSERT_EQUAL(JoinSeq(" ", std::initializer_list<TStringBuf>{vbuf[0], vbuf[1], vbuf[2]}), result);
+ UNIT_ASSERT_EQUAL(JoinSeq(" ", std::initializer_list<TString>{vstring[0], vstring[1], vstring[2]}), result);
{
TStringStream stream;
stream << MakeRangeJoiner(" ", std::initializer_list<const char*>{v[0], v[1], v[2]});
@@ -146,8 +146,8 @@ Y_UNIT_TEST_SUITE(JoinStringTest) {
// c-style array
UNIT_ASSERT_VALUES_EQUAL(JoinSeq(" ", v), result);
- }
-
+ }
+
Y_UNIT_TEST(CustomToString) {
TCustomData d1{{1, 2, 3, 4, 5}};
TCustomData d2{{0, -1, -2}};
diff --git a/util/system/direct_io.cpp b/util/system/direct_io.cpp
index 8a0d453bdd..f59c54b0cb 100644
--- a/util/system/direct_io.cpp
+++ b/util/system/direct_io.cpp
@@ -34,10 +34,10 @@ namespace {
} else if (linuxVersionCode < KERNEL_VERSION(2, 6, 0)) {
Alignment = NSystemInfo::GetPageSize();
} else {
- // Default alignment used to be 512, but most modern devices rely on 4k physical blocks.
- // 4k alignment works well for both 512 and 4k blocks and doesn't require 512e support in the kernel.
- // See IGNIETFERRO-946.
- Alignment = 4096;
+ // Default alignment used to be 512, but most modern devices rely on 4k physical blocks.
+ // 4k alignment works well for both 512 and 4k blocks and doesn't require 512e support in the kernel.
+ // See IGNIETFERRO-946.
+ Alignment = 4096;
}
#endif
}
diff --git a/util/system/direct_io_ut.cpp b/util/system/direct_io_ut.cpp
index d6f5e26ffa..839c3de7ca 100644
--- a/util/system/direct_io_ut.cpp
+++ b/util/system/direct_io_ut.cpp
@@ -1,7 +1,7 @@
#include <library/cpp/testing/unittest/registar.h>
#include <util/generic/yexception.h>
-#include <util/system/fs.h>
+#include <util/system/fs.h>
#include <util/system/tempfile.h>
#include <util/random/random.h>
@@ -11,7 +11,7 @@ static const char* FileName_("./test.file");
Y_UNIT_TEST_SUITE(TDirectIoTestSuite) {
Y_UNIT_TEST(TestDirectFile) {
- TDirectIOBufferedFile file(FileName_, RdWr | Direct | Seq | CreateAlways, 1 << 15);
+ TDirectIOBufferedFile file(FileName_, RdWr | Direct | Seq | CreateAlways, 1 << 15);
TVector<ui64> data((1 << 15) + 1);
TVector<ui64> readResult(data.size());
for (auto& i : data) {
@@ -31,7 +31,7 @@ Y_UNIT_TEST_SUITE(TDirectIoTestSuite) {
}
}
file.Finish();
- TDirectIOBufferedFile fileNew(FileName_, RdOnly | Direct | Seq | OpenAlways, 1 << 15);
+ TDirectIOBufferedFile fileNew(FileName_, RdOnly | Direct | Seq | OpenAlways, 1 << 15);
for (int i = 0; i < 1000; ++i) {
size_t readPos = RandomNumber(data.size());
size_t readCount = RandomNumber(data.size() - readPos);
@@ -49,7 +49,7 @@ Y_UNIT_TEST_SUITE(TDirectIoTestSuite) {
for (size_t i = 0; i < readCount; ++i) {
UNIT_ASSERT_VALUES_EQUAL(readResult[i], data[i]);
}
- NFs::Remove(FileName_);
+ NFs::Remove(FileName_);
}
void TestHugeFile(size_t size) {
diff --git a/util/system/filemap.cpp b/util/system/filemap.cpp
index f6e3a7f5b7..7454a4cb94 100644
--- a/util/system/filemap.cpp
+++ b/util/system/filemap.cpp
@@ -126,7 +126,7 @@ void NPrivate::Precharge(const void* data, size_t dataSize, size_t off, size_t s
class TMemoryMap::TImpl: public TAtomicRefCount<TImpl> {
public:
- inline void CreateMapping() {
+ inline void CreateMapping() {
#if defined(_win_)
Mapping_ = nullptr;
if (Length_) {
@@ -134,7 +134,7 @@ public:
(Mode_ & oAccessMask) == TFileMap::oRdWr ? PAGE_READWRITE : PAGE_READONLY,
(DWORD)(Length_ >> 32), (DWORD)(Length_ & 0xFFFFFFFF), nullptr);
if (Mapping_ == nullptr) {
- ythrow yexception() << "Can't create file mapping of '" << DbgName_ << "': " << LastSystemErrorText();
+ ythrow yexception() << "Can't create file mapping of '" << DbgName_ << "': " << LastSystemErrorText();
}
} else {
Mapping_ = MAP_FAILED;
@@ -144,7 +144,7 @@ public:
PtrStart_ = mmap((caddr_t) nullptr, Length_, ModeToMmapProt(Mode_), ModeToMmapFlags(Mode_), File_.GetHandle(), 0);
if ((MAP_FAILED == PtrStart_) && Length_) {
- ythrow yexception() << "Can't map " << (unsigned long)Length_ << " bytes of file '" << DbgName_ << "' at offset 0: " << LastSystemErrorText();
+ ythrow yexception() << "Can't map " << (unsigned long)Length_ << " bytes of file '" << DbgName_ << "' at offset 0: " << LastSystemErrorText();
}
} else {
PtrStart_ = nullptr;
@@ -152,58 +152,58 @@ public:
#endif
}
- void CheckFile() const {
+ void CheckFile() const {
if (!File_.IsOpen()) {
- ythrow yexception() << "TMemoryMap: FILE '" << DbgName_ << "' is not open, " << LastSystemErrorText();
+ ythrow yexception() << "TMemoryMap: FILE '" << DbgName_ << "' is not open, " << LastSystemErrorText();
}
if (Length_ < 0) {
- ythrow yexception() << "'" << DbgName_ << "' is not a regular file";
+ ythrow yexception() << "'" << DbgName_ << "' is not a regular file";
}
}
inline TImpl(FILE* f, EOpenMode om, TString dbgName)
: File_(Duplicate(f))
- , DbgName_(std::move(dbgName))
+ , DbgName_(std::move(dbgName))
, Length_(File_.GetLength())
, Mode_(om)
{
- CheckFile();
- CreateMapping();
+ CheckFile();
+ CreateMapping();
}
inline TImpl(const TString& name, EOpenMode om)
: File_(name, (om & oRdWr) ? OpenExisting | RdWr : OpenExisting | RdOnly)
- , DbgName_(name)
+ , DbgName_(name)
, Length_(File_.GetLength())
, Mode_(om)
{
- CheckFile();
- CreateMapping();
+ CheckFile();
+ CreateMapping();
}
inline TImpl(const TString& name, i64 length, EOpenMode om)
: File_(name, (om & oRdWr) ? OpenExisting | RdWr : OpenExisting | RdOnly)
- , DbgName_(name)
+ , DbgName_(name)
, Length_(length)
, Mode_(om)
{
- CheckFile();
+ CheckFile();
if (File_.GetLength() < Length_) {
File_.Resize(Length_);
}
- CreateMapping();
+ CreateMapping();
}
inline TImpl(const TFile& file, EOpenMode om, TString dbgName)
: File_(file)
- , DbgName_(File_.GetName() ? File_.GetName() : std::move(dbgName))
+ , DbgName_(File_.GetName() ? File_.GetName() : std::move(dbgName))
, Length_(File_.GetLength())
, Mode_(om)
{
- CheckFile();
- CreateMapping();
+ CheckFile();
+ CreateMapping();
}
inline bool IsOpen() const noexcept {
@@ -218,15 +218,15 @@ public:
return (Mode_ & oRdWr || Mode_ & oCopyOnWr);
}
- inline TMapResult Map(i64 offset, size_t size) {
+ inline TMapResult Map(i64 offset, size_t size) {
assert(File_.IsOpen());
if (offset > Length_) {
- ythrow yexception() << "Can't map something at offset " << offset << " of '" << DbgName_ << "' with length " << Length_;
+ ythrow yexception() << "Can't map something at offset " << offset << " of '" << DbgName_ << "' with length " << Length_;
}
if (offset + (i64)size > Length_) {
- ythrow yexception() << "Can't map " << (unsigned long)size << " bytes at offset " << offset << " of '" << DbgName_ << "' with length " << Length_;
+ ythrow yexception() << "Can't map " << (unsigned long)size << " bytes at offset " << offset << " of '" << DbgName_ << "' with length " << Length_;
}
TMapResult result;
@@ -258,7 +258,7 @@ public:
if (result.Ptr != nullptr || size == 0) { // allow map of size 0
result.Size = size;
} else {
- ythrow yexception() << "Can't map " << (unsigned long)size << " bytes at offset " << offset << " of '" << DbgName_ << "': " << LastSystemErrorText();
+ ythrow yexception() << "Can't map " << (unsigned long)size << " bytes at offset " << offset << " of '" << DbgName_ << "': " << LastSystemErrorText();
}
NSan::Unpoison(result.Ptr, result.Size);
if (Mode_ & oPrecharge) {
@@ -326,13 +326,13 @@ public:
}
inline TString GetDbgName() const {
- return DbgName_;
- }
-
- inline EOpenMode GetMode() const noexcept {
- return Mode_;
- }
-
+ return DbgName_;
+ }
+
+ inline EOpenMode GetMode() const noexcept {
+ return Mode_;
+ }
+
private:
TFile File_;
TString DbgName_; // This string is never used to actually open a file, only in exceptions
@@ -362,29 +362,29 @@ TMemoryMap::TMemoryMap(const TString& name, i64 length, EOpenMode om)
}
TMemoryMap::TMemoryMap(FILE* f, TString dbgName)
- : Impl_(new TImpl(f, EOpenModeFlag::oRdOnly, std::move(dbgName)))
+ : Impl_(new TImpl(f, EOpenModeFlag::oRdOnly, std::move(dbgName)))
{
}
TMemoryMap::TMemoryMap(FILE* f, EOpenMode om, TString dbgName)
- : Impl_(new TImpl(f, om, std::move(dbgName)))
+ : Impl_(new TImpl(f, om, std::move(dbgName)))
{
}
TMemoryMap::TMemoryMap(const TFile& file, TString dbgName)
- : Impl_(new TImpl(file, EOpenModeFlag::oRdOnly, std::move(dbgName)))
+ : Impl_(new TImpl(file, EOpenModeFlag::oRdOnly, std::move(dbgName)))
{
}
TMemoryMap::TMemoryMap(const TFile& file, EOpenMode om, TString dbgName)
- : Impl_(new TImpl(file, om, std::move(dbgName)))
+ : Impl_(new TImpl(file, om, std::move(dbgName)))
{
}
TMemoryMap::~TMemoryMap() = default;
-TMemoryMap::TMapResult TMemoryMap::Map(i64 offset, size_t size) {
- return Impl_->Map(offset, size);
+TMemoryMap::TMapResult TMemoryMap::Map(i64 offset, size_t size) {
+ return Impl_->Map(offset, size);
}
bool TMemoryMap::Unmap(void* ptr, size_t size) {
@@ -395,18 +395,18 @@ bool TMemoryMap::Unmap(TMapResult region) {
return Unmap(region.Ptr, region.Size);
}
-void TMemoryMap::ResizeAndReset(i64 size) {
- EOpenMode om = Impl_->GetMode();
- TFile file = GetFile();
- file.Resize(size);
- Impl_.Reset(new TImpl(file, om, Impl_->GetDbgName()));
-}
-
-TMemoryMap::TMapResult TMemoryMap::ResizeAndRemap(i64 offset, size_t size) {
- ResizeAndReset(offset + (i64)size);
- return Map(offset, size);
-}
-
+void TMemoryMap::ResizeAndReset(i64 size) {
+ EOpenMode om = Impl_->GetMode();
+ TFile file = GetFile();
+ file.Resize(size);
+ Impl_.Reset(new TImpl(file, om, Impl_->GetDbgName()));
+}
+
+TMemoryMap::TMapResult TMemoryMap::ResizeAndRemap(i64 offset, size_t size) {
+ ResizeAndReset(offset + (i64)size);
+ return Map(offset, size);
+}
+
void TMemoryMap::SetSequential() {
Impl_->SetSequential();
}
@@ -460,12 +460,12 @@ TFileMap::TFileMap(const TString& name, i64 length, EOpenMode om)
}
TFileMap::TFileMap(FILE* f, EOpenMode om, TString dbgName)
- : Map_(f, om, dbgName)
+ : Map_(f, om, dbgName)
{
}
TFileMap::TFileMap(const TFile& file, EOpenMode om, TString dbgName)
- : Map_(file, om, dbgName)
+ : Map_(file, om, dbgName)
{
}
@@ -491,19 +491,19 @@ void TFileMap::Flush(void* ptr, size_t size, bool sync) {
#endif
}
-TFileMap::TMapResult TFileMap::Map(i64 offset, size_t size) {
+TFileMap::TMapResult TFileMap::Map(i64 offset, size_t size) {
+ Unmap();
+ Region_ = Map_.Map(offset, size);
+ return Region_;
+}
+
+TFileMap::TMapResult TFileMap::ResizeAndRemap(i64 offset, size_t size) {
+ // explicit Unmap() is required because in oNotGreedy mode the Map_ object doesn't own the mapped area
Unmap();
- Region_ = Map_.Map(offset, size);
- return Region_;
+ Region_ = Map_.ResizeAndRemap(offset, size);
+ return Region_;
}
-TFileMap::TMapResult TFileMap::ResizeAndRemap(i64 offset, size_t size) {
- // explicit Unmap() is required because in oNotGreedy mode the Map_ object doesn't own the mapped area
- Unmap();
- Region_ = Map_.ResizeAndRemap(offset, size);
- return Region_;
-}
-
void TFileMap::Unmap() {
if (!Region_.IsMapped()) {
return;
@@ -518,7 +518,7 @@ void TFileMap::Unmap() {
TFileMap::~TFileMap() {
try {
- // explicit Unmap() is required because in oNotGreedy mode the Map_ object doesn't own the mapped area
+ // explicit Unmap() is required because in oNotGreedy mode the Map_ object doesn't own the mapped area
Unmap();
} catch (...) {
// ¯\_(ツ)_/¯
diff --git a/util/system/filemap.h b/util/system/filemap.h
index 31eac6de47..11be64bff4 100644
--- a/util/system/filemap.h
+++ b/util/system/filemap.h
@@ -80,12 +80,12 @@ public:
~TMemoryMap();
- TMapResult Map(i64 offset, size_t size);
+ TMapResult Map(i64 offset, size_t size);
bool Unmap(TMapResult region);
- void ResizeAndReset(i64 size);
- TMapResult ResizeAndRemap(i64 offset, size_t size);
-
+ void ResizeAndReset(i64 size);
+ TMapResult ResizeAndRemap(i64 offset, size_t size);
+
i64 Length() const noexcept;
bool IsOpen() const noexcept;
bool IsWritable() const noexcept;
@@ -118,8 +118,8 @@ public:
~TFileMap();
- TMapResult Map(i64 offset, size_t size);
- TMapResult ResizeAndRemap(i64 offset, size_t size);
+ TMapResult Map(i64 offset, size_t size);
+ TMapResult ResizeAndRemap(i64 offset, size_t size);
void Unmap();
void Flush(void* ptr, size_t size) {
diff --git a/util/system/filemap_ut.cpp b/util/system/filemap_ut.cpp
index c796562f26..73f109dc88 100644
--- a/util/system/filemap_ut.cpp
+++ b/util/system/filemap_ut.cpp
@@ -6,11 +6,11 @@
#include "filemap.h"
-#include <util/system/fs.h>
-
-#include <cstring>
-#include <cstdio>
-
+#include <util/system/fs.h>
+
+#include <cstring>
+#include <cstdio>
+
Y_UNIT_TEST_SUITE(TFileMapTest) {
static const char* FileName_("./mappped_file");
@@ -32,9 +32,9 @@ Y_UNIT_TEST_SUITE(TFileMapTest) {
}
mappedFile.Flush();
- TFileMap::TMapResult mapResult = mappedFile.Map(2, 2);
- UNIT_ASSERT(mapResult.MappedSize() == 2);
- UNIT_ASSERT(mapResult.MappedData() == mappedFile.Ptr());
+ TFileMap::TMapResult mapResult = mappedFile.Map(2, 2);
+ UNIT_ASSERT(mapResult.MappedSize() == 2);
+ UNIT_ASSERT(mapResult.MappedData() == mappedFile.Ptr());
UNIT_ASSERT(mappedFile.MappedSize() == 2);
UNIT_ASSERT(static_cast<char*>(mappedFile.Ptr())[0] == 'd' && static_cast<char*>(mappedFile.Ptr())[1] == 'e');
@@ -48,7 +48,7 @@ Y_UNIT_TEST_SUITE(TFileMapTest) {
UNIT_ASSERT(static_cast<char*>(mappedFile2.Ptr())[0] == data[0] + 1);
fclose(f);
}
- NFs::Remove(FileName_);
+ NFs::Remove(FileName_);
}
Y_UNIT_TEST(TestFileMap) {
@@ -60,26 +60,26 @@ Y_UNIT_TEST_SUITE(TFileMapTest) {
}
Y_UNIT_TEST(TestFileRemap) {
- const char data1[] = "01234";
- const char data2[] = "abcdefg";
+ const char data1[] = "01234";
+ const char data2[] = "abcdefg";
const char data3[] = "COPY";
- const char dataFinal[] = "012abcdefg";
- const size_t data2Shift = 3;
-
- TFile file(FileName_, CreateAlways | WrOnly);
- file.Write(static_cast<const void*>(data1), sizeof(data1));
- file.Close();
-
- {
- TFileMap mappedFile(FileName_, TMemoryMapCommon::oRdWr);
- mappedFile.Map(0, mappedFile.Length());
+ const char dataFinal[] = "012abcdefg";
+ const size_t data2Shift = 3;
+
+ TFile file(FileName_, CreateAlways | WrOnly);
+ file.Write(static_cast<const void*>(data1), sizeof(data1));
+ file.Close();
+
+ {
+ TFileMap mappedFile(FileName_, TMemoryMapCommon::oRdWr);
+ mappedFile.Map(0, mappedFile.Length());
UNIT_ASSERT(mappedFile.MappedSize() == sizeof(data1) &&
mappedFile.Length() == sizeof(data1));
-
- mappedFile.ResizeAndRemap(data2Shift, sizeof(data2));
- memcpy(mappedFile.Ptr(), data2, sizeof(data2));
- }
-
+
+ mappedFile.ResizeAndRemap(data2Shift, sizeof(data2));
+ memcpy(mappedFile.Ptr(), data2, sizeof(data2));
+ }
+
{
TFileMap mappedFile(FileName_, TMemoryMapCommon::oCopyOnWr);
mappedFile.Map(0, mappedFile.Length());
@@ -94,38 +94,38 @@ Y_UNIT_TEST_SUITE(TFileMapTest) {
UNIT_ASSERT(data[3] == 'Y');
}
- TFile resFile(FileName_, RdOnly);
- UNIT_ASSERT(resFile.GetLength() == sizeof(dataFinal));
- char buf[sizeof(dataFinal)];
- resFile.Read(buf, sizeof(dataFinal));
- UNIT_ASSERT(0 == memcmp(buf, dataFinal, sizeof(dataFinal)));
- resFile.Close();
-
- NFs::Remove(FileName_);
- }
-
+ TFile resFile(FileName_, RdOnly);
+ UNIT_ASSERT(resFile.GetLength() == sizeof(dataFinal));
+ char buf[sizeof(dataFinal)];
+ resFile.Read(buf, sizeof(dataFinal));
+ UNIT_ASSERT(0 == memcmp(buf, dataFinal, sizeof(dataFinal)));
+ resFile.Close();
+
+ NFs::Remove(FileName_);
+ }
+
Y_UNIT_TEST(TestFileMapDbgName) {
- // This test checks that dbgName passed to the TFileMap constructor is saved inside the object and appears
- // in subsequent error messages.
- const char* const dbgName = "THIS_IS_A_TEST";
- FILE* f = fopen(FileName_, "w+");
- UNIT_ASSERT(f);
- {
- TFileMap mappedFile(f, TFileMap::oRdWr, dbgName);
- bool gotException = false;
- try {
- // trying to map an empty file to force an exception and check the message
- mappedFile.Map(0, 1000);
- } catch (const yexception& e) {
- gotException = true;
- UNIT_ASSERT_STRING_CONTAINS(e.what(), dbgName);
- }
- UNIT_ASSERT(gotException);
- }
- fclose(f);
- NFs::Remove(FileName_);
- }
-
+ // This test checks that dbgName passed to the TFileMap constructor is saved inside the object and appears
+ // in subsequent error messages.
+ const char* const dbgName = "THIS_IS_A_TEST";
+ FILE* f = fopen(FileName_, "w+");
+ UNIT_ASSERT(f);
+ {
+ TFileMap mappedFile(f, TFileMap::oRdWr, dbgName);
+ bool gotException = false;
+ try {
+ // trying to map an empty file to force an exception and check the message
+ mappedFile.Map(0, 1000);
+ } catch (const yexception& e) {
+ gotException = true;
+ UNIT_ASSERT_STRING_CONTAINS(e.what(), dbgName);
+ }
+ UNIT_ASSERT(gotException);
+ }
+ fclose(f);
+ NFs::Remove(FileName_);
+ }
+
#if defined(_asan_enabled_) || defined(_msan_enabled_)
//setrlimit incompatible with asan runtime
#elif defined(_cygwin_)
@@ -194,7 +194,7 @@ Y_UNIT_TEST_SUITE(TFileMapTest) {
}
#endif
maps.clear();
- NFs::Remove(FileName_);
+ NFs::Remove(FileName_);
} catch (...) {
// TODO: RAII'ize all this stuff
#if defined(_unix_)
@@ -204,7 +204,7 @@ Y_UNIT_TEST_SUITE(TFileMapTest) {
throw TSystemError() << "Cannot restore rlimit for virtual memory";
}
#endif
- NFs::Remove(FileName_);
+ NFs::Remove(FileName_);
throw;
}
@@ -265,7 +265,7 @@ Y_UNIT_TEST_SUITE(TFileMapTest) {
}
UNIT_ASSERT(caught);
}
- NFs::Remove(FileName_);
+ NFs::Remove(FileName_);
}
Y_UNIT_TEST(TestMappedArray) {
@@ -315,7 +315,7 @@ Y_UNIT_TEST_SUITE(TFileMapTest) {
TString text = exc.what(); // exception should contain failed file name
UNIT_ASSERT(text.find(FileName_) != TString::npos);
}
- NFs::Remove(FileName_);
+ NFs::Remove(FileName_);
}
Y_UNIT_TEST(TestMemoryMapIsWritable) {
@@ -330,7 +330,7 @@ Y_UNIT_TEST_SUITE(TFileMapTest) {
TMemoryMap mappedMem(FileName_, TMemoryMap::oRdWr);
UNIT_ASSERT(mappedMem.IsWritable());
}
- NFs::Remove(FileName_);
+ NFs::Remove(FileName_);
}
Y_UNIT_TEST(TestFileMapIsWritable) {
@@ -354,6 +354,6 @@ Y_UNIT_TEST_SUITE(TFileMapTest) {
TFileMap fileMap(FileName_, TFileMap::oRdWr);
UNIT_ASSERT(fileMap.IsWritable());
}
- NFs::Remove(FileName_);
+ NFs::Remove(FileName_);
}
};
diff --git a/util/system/mincore.cpp b/util/system/mincore.cpp
index 7dfb241c86..8cbae72586 100644
--- a/util/system/mincore.cpp
+++ b/util/system/mincore.cpp
@@ -1,35 +1,35 @@
-#include "align.h"
-#include "compiler.h"
-#include "info.h"
-#include "mincore.h"
-
-#include <util/generic/yexception.h>
-
-#include <cstring>
-
-#if defined(_unix_)
+#include "align.h"
+#include "compiler.h"
+#include "info.h"
+#include "mincore.h"
+
+#include <util/generic/yexception.h>
+
+#include <cstring>
+
+#if defined(_unix_)
#include <sys/unistd.h>
#include <sys/mman.h>
#if defined(_android_)
#include <sys/syscall.h>
#endif
-#endif
-
-void InCoreMemory(const void* addr, size_t len, unsigned char* vec, size_t vecLen) {
-#if defined(_linux_)
- const size_t pageSize = NSystemInfo::GetPageSize();
- void* maddr = const_cast<void*>(AlignDown(addr, pageSize));
- len = AlignUp(len, pageSize);
- if (vecLen * pageSize < len) {
- ythrow yexception() << "vector argument for mincore is too small: " << vecLen * pageSize << " < " << len;
- }
- if (::mincore(maddr, len, vec)) {
- ythrow yexception() << LastSystemErrorText();
- }
-#else
- // pessimistic assumption: nothing is in core
- Y_UNUSED(addr);
- Y_UNUSED(len);
- ::memset(vec, 0, vecLen);
-#endif
-}
+#endif
+
+void InCoreMemory(const void* addr, size_t len, unsigned char* vec, size_t vecLen) {
+#if defined(_linux_)
+ const size_t pageSize = NSystemInfo::GetPageSize();
+ void* maddr = const_cast<void*>(AlignDown(addr, pageSize));
+ len = AlignUp(len, pageSize);
+ if (vecLen * pageSize < len) {
+ ythrow yexception() << "vector argument for mincore is too small: " << vecLen * pageSize << " < " << len;
+ }
+ if (::mincore(maddr, len, vec)) {
+ ythrow yexception() << LastSystemErrorText();
+ }
+#else
+ // pessimistic assumption: nothing is in core
+ Y_UNUSED(addr);
+ Y_UNUSED(len);
+ ::memset(vec, 0, vecLen);
+#endif
+}
diff --git a/util/system/mincore.h b/util/system/mincore.h
index 1fc3f7d69c..0f5d8b78c7 100644
--- a/util/system/mincore.h
+++ b/util/system/mincore.h
@@ -1,38 +1,38 @@
-#pragma once
-
-#include "defaults.h"
-/**
- * Fills a vector that indicates whether pages of the calling process's virtual memory are resident in RAM. Each byte
- * in the vector contains the status of a single page. The page size can be obtained via the NSystemInfo::GetPageSize()
- * function. Use the IsPageInCore function to interpret the page status byte.
- *
- * Can be overly pessimistic:
- * - Assumes nothing is in RAM on platforms other than Linux
- * - Recent Linux kernels (4.21 and some backports) may return zeroes if the process doesn't have writing permissions
- * for the given file. See CVE-2019-5489.
- *
- * @param[in] addr starting address of the memory range to be examined
- * @param[in] len length (bytes) of the memory range to be examined
- * @param[out] vec vector of bytes to store statuses of memory pages
- * @param[in] vecLen length (bytes) of the vec, should be large enough to hold the requested pages count
- * @throws yexception if there was a system error or if the vecLen is too small
- *
- * @note this is only a snapshot, results may be stale by the time they're used
- * @see man 2 mincore
- */
-void InCoreMemory(const void* addr, size_t len, unsigned char* vec, size_t vecLen);
-
-/**
- * Takes as an argument an element of the vector previously filled by InCoreMemory.
- *
- * @param[in] byte corresponding to the status of a single page
- *
- * @returns true if this page was resident in memory at the time out the InCoreMemory execution
- */
-inline bool IsPageInCore(unsigned char s) {
- /* From mincore(2): On return, the least significant bit of each byte will be set if the corresponding page is
- * currently resident in memory, and be clear otherwise. (The settings of the other bits in each byte are
- * undefined; these bits are reserved for possible later use.)
- */
- return s & 1;
-}
+#pragma once
+
+#include "defaults.h"
+/**
+ * Fills a vector that indicates whether pages of the calling process's virtual memory are resident in RAM. Each byte
+ * in the vector contains the status of a single page. The page size can be obtained via the NSystemInfo::GetPageSize()
+ * function. Use the IsPageInCore function to interpret the page status byte.
+ *
+ * Can be overly pessimistic:
+ * - Assumes nothing is in RAM on platforms other than Linux
+ * - Recent Linux kernels (4.21 and some backports) may return zeroes if the process doesn't have writing permissions
+ * for the given file. See CVE-2019-5489.
+ *
+ * @param[in] addr starting address of the memory range to be examined
+ * @param[in] len length (bytes) of the memory range to be examined
+ * @param[out] vec vector of bytes to store statuses of memory pages
+ * @param[in] vecLen length (bytes) of the vec, should be large enough to hold the requested pages count
+ * @throws yexception if there was a system error or if the vecLen is too small
+ *
+ * @note this is only a snapshot, results may be stale by the time they're used
+ * @see man 2 mincore
+ */
+void InCoreMemory(const void* addr, size_t len, unsigned char* vec, size_t vecLen);
+
+/**
+ * Takes as an argument an element of the vector previously filled by InCoreMemory.
+ *
+ * @param[in] byte corresponding to the status of a single page
+ *
+ * @returns true if this page was resident in memory at the time out the InCoreMemory execution
+ */
+inline bool IsPageInCore(unsigned char s) {
+ /* From mincore(2): On return, the least significant bit of each byte will be set if the corresponding page is
+ * currently resident in memory, and be clear otherwise. (The settings of the other bits in each byte are
+ * undefined; these bits are reserved for possible later use.)
+ */
+ return s & 1;
+}
diff --git a/util/system/mincore_ut.cpp b/util/system/mincore_ut.cpp
index 1a7afcc6a5..fc46cb1632 100644
--- a/util/system/mincore_ut.cpp
+++ b/util/system/mincore_ut.cpp
@@ -1,47 +1,47 @@
#include <library/cpp/testing/unittest/registar.h>
-
-#ifdef _unix_
+
+#ifdef _unix_
#include <sys/resource.h>
-#endif
-
-#include "filemap.h"
-#include "info.h"
-#include "mincore.h"
-#include "mlock.h"
-#include "tempfile.h"
-
-#include <util/generic/size_literals.h>
-#include <util/system/fs.h>
-
-#include <cstring>
-#include <cstdio>
-
-Y_UNIT_TEST_SUITE(MincoreSuite) {
- static const char* FileName_("./mappped_file");
-
- Y_UNIT_TEST(TestLockAndInCore) {
- TVector<char> content(2_MB);
-
- TTempFile cleanup(FileName_);
- TFile file(FileName_, CreateAlways | WrOnly);
- file.Write(content.data(), content.size());
- file.Close();
-
- TFileMap mappedFile(FileName_, TMemoryMapCommon::oRdWr);
- mappedFile.Map(0, mappedFile.Length());
- UNIT_ASSERT_EQUAL(mappedFile.MappedSize(), content.size());
- UNIT_ASSERT_EQUAL(mappedFile.Length(), static_cast<i64>(content.size()));
-
- LockMemory(mappedFile.Ptr(), mappedFile.Length());
-
- TVector<unsigned char> incore(mappedFile.Length() / NSystemInfo::GetPageSize());
- InCoreMemory(mappedFile.Ptr(), mappedFile.Length(), incore.data(), incore.size());
-
- // compile and run on all platforms, but assume non-zero results only on Linux
-#if defined(_linux_)
- for (const auto& flag : incore) {
- UNIT_ASSERT(IsPageInCore(flag));
- }
-#endif
- }
-}
+#endif
+
+#include "filemap.h"
+#include "info.h"
+#include "mincore.h"
+#include "mlock.h"
+#include "tempfile.h"
+
+#include <util/generic/size_literals.h>
+#include <util/system/fs.h>
+
+#include <cstring>
+#include <cstdio>
+
+Y_UNIT_TEST_SUITE(MincoreSuite) {
+ static const char* FileName_("./mappped_file");
+
+ Y_UNIT_TEST(TestLockAndInCore) {
+ TVector<char> content(2_MB);
+
+ TTempFile cleanup(FileName_);
+ TFile file(FileName_, CreateAlways | WrOnly);
+ file.Write(content.data(), content.size());
+ file.Close();
+
+ TFileMap mappedFile(FileName_, TMemoryMapCommon::oRdWr);
+ mappedFile.Map(0, mappedFile.Length());
+ UNIT_ASSERT_EQUAL(mappedFile.MappedSize(), content.size());
+ UNIT_ASSERT_EQUAL(mappedFile.Length(), static_cast<i64>(content.size()));
+
+ LockMemory(mappedFile.Ptr(), mappedFile.Length());
+
+ TVector<unsigned char> incore(mappedFile.Length() / NSystemInfo::GetPageSize());
+ InCoreMemory(mappedFile.Ptr(), mappedFile.Length(), incore.data(), incore.size());
+
+ // compile and run on all platforms, but assume non-zero results only on Linux
+#if defined(_linux_)
+ for (const auto& flag : incore) {
+ UNIT_ASSERT(IsPageInCore(flag));
+ }
+#endif
+ }
+}
diff --git a/util/system/unaligned_mem.h b/util/system/unaligned_mem.h
index abcdde9fd6..4b84686f2f 100644
--- a/util/system/unaligned_mem.h
+++ b/util/system/unaligned_mem.h
@@ -6,11 +6,11 @@
#include <string.h>
#include <type_traits>
-// The following code used to have smart tricks assuming that unaligned reads and writes are OK on x86. This assumption
-// is wrong because compiler may emit alignment-sensitive x86 instructions e.g. movaps. See IGNIETFERRO-735.
-
+// The following code used to have smart tricks assuming that unaligned reads and writes are OK on x86. This assumption
+// is wrong because compiler may emit alignment-sensitive x86 instructions e.g. movaps. See IGNIETFERRO-735.
+
template <class T>
-inline T ReadUnaligned(const void* from) noexcept {
+inline T ReadUnaligned(const void* from) noexcept {
T ret;
memcpy(&ret, from, sizeof(T));
return ret;
diff --git a/util/system/unaligned_mem_ut.cpp b/util/system/unaligned_mem_ut.cpp
index 3c575d4f69..9de3f3e931 100644
--- a/util/system/unaligned_mem_ut.cpp
+++ b/util/system/unaligned_mem_ut.cpp
@@ -3,94 +3,94 @@
#include <library/cpp/testing/benchmark/bench.h>
#include <library/cpp/testing/unittest/registar.h>
-#include <util/system/compiler.h>
-
-#ifdef Y_HAVE_INT128
-namespace {
- struct TUInt128 {
- bool operator==(const TUInt128& other) const {
- return x == other.x;
- }
-
- ui64 Low() const {
- return (ui64)x;
- }
-
- ui64 High() const {
- return (ui64)(x >> 64);
- }
-
- static TUInt128 Max() {
+#include <util/system/compiler.h>
+
+#ifdef Y_HAVE_INT128
+namespace {
+ struct TUInt128 {
+ bool operator==(const TUInt128& other) const {
+ return x == other.x;
+ }
+
+ ui64 Low() const {
+ return (ui64)x;
+ }
+
+ ui64 High() const {
+ return (ui64)(x >> 64);
+ }
+
+ static TUInt128 Max() {
return {~(__uint128_t)0};
- }
-
- __uint128_t x;
- };
-}
-#endif
-
+ }
+
+ __uint128_t x;
+ };
+}
+#endif
+
Y_UNIT_TEST_SUITE(UnalignedMem) {
Y_UNIT_TEST(TestReadWrite) {
- alignas(ui64) char buf[100];
+ alignas(ui64) char buf[100];
WriteUnaligned<ui16>(buf + 1, (ui16)1);
WriteUnaligned<ui32>(buf + 1 + 2, (ui32)2);
WriteUnaligned<ui64>(buf + 1 + 2 + 4, (ui64)3);
- UNIT_ASSERT_VALUES_EQUAL(ReadUnaligned<ui16>(buf + 1), 1);
- UNIT_ASSERT_VALUES_EQUAL(ReadUnaligned<ui32>(buf + 1 + 2), 2);
- UNIT_ASSERT_VALUES_EQUAL(ReadUnaligned<ui64>(buf + 1 + 2 + 4), 3);
+ UNIT_ASSERT_VALUES_EQUAL(ReadUnaligned<ui16>(buf + 1), 1);
+ UNIT_ASSERT_VALUES_EQUAL(ReadUnaligned<ui32>(buf + 1 + 2), 2);
+ UNIT_ASSERT_VALUES_EQUAL(ReadUnaligned<ui64>(buf + 1 + 2 + 4), 3);
}
-
+
Y_UNIT_TEST(TestReadWriteRuntime) {
- // Unlike the test above, this test avoids compile-time execution by a smart compiler.
- // It is required to catch the SIGSEGV in case compiler emits an alignment-sensitive instruction.
-
- alignas(ui64) static char buf[100] = {0}; // static is required for Clobber to work
-
+ // Unlike the test above, this test avoids compile-time execution by a smart compiler.
+ // It is required to catch the SIGSEGV in case compiler emits an alignment-sensitive instruction.
+
+ alignas(ui64) static char buf[100] = {0}; // static is required for Clobber to work
+
WriteUnaligned<ui16>(buf + 1, (ui16)1);
WriteUnaligned<ui32>(buf + 1 + 2, (ui32)2);
WriteUnaligned<ui64>(buf + 1 + 2 + 4, (ui64)3);
- NBench::Clobber();
-
- auto val1 = ReadUnaligned<ui16>(buf + 1);
- auto val2 = ReadUnaligned<ui32>(buf + 1 + 2);
- auto val3 = ReadUnaligned<ui64>(buf + 1 + 2 + 4);
-
- Y_DO_NOT_OPTIMIZE_AWAY(&val1);
- Y_DO_NOT_OPTIMIZE_AWAY(&val2);
- Y_DO_NOT_OPTIMIZE_AWAY(&val3);
- Y_DO_NOT_OPTIMIZE_AWAY(val1);
- Y_DO_NOT_OPTIMIZE_AWAY(val2);
- Y_DO_NOT_OPTIMIZE_AWAY(val3);
-
- UNIT_ASSERT_VALUES_EQUAL(val1, 1);
- UNIT_ASSERT_VALUES_EQUAL(val2, 2);
- UNIT_ASSERT_VALUES_EQUAL(val3, 3);
- }
-#ifdef Y_HAVE_INT128
+ NBench::Clobber();
+
+ auto val1 = ReadUnaligned<ui16>(buf + 1);
+ auto val2 = ReadUnaligned<ui32>(buf + 1 + 2);
+ auto val3 = ReadUnaligned<ui64>(buf + 1 + 2 + 4);
+
+ Y_DO_NOT_OPTIMIZE_AWAY(&val1);
+ Y_DO_NOT_OPTIMIZE_AWAY(&val2);
+ Y_DO_NOT_OPTIMIZE_AWAY(&val3);
+ Y_DO_NOT_OPTIMIZE_AWAY(val1);
+ Y_DO_NOT_OPTIMIZE_AWAY(val2);
+ Y_DO_NOT_OPTIMIZE_AWAY(val3);
+
+ UNIT_ASSERT_VALUES_EQUAL(val1, 1);
+ UNIT_ASSERT_VALUES_EQUAL(val2, 2);
+ UNIT_ASSERT_VALUES_EQUAL(val3, 3);
+ }
+#ifdef Y_HAVE_INT128
Y_UNIT_TEST(TestReadWrite128) {
- alignas(TUInt128) char buf[100] = {0};
-
+ alignas(TUInt128) char buf[100] = {0};
+
WriteUnaligned<TUInt128>(buf + 1, TUInt128::Max());
- auto val = ReadUnaligned<TUInt128>(buf + 1);
- UNIT_ASSERT(val == TUInt128::Max());
- }
+ auto val = ReadUnaligned<TUInt128>(buf + 1);
+ UNIT_ASSERT(val == TUInt128::Max());
+ }
Y_UNIT_TEST(TestReadWriteRuntime128) {
- // Unlike the test above, this test avoids compile-time execution by a smart compiler.
- // It is required to catch the SIGSEGV in case compiler emits an alignment-sensitive instruction.
-
- alignas(TUInt128) static char buf[100] = {0}; // static is required for Clobber to work
-
+ // Unlike the test above, this test avoids compile-time execution by a smart compiler.
+ // It is required to catch the SIGSEGV in case compiler emits an alignment-sensitive instruction.
+
+ alignas(TUInt128) static char buf[100] = {0}; // static is required for Clobber to work
+
WriteUnaligned<TUInt128>(buf + 1, TUInt128::Max());
- NBench::Clobber();
-
- auto val = ReadUnaligned<TUInt128>(buf + 1);
- Y_DO_NOT_OPTIMIZE_AWAY(&val);
- Y_DO_NOT_OPTIMIZE_AWAY(val.Low());
- Y_DO_NOT_OPTIMIZE_AWAY(val.High());
-
- UNIT_ASSERT(val == TUInt128::Max());
- }
-#endif
+ NBench::Clobber();
+
+ auto val = ReadUnaligned<TUInt128>(buf + 1);
+ Y_DO_NOT_OPTIMIZE_AWAY(&val);
+ Y_DO_NOT_OPTIMIZE_AWAY(val.Low());
+ Y_DO_NOT_OPTIMIZE_AWAY(val.High());
+
+ UNIT_ASSERT(val == TUInt128::Max());
+ }
+#endif
}
diff --git a/util/system/ut/ya.make b/util/system/ut/ya.make
index 8187e2110b..127e7c261e 100644
--- a/util/system/ut/ya.make
+++ b/util/system/ut/ya.make
@@ -19,10 +19,10 @@ IF (OS_DARWIN)
TIMEOUT(3600)
ENDIF()
-PEERDIR(
+PEERDIR(
library/cpp/testing/benchmark
-)
-
+)
+
SRCS(
system/align_ut.cpp
system/atexit_ut.cpp
@@ -53,7 +53,7 @@ SRCS(
system/info_ut.cpp
system/interrupt_signals_ut.cpp
system/mem_info_ut.cpp
- system/mincore_ut.cpp
+ system/mincore_ut.cpp
system/mutex_ut.cpp
system/nice_ut.cpp
system/pipe_ut.cpp
diff --git a/util/ya.make b/util/ya.make
index f602a9f343..6ebe7e40cf 100644
--- a/util/ya.make
+++ b/util/ya.make
@@ -292,7 +292,7 @@ JOIN_SRCS(
system/madvise.cpp
system/maxlen.cpp
system/mem_info.cpp
- system/mincore.cpp
+ system/mincore.cpp
system/mktemp.cpp
system/mlock.cpp
system/mutex.cpp