arena_test.cc 4.1 KB
Newer Older
1 2 3 4 5
//  Copyright (c) 2013, Facebook, Inc.  All rights reserved.
//  This source code is licensed under the BSD-style license found in the
//  LICENSE file in the root directory of this source tree. An additional grant
//  of patent rights can be found in the PATENTS file in the same directory.
//
J
jorlow@chromium.org 已提交
6 7 8 9
// Copyright (c) 2011 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.

X
Xing Jin 已提交
10
#include "util/arena_impl.h"
J
jorlow@chromium.org 已提交
11 12 13
#include "util/random.h"
#include "util/testharness.h"

14
namespace rocksdb {
J
jorlow@chromium.org 已提交
15

X
Xing Jin 已提交
16 17 18 19 20 21 22 23 24 25 26
class ArenaImplTest { };

TEST(ArenaImplTest, Empty) {
  ArenaImpl arena0;
}

TEST(ArenaImplTest, MemoryAllocatedBytes) {
  const int N = 17;
  size_t req_sz;  //requested size
  size_t bsz = 8192;  // block size
  size_t expected_memory_allocated;
J
jorlow@chromium.org 已提交
27

X
Xing Jin 已提交
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
  ArenaImpl arena_impl(bsz);

  // requested size > quarter of a block:
  //   allocate requested size separately
  req_sz = 3001;
  for (int i = 0; i < N; i++) {
    arena_impl.Allocate(req_sz);
  }
  expected_memory_allocated = req_sz * N;
  ASSERT_EQ(arena_impl.MemoryAllocatedBytes(), expected_memory_allocated);

  // requested size < quarter of a block:
  //   allocate a block with the default size, then try to use unused part
  //   of the block. So one new block will be allocated for the first
  //   Allocate(99) call. All the remaining calls won't lead to new allocation.
  req_sz = 99;
  for (int i = 0; i < N; i++) {
    arena_impl.Allocate(req_sz);
  }
  expected_memory_allocated += bsz;
  ASSERT_EQ(arena_impl.MemoryAllocatedBytes(), expected_memory_allocated);

  // requested size > quarter of a block:
  //   allocate requested size separately
  req_sz = 99999999;
  for (int i = 0; i < N; i++) {
    arena_impl.Allocate(req_sz);
  }
  expected_memory_allocated += req_sz * N;
  ASSERT_EQ(arena_impl.MemoryAllocatedBytes(), expected_memory_allocated);
J
jorlow@chromium.org 已提交
58 59
}

60 61 62 63 64
// Make sure we didn't count the allocate but not used memory space in
// Arena::ApproximateMemoryUsage()
TEST(ArenaImplTest, ApproximateMemoryUsageTest) {
  const size_t kBlockSize = 4096;
  const size_t kEntrySize = kBlockSize / 8;
Y
Yancey 已提交
65
	const size_t kZero = 0;
66
  ArenaImpl arena(kBlockSize);
Y
Yancey 已提交
67
  ASSERT_EQ(kZero, arena.ApproximateMemoryUsage());
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85

  auto num_blocks = kBlockSize / kEntrySize;

  // first allocation
  arena.AllocateAligned(kEntrySize);
  auto mem_usage = arena.MemoryAllocatedBytes();
  ASSERT_EQ(mem_usage, kBlockSize);
  auto usage = arena.ApproximateMemoryUsage();
  ASSERT_LT(usage, mem_usage);
  for (size_t i = 1; i < num_blocks; ++i) {
    arena.AllocateAligned(kEntrySize);
    ASSERT_EQ(mem_usage, arena.MemoryAllocatedBytes());
    ASSERT_EQ(arena.ApproximateMemoryUsage(), usage + kEntrySize);
    usage = arena.ApproximateMemoryUsage();
  }
  ASSERT_GT(usage, mem_usage);
}

X
Xing Jin 已提交
86
TEST(ArenaImplTest, Simple) {
87
  std::vector<std::pair<size_t, char*>> allocated;
X
Xing Jin 已提交
88
  ArenaImpl arena_impl;
J
jorlow@chromium.org 已提交
89 90 91 92 93 94 95 96
  const int N = 100000;
  size_t bytes = 0;
  Random rnd(301);
  for (int i = 0; i < N; i++) {
    size_t s;
    if (i % (N / 10) == 0) {
      s = i;
    } else {
97 98 99
      s = rnd.OneIn(4000)
              ? rnd.Uniform(6000)
              : (rnd.OneIn(10) ? rnd.Uniform(100) : rnd.Uniform(20));
J
jorlow@chromium.org 已提交
100 101 102 103 104 105 106
    }
    if (s == 0) {
      // Our arena disallows size 0 allocations.
      s = 1;
    }
    char* r;
    if (rnd.OneIn(10)) {
X
Xing Jin 已提交
107
      r = arena_impl.AllocateAligned(s);
J
jorlow@chromium.org 已提交
108
    } else {
X
Xing Jin 已提交
109
      r = arena_impl.Allocate(s);
J
jorlow@chromium.org 已提交
110 111
    }

112
    for (unsigned int b = 0; b < s; b++) {
J
jorlow@chromium.org 已提交
113 114 115 116 117
      // Fill the "i"th allocation with a known bit pattern
      r[b] = i % 256;
    }
    bytes += s;
    allocated.push_back(std::make_pair(s, r));
X
Xing Jin 已提交
118
    ASSERT_GE(arena_impl.ApproximateMemoryUsage(), bytes);
119
    if (i > N / 10) {
X
Xing Jin 已提交
120
      ASSERT_LE(arena_impl.ApproximateMemoryUsage(), bytes * 1.10);
J
jorlow@chromium.org 已提交
121 122
    }
  }
123
  for (unsigned int i = 0; i < allocated.size(); i++) {
J
jorlow@chromium.org 已提交
124 125
    size_t num_bytes = allocated[i].first;
    const char* p = allocated[i].second;
126
    for (unsigned int b = 0; b < num_bytes; b++) {
J
jorlow@chromium.org 已提交
127
      // Check the "i"th allocation for the known bit pattern
128
      ASSERT_EQ(int(p[b]) & 0xff, (int)(i % 256));
J
jorlow@chromium.org 已提交
129 130 131 132
    }
  }
}

133
}  // namespace rocksdb
J
jorlow@chromium.org 已提交
134 135

int main(int argc, char** argv) {
136
  return rocksdb::test::RunAllTests();
J
jorlow@chromium.org 已提交
137
}