216 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			216 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/**
 | 
						|
 * Copyright (c) 2021 OceanBase
 | 
						|
 * OceanBase CE is licensed under Mulan PubL v2.
 | 
						|
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 | 
						|
 * You may obtain a copy of Mulan PubL v2 at:
 | 
						|
 *          http://license.coscl.org.cn/MulanPubL-2.0
 | 
						|
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | 
						|
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | 
						|
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | 
						|
 * See the Mulan PubL v2 for more details.
 | 
						|
 */
 | 
						|
 | 
						|
#include <cstdlib>
 | 
						|
#include <pthread.h>
 | 
						|
 | 
						|
#include "gtest/gtest.h"
 | 
						|
#include "lib/allocator/ob_malloc.h"
 | 
						|
 | 
						|
#include "clog/ob_log_ext_ring_buffer.h"
 | 
						|
 | 
						|
using namespace oceanbase;
 | 
						|
using namespace common;
 | 
						|
 | 
						|
namespace oceanbase {
 | 
						|
namespace unittest {
 | 
						|
 | 
						|
class Runnable {
 | 
						|
public:
 | 
						|
  virtual ~Runnable()
 | 
						|
  {}
 | 
						|
  virtual void routine() = 0;
 | 
						|
 | 
						|
public:
 | 
						|
  void run()
 | 
						|
  {
 | 
						|
    pthread_create(&thread_, NULL, pthread_routine_, this);
 | 
						|
  }
 | 
						|
  void join()
 | 
						|
  {
 | 
						|
    pthread_join(thread_, NULL);
 | 
						|
  }
 | 
						|
 | 
						|
private:
 | 
						|
  static void* pthread_routine_(void* arg)
 | 
						|
  {
 | 
						|
    Runnable* runnable = static_cast<Runnable*>(arg);
 | 
						|
    runnable->routine();
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
  pthread_t thread_;
 | 
						|
};
 | 
						|
 | 
						|
class Data : public clog::ObILogExtRingBufferData {
 | 
						|
public:
 | 
						|
  virtual ~Data()
 | 
						|
  {}
 | 
						|
  virtual void destroy()
 | 
						|
  {
 | 
						|
    delete this;
 | 
						|
  }
 | 
						|
  virtual bool can_overwrite(const ObILogExtRingBufferData* data)
 | 
						|
  {
 | 
						|
    UNUSED(data);
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
  virtual bool can_be_removed()
 | 
						|
  {
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
  virtual int on_pop()
 | 
						|
  {
 | 
						|
    return OB_SUCCESS;
 | 
						|
  }
 | 
						|
  int64_t data_;
 | 
						|
};
 | 
						|
 | 
						|
class SetRunnable : public Runnable {
 | 
						|
public:
 | 
						|
  virtual void routine()
 | 
						|
  {
 | 
						|
    for (int64_t idx = 0; idx < cnt_; ++idx) {
 | 
						|
      int64_t sn = s_ + idx;
 | 
						|
      Data* d = new Data();
 | 
						|
      rb_->set(sn, d);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  clog::ObLogExtRingBuffer* rb_;
 | 
						|
  int64_t s_;
 | 
						|
  int64_t cnt_;
 | 
						|
};
 | 
						|
class PopRunnable : public Runnable {
 | 
						|
public:
 | 
						|
  virtual void routine()
 | 
						|
  {
 | 
						|
    // int64_t begin_sn = -1;
 | 
						|
    // while ((begin_sn = rb_->get_start_id()) < (s_ + cnt_)) {
 | 
						|
    //  int ret = rb_->pop();
 | 
						|
    //  UNUSED(ret);
 | 
						|
    //}
 | 
						|
  }
 | 
						|
  clog::ObLogExtRingBuffer* rb_;
 | 
						|
  int64_t s_;
 | 
						|
  int64_t cnt_;
 | 
						|
};
 | 
						|
TEST(RINGBUFFER_BASE, debug3)
 | 
						|
{
 | 
						|
  const int64_t s = 10000;
 | 
						|
  const int64_t setthcnt = 16;
 | 
						|
  const int64_t popthcnt = 16;
 | 
						|
  const int64_t th_size = 500000;
 | 
						|
 | 
						|
  int ret = OB_SUCCESS;
 | 
						|
  clog::ObLogExtRingBuffer rb;
 | 
						|
  ret = rb.init(s);
 | 
						|
  EXPECT_EQ(OB_SUCCESS, ret);
 | 
						|
 | 
						|
  SetRunnable set_runnable[setthcnt];
 | 
						|
  PopRunnable pop_runnable[popthcnt];
 | 
						|
  for (int64_t idx = 0; idx < setthcnt; ++idx) {
 | 
						|
    SetRunnable& r = set_runnable[idx];
 | 
						|
    r.rb_ = &rb;
 | 
						|
    r.s_ = s + idx * th_size;
 | 
						|
    r.cnt_ = th_size;
 | 
						|
  }
 | 
						|
  for (int64_t idx = 0; idx < popthcnt; ++idx) {
 | 
						|
    PopRunnable& r = pop_runnable[idx];
 | 
						|
    r.rb_ = &rb;
 | 
						|
    r.s_ = s;
 | 
						|
    r.cnt_ = th_size * setthcnt;
 | 
						|
  }
 | 
						|
 | 
						|
  // Run.
 | 
						|
  for (int64_t idx = 0; idx < popthcnt; ++idx) {
 | 
						|
    PopRunnable& r = pop_runnable[idx];
 | 
						|
    r.run();
 | 
						|
  }
 | 
						|
  for (int64_t idx = 0; idx < setthcnt; ++idx) {
 | 
						|
    SetRunnable& r = set_runnable[idx];
 | 
						|
    r.run();
 | 
						|
  }
 | 
						|
 | 
						|
  // Join.
 | 
						|
  for (int64_t idx = 0; idx < popthcnt; ++idx) {
 | 
						|
    PopRunnable& r = pop_runnable[idx];
 | 
						|
    r.join();
 | 
						|
  }
 | 
						|
  for (int64_t idx = 0; idx < setthcnt; ++idx) {
 | 
						|
    SetRunnable& r = set_runnable[idx];
 | 
						|
    r.join();
 | 
						|
  }
 | 
						|
 | 
						|
  ret = rb.destroy();
 | 
						|
  EXPECT_EQ(OB_SUCCESS, ret);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Test Truncate.
 | 
						|
 */
 | 
						|
TEST(RingBuffer, TruncateTest1)
 | 
						|
{
 | 
						|
 | 
						|
  int ret = OB_SUCCESS;
 | 
						|
  clog::ObLogExtRingBuffer rb;
 | 
						|
  ret = rb.init(0);
 | 
						|
  EXPECT_EQ(OB_SUCCESS, ret);
 | 
						|
 | 
						|
  // Ringbuffer empty and truncate to 5.
 | 
						|
  ret = rb.truncate(5);
 | 
						|
  EXPECT_EQ(OB_SUCCESS, ret);
 | 
						|
  EXPECT_EQ(5, rb.get_start_id());
 | 
						|
 | 
						|
  // Insert 5-10 and trucate to 11.
 | 
						|
  {
 | 
						|
    for (int64_t sn = 5; sn <= 10; ++sn) {
 | 
						|
      Data* d = new Data();
 | 
						|
      ret = rb.set(sn, d);
 | 
						|
      EXPECT_EQ(OB_SUCCESS, ret);
 | 
						|
    }
 | 
						|
    ret = rb.truncate(11);
 | 
						|
    EXPECT_EQ(OB_SUCCESS, ret);
 | 
						|
    EXPECT_EQ(11, rb.get_start_id());
 | 
						|
  }
 | 
						|
 | 
						|
  // Insert 11-20 and trucate to 16.
 | 
						|
  {
 | 
						|
    for (int64_t sn = 11; sn <= 20; ++sn) {
 | 
						|
      Data* d = new Data();
 | 
						|
      ret = rb.set(sn, d);
 | 
						|
      EXPECT_EQ(OB_SUCCESS, ret);
 | 
						|
    }
 | 
						|
    ret = rb.truncate(16);
 | 
						|
    EXPECT_EQ(OB_SUCCESS, ret);
 | 
						|
    EXPECT_EQ(16, rb.get_start_id());
 | 
						|
  }
 | 
						|
 | 
						|
  // Truncate to 1001.
 | 
						|
  ret = rb.truncate(1001);
 | 
						|
  EXPECT_EQ(OB_SUCCESS, ret);
 | 
						|
  EXPECT_EQ(1001, rb.get_start_id());
 | 
						|
 | 
						|
  ret = rb.destroy();
 | 
						|
  EXPECT_EQ(OB_SUCCESS, ret);
 | 
						|
}
 | 
						|
 | 
						|
}  // namespace unittest
 | 
						|
}  // namespace oceanbase
 | 
						|
 | 
						|
int main(int argc, char** argv)
 | 
						|
{
 | 
						|
  oceanbase::common::ObLogger::get_logger().set_log_level("debug");
 | 
						|
  testing::InitGoogleTest(&argc, argv);
 | 
						|
  // testing::FLAGS_gtest_filter = "DO_NOT_RUN";
 | 
						|
  testing::FLAGS_gtest_filter = "*Truncate*";
 | 
						|
  return RUN_ALL_TESTS();
 | 
						|
}
 |