mirror of
https://github.com/MariaDB/server.git
synced 2025-01-22 23:04:20 +01:00
7ea6dd4171
git-svn-id: file:///svn/toku/tokudb@46797 c7de825b-a66e-492c-adef-691d508d4ae1
228 lines
7.2 KiB
C++
228 lines
7.2 KiB
C++
/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
|
|
#ident "$Id: cachetable-simple-verify.cc 45903 2012-07-19 13:06:39Z leifwalsh $"
|
|
#ident "Copyright (c) 2007-2012 Tokutek Inc. All rights reserved."
|
|
#include "includes.h"
|
|
#include "test.h"
|
|
#include "cachetable-internal.h"
|
|
|
|
class evictor_unit_test {
|
|
public:
|
|
evictor m_ev;
|
|
pair_list m_pl;
|
|
KIBBUTZ m_kb;
|
|
void init();
|
|
void destroy();
|
|
void run_test();
|
|
void verify_ev_init(long limit);
|
|
void verify_ev_destroy();
|
|
void verify_ev_counts();
|
|
void verify_ev_m_size_reserved();
|
|
void verify_ev_handling_cache_pressure();
|
|
|
|
// function to disable the eviction thread from waking up every second
|
|
void disable_ev_thread();
|
|
};
|
|
|
|
// initialize this class to run tests
|
|
void evictor_unit_test::init() {
|
|
m_pl.init();
|
|
m_kb = toku_kibbutz_create(1);
|
|
}
|
|
|
|
// destroy class after tests have run
|
|
void evictor_unit_test::destroy() {
|
|
m_pl.destroy();
|
|
toku_kibbutz_destroy(m_kb);
|
|
}
|
|
|
|
// test that verifies evictor.init properly worked
|
|
void evictor_unit_test::verify_ev_init(long limit) {
|
|
assert(m_ev.m_kibbutz == m_kb);
|
|
assert(m_ev.m_pl == &m_pl);
|
|
assert(m_ev.m_low_size_watermark == limit);
|
|
assert(m_ev.m_num_sleepers == 0);
|
|
assert(m_ev.m_run_thread == true);
|
|
assert(m_ev.m_size_current == 0);
|
|
assert(m_ev.m_size_leaf== 0);
|
|
assert(m_ev.m_size_nonleaf== 0);
|
|
assert(m_ev.m_size_rollback== 0);
|
|
assert(m_ev.m_size_cachepressure == 0);
|
|
assert(m_ev.m_size_evicting == 0);
|
|
// this comes from definition of unreservable_memory in cachetable.cc
|
|
assert(m_ev.m_size_reserved == (limit/4));
|
|
}
|
|
|
|
// test that verifies evictor.destroy properly worked
|
|
void evictor_unit_test::verify_ev_destroy() {
|
|
assert(m_ev.m_num_sleepers == 0);
|
|
assert(m_ev.m_run_thread == false);
|
|
}
|
|
|
|
void evictor_unit_test::disable_ev_thread() {
|
|
toku_mutex_lock(&m_ev.m_ev_thread_lock);
|
|
m_ev.m_period_in_seconds = 0;
|
|
// signal eviction thread so that it wakes up
|
|
// and then sleeps indefinitely
|
|
m_ev.signal_eviction_thread();
|
|
toku_mutex_unlock(&m_ev.m_ev_thread_lock);
|
|
// sleep for one second to ensure eviction thread picks up new period
|
|
usleep(1*1024*1024);
|
|
}
|
|
|
|
// test that verifies that counts, such as m_size_current
|
|
// are accurately maintained
|
|
void evictor_unit_test::verify_ev_counts() {
|
|
long limit = 10;
|
|
long expected_m_size_reserved = limit/4;
|
|
m_ev.init(limit, &m_pl, m_kb, 0);
|
|
this->verify_ev_init(limit);
|
|
|
|
m_ev.add_to_size_current(1);
|
|
assert(m_ev.m_size_current == 1);
|
|
assert(m_ev.m_size_reserved == expected_m_size_reserved);
|
|
assert(m_ev.m_size_leaf == 0);
|
|
assert(m_ev.m_size_nonleaf == 0);
|
|
assert(m_ev.m_size_rollback == 0);
|
|
assert(m_ev.m_size_cachepressure == 0);
|
|
assert(m_ev.m_size_evicting == 0);
|
|
|
|
m_ev.add_to_size_current(3);
|
|
assert(m_ev.m_size_current == 4);
|
|
|
|
m_ev.remove_from_size_current(4);
|
|
assert(m_ev.m_size_current == 0);
|
|
assert(m_ev.m_size_reserved == expected_m_size_reserved);
|
|
|
|
PAIR_ATTR attr = {
|
|
.size = 1,
|
|
.nonleaf_size = 2,
|
|
.leaf_size = 3,
|
|
.rollback_size = 4,
|
|
.cache_pressure_size = 5,
|
|
.is_valid = true
|
|
};
|
|
|
|
m_ev.add_pair_attr(attr);
|
|
assert(m_ev.m_size_current == 1);
|
|
assert(m_ev.m_size_nonleaf == 2);
|
|
assert(m_ev.m_size_leaf == 3);
|
|
assert(m_ev.m_size_rollback == 4);
|
|
assert(m_ev.m_size_cachepressure == 5);
|
|
m_ev.remove_pair_attr(attr);
|
|
assert(m_ev.m_size_current == 0);
|
|
assert(m_ev.m_size_leaf == 0);
|
|
assert(m_ev.m_size_nonleaf == 0);
|
|
assert(m_ev.m_size_rollback == 0);
|
|
assert(m_ev.m_size_cachepressure == 0);
|
|
|
|
PAIR_ATTR other_attr = {
|
|
.size = 2,
|
|
.nonleaf_size = 3,
|
|
.leaf_size = 4,
|
|
.rollback_size = 5,
|
|
.cache_pressure_size = 6,
|
|
.is_valid = true
|
|
};
|
|
m_ev.change_pair_attr(attr, other_attr);
|
|
assert(m_ev.m_size_current == 1);
|
|
assert(m_ev.m_size_leaf == 1);
|
|
assert(m_ev.m_size_nonleaf == 1);
|
|
assert(m_ev.m_size_rollback == 1);
|
|
assert(m_ev.m_size_cachepressure == 1);
|
|
|
|
m_ev.destroy();
|
|
this->verify_ev_destroy();
|
|
}
|
|
|
|
// test to verify the functionality surrounding m_size_reserved
|
|
void evictor_unit_test::verify_ev_m_size_reserved() {
|
|
long limit = 400;
|
|
long expected_m_size_reserved = 100; //limit/4
|
|
m_ev.init(limit, &m_pl, m_kb, 0);
|
|
this->verify_ev_init(limit);
|
|
assert(m_ev.m_size_reserved == expected_m_size_reserved);
|
|
m_ev.m_num_eviction_thread_runs = 0;
|
|
m_ev.reserve_memory(0.5);
|
|
assert(m_ev.m_size_reserved == 100+150); //100 original, 150 from last call
|
|
assert(m_ev.m_size_current == 150);
|
|
assert(m_ev.m_size_evicting == 0);
|
|
usleep(1*1024*1024); // sleep to give eviction thread a chance to wake up
|
|
assert(m_ev.m_num_eviction_thread_runs == 1);
|
|
|
|
m_ev.destroy();
|
|
this->verify_ev_destroy();
|
|
}
|
|
|
|
// test to verify functionality of handling cache pressure,
|
|
// ensures that wait_for_cache_pressure_to_subside works correctly,
|
|
// that decrease_m_size_evicting works correctly, and the logic for when to wake
|
|
// threads up works correctly
|
|
void evictor_unit_test::verify_ev_handling_cache_pressure() {
|
|
long limit = 400;
|
|
m_ev.init(limit, &m_pl, m_kb, 0);
|
|
this->verify_ev_init(limit);
|
|
m_ev.m_low_size_watermark = 400;
|
|
m_ev.m_low_size_hysteresis = 400;
|
|
m_ev.m_high_size_hysteresis = 500;
|
|
m_ev.m_high_size_watermark = 500;
|
|
m_ev.m_size_current = 500;
|
|
|
|
m_ev.m_num_eviction_thread_runs = 0;
|
|
|
|
// test that waiting for cache pressure wakes eviction thread
|
|
assert(m_ev.m_num_sleepers == 0);
|
|
m_ev.wait_for_cache_pressure_to_subside();
|
|
assert(m_ev.m_num_eviction_thread_runs == 1);
|
|
assert(m_ev.m_num_sleepers == 0);
|
|
|
|
m_ev.m_num_eviction_thread_runs = 0;
|
|
m_ev.m_size_evicting = 101;
|
|
m_ev.decrease_size_evicting(101);
|
|
usleep(1*1024*1024);
|
|
// should not have been signaled because we have no sleepers
|
|
assert(m_ev.m_num_eviction_thread_runs == 0);
|
|
|
|
m_ev.m_num_eviction_thread_runs = 0;
|
|
m_ev.m_size_evicting = 101;
|
|
m_ev.m_num_sleepers = 1;
|
|
m_ev.decrease_size_evicting(2);
|
|
usleep(1*1024*1024);
|
|
// should have been signaled because we have sleepers
|
|
assert(m_ev.m_num_eviction_thread_runs == 1);
|
|
assert(m_ev.m_num_sleepers == 1); // make sure fake sleeper did not go away
|
|
|
|
m_ev.m_num_eviction_thread_runs = 0;
|
|
m_ev.m_size_evicting = 102;
|
|
m_ev.m_num_sleepers = 1;
|
|
m_ev.decrease_size_evicting(1);
|
|
usleep(1*1024*1024);
|
|
// should not have been signaled because we did not go to less than 100
|
|
assert(m_ev.m_num_eviction_thread_runs == 0);
|
|
assert(m_ev.m_num_sleepers == 1); // make sure fake sleeper did not go away
|
|
|
|
m_ev.m_size_evicting = 0;
|
|
m_ev.m_num_sleepers = 0;
|
|
m_ev.destroy();
|
|
this->verify_ev_destroy();
|
|
}
|
|
|
|
void evictor_unit_test::run_test() {
|
|
this->verify_ev_counts();
|
|
this->verify_ev_m_size_reserved();
|
|
this->verify_ev_handling_cache_pressure();
|
|
return;
|
|
//this->disable_ev_thread();
|
|
//usleep(9*1024*1024);
|
|
|
|
}
|
|
|
|
int
|
|
test_main(int argc, const char *argv[]) {
|
|
default_parse_args(argc, argv);
|
|
evictor_unit_test ev_test;
|
|
ev_test.init();
|
|
ev_test.run_test();
|
|
ev_test.destroy();
|
|
return 0;
|
|
}
|