| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 | //  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.//  This source code is licensed under both the GPLv2 (found in the//  COPYING file in the root directory) and Apache 2.0 License//  (found in the LICENSE.Apache file in the root directory).#include "port/port.h"#include "port/stack_trace.h"#include "rocksdb/slice.h"#include "test_util/testharness.h"#include "test_util/testutil.h"namespace ROCKSDB_NAMESPACE {// Use this to keep track of the cleanups that were actually performedvoid Multiplier(void* arg1, void* arg2) {  int* res = reinterpret_cast<int*>(arg1);  int* num = reinterpret_cast<int*>(arg2);  *res *= *num;}class PinnableSliceTest : public testing::Test { public:  void AssertSameData(const std::string& expected,                      const PinnableSlice& slice) {    std::string got;    got.assign(slice.data(), slice.size());    ASSERT_EQ(expected, got);  }};// Test that the external buffer is moved instead of being copied.TEST_F(PinnableSliceTest, MoveExternalBuffer) {  Slice s("123");  std::string buf;  PinnableSlice v1(&buf);  v1.PinSelf(s);  PinnableSlice v2(std::move(v1));  ASSERT_EQ(buf.data(), v2.data());  ASSERT_EQ(&buf, v2.GetSelf());  PinnableSlice v3;  v3 = std::move(v2);  ASSERT_EQ(buf.data(), v3.data());  ASSERT_EQ(&buf, v3.GetSelf());}TEST_F(PinnableSliceTest, Move) {  int n2 = 2;  int res = 1;  const std::string const_str1 = "123";  const std::string const_str2 = "ABC";  Slice slice1(const_str1);  Slice slice2(const_str2);  {    // Test move constructor on a pinned slice.    res = 1;    PinnableSlice v1;    v1.PinSlice(slice1, Multiplier, &res, &n2);    PinnableSlice v2(std::move(v1));    // Since v1's Cleanable has been moved to v2,    // no cleanup should happen in Reset.    v1.Reset();    ASSERT_EQ(1, res);    AssertSameData(const_str1, v2);  }  // v2 is cleaned up.  ASSERT_EQ(2, res);  {    // Test move constructor on an unpinned slice.    PinnableSlice v1;    v1.PinSelf(slice1);    PinnableSlice v2(std::move(v1));    AssertSameData(const_str1, v2);  }  {    // Test move assignment from a pinned slice to    // another pinned slice.    res = 1;    PinnableSlice v1;    v1.PinSlice(slice1, Multiplier, &res, &n2);    PinnableSlice v2;    v2.PinSlice(slice2, Multiplier, &res, &n2);    v2 = std::move(v1);    // v2's Cleanable will be Reset before moving    // anything from v1.    ASSERT_EQ(2, res);    // Since v1's Cleanable has been moved to v2,    // no cleanup should happen in Reset.    v1.Reset();    ASSERT_EQ(2, res);    AssertSameData(const_str1, v2);  }  // The Cleanable moved from v1 to v2 will be Reset.  ASSERT_EQ(4, res);  {    // Test move assignment from a pinned slice to    // an unpinned slice.    res = 1;    PinnableSlice v1;    v1.PinSlice(slice1, Multiplier, &res, &n2);    PinnableSlice v2;    v2.PinSelf(slice2);    v2 = std::move(v1);    // Since v1's Cleanable has been moved to v2,    // no cleanup should happen in Reset.    v1.Reset();    ASSERT_EQ(1, res);    AssertSameData(const_str1, v2);  }  // The Cleanable moved from v1 to v2 will be Reset.  ASSERT_EQ(2, res);  {    // Test move assignment from an upinned slice to    // another unpinned slice.    PinnableSlice v1;    v1.PinSelf(slice1);    PinnableSlice v2;    v2.PinSelf(slice2);    v2 = std::move(v1);    AssertSameData(const_str1, v2);  }  {    // Test move assignment from an upinned slice to    // a pinned slice.    res = 1;    PinnableSlice v1;    v1.PinSelf(slice1);    PinnableSlice v2;    v2.PinSlice(slice2, Multiplier, &res, &n2);    v2 = std::move(v1);    // v2's Cleanable will be Reset before moving    // anything from v1.    ASSERT_EQ(2, res);    AssertSameData(const_str1, v2);  }  // No Cleanable is moved from v1 to v2, so no more cleanup.  ASSERT_EQ(2, res);}}  // namespace ROCKSDB_NAMESPACEint main(int argc, char** argv) {  ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();  ::testing::InitGoogleTest(&argc, argv);  return RUN_ALL_TESTS();}
 |