Skip to content

Commit

Permalink
Add move constructor to Status.
Browse files Browse the repository at this point in the history
This will result in smaller code generation when Status instances are
passed around.

Benchmarks don't indicate a significant change either way.
CPU:        48 * Intel(R) Xeon(R) CPU E5-2690 v3 @ 2.60GHz
CPUCache:   30720 KB
Keys:       16 bytes each
Values:     100 bytes each (50 bytes after compression)
Entries:    1000000
RawSize:    110.6 MB (estimated)
FileSize:   62.9 MB (estimated)

Baseline:
fillseq      :       3.589 micros/op;   30.8 MB/s
fillsync     :    4165.299 micros/op;    0.0 MB/s (1000 ops)
fillrandom   :       5.864 micros/op;   18.9 MB/s
overwrite    :       7.830 micros/op;   14.1 MB/s
readrandom   :       5.534 micros/op; (1000000 of 1000000 found)
readrandom   :       4.292 micros/op; (1000000 of 1000000 found)
readseq      :       0.312 micros/op;  354.1 MB/s
readreverse  :       0.501 micros/op;  220.8 MB/s
compact      :  886211.000 micros/op;
readrandom   :       3.518 micros/op; (1000000 of 1000000 found)
readseq      :       0.251 micros/op;  441.2 MB/s
readreverse  :       0.456 micros/op;  242.4 MB/s
fill100K     :    1329.723 micros/op;   71.7 MB/s (1000 ops)
crc32c       :       1.976 micros/op; 1976.7 MB/s (4K per op)
snappycomp   :       4.705 micros/op;  830.2 MB/s (output: 55.1%)
snappyuncomp :       0.958 micros/op; 4079.1 MB/s
acquireload  :       0.727 micros/op; (each op is 1000 loads)

New:
fillseq      :       3.129 micros/op;   35.4 MB/s
fillsync     :    2748.099 micros/op;    0.0 MB/s (1000 ops)
fillrandom   :       5.394 micros/op;   20.5 MB/s
overwrite    :       7.253 micros/op;   15.3 MB/s
readrandom   :       5.655 micros/op; (1000000 of 1000000 found)
readrandom   :       4.425 micros/op; (1000000 of 1000000 found)
readseq      :       0.298 micros/op;  371.3 MB/s
readreverse  :       0.508 micros/op;  217.9 MB/s
compact      :  885842.000 micros/op;
readrandom   :       3.545 micros/op; (1000000 of 1000000 found)
readseq      :       0.252 micros/op;  438.2 MB/s
readreverse  :       0.425 micros/op;  260.2 MB/s
fill100K     :    1418.347 micros/op;   67.2 MB/s (1000 ops)
crc32c       :       1.987 micros/op; 1966.0 MB/s (4K per op)
snappycomp   :       4.767 micros/op;  819.4 MB/s (output: 55.1%)
snappyuncomp :       0.916 micros/op; 4264.9 MB/s
acquireload  :       0.665 micros/op; (each op is 1000 loads)

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=194002392
  • Loading branch information
pwnall committed Apr 23, 2018
1 parent d177a02 commit 4de9594
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 11 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ if(LEVELDB_BUILD_TESTS)
leveldb_test("${PROJECT_SOURCE_DIR}/issues/issue200_test.cc")

leveldb_test("${PROJECT_SOURCE_DIR}/util/env_test.cc")
leveldb_test("${PROJECT_SOURCE_DIR}/util/status_test.cc")

if(NOT BUILD_SHARED_LIBS)
leveldb_test("${PROJECT_SOURCE_DIR}/db/autocompact_test.cc")
Expand Down
30 changes: 19 additions & 11 deletions include/leveldb/status.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#ifndef STORAGE_LEVELDB_INCLUDE_STATUS_H_
#define STORAGE_LEVELDB_INCLUDE_STATUS_H_

#include <algorithm>
#include <string>
#include "leveldb/export.h"
#include "leveldb/slice.h"
Expand All @@ -22,12 +23,14 @@ namespace leveldb {
class LEVELDB_EXPORT Status {
public:
// Create a success status.
Status() : state_(nullptr) { }
Status() noexcept : state_(nullptr) { }
~Status() { delete[] state_; }

// Copy the specified status.
Status(const Status& s);
void operator=(const Status& s);
Status(const Status& rhs);
Status& operator=(const Status& rhs);

Status(Status&& rhs) noexcept : state_(rhs.state_) { rhs.state_ = nullptr; }
Status& operator=(Status&& rhs) noexcept;

// Return a success status.
static Status OK() { return Status(); }
Expand Down Expand Up @@ -96,16 +99,21 @@ class LEVELDB_EXPORT Status {
static const char* CopyState(const char* s);
};

inline Status::Status(const Status& s) {
state_ = (s.state_ == nullptr) ? nullptr : CopyState(s.state_);
inline Status::Status(const Status& rhs) {
state_ = (rhs.state_ == nullptr) ? nullptr : CopyState(rhs.state_);
}
inline void Status::operator=(const Status& s) {
// The following condition catches both aliasing (when this == &s),
// and the common case where both s and *this are ok.
if (state_ != s.state_) {
inline Status& Status::operator=(const Status& rhs) {
// The following condition catches both aliasing (when this == &rhs),
// and the common case where both rhs and *this are ok.
if (state_ != rhs.state_) {
delete[] state_;
state_ = (s.state_ == nullptr) ? nullptr : CopyState(s.state_);
state_ = (rhs.state_ == nullptr) ? nullptr : CopyState(rhs.state_);
}
return *this;
}
inline Status& Status::operator=(Status&& rhs) noexcept {
std::swap(state_, rhs.state_);
return *this;
}

} // namespace leveldb
Expand Down
42 changes: 42 additions & 0 deletions util/status_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) 2018 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#include <utility>

#include "leveldb/slice.h"
#include "leveldb/status.h"
#include "util/testharness.h"

namespace leveldb {

TEST(Status, MoveConstructor) {
{
Status ok = Status::OK();
Status ok2 = std::move(ok);

ASSERT_TRUE(ok2.ok());
}

{
Status status = Status::NotFound("custom NotFound status message");
Status status2 = std::move(status);

ASSERT_TRUE(status2.IsNotFound());
ASSERT_EQ("NotFound: custom NotFound status message", status2.ToString());
}

{
Status self_moved = Status::IOError("custom IOError status message");

// Needed to bypass compiler warning about explicit move-assignment.
Status& self_moved_reference = self_moved;
self_moved_reference = std::move(self_moved);
}
}

} // namespace leveldb

int main(int argc, char** argv) {
return leveldb::test::RunAllTests();
}

0 comments on commit 4de9594

Please sign in to comment.