trx.h 3.1 KB
Newer Older
羽飞's avatar
羽飞 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
         http://license.coscl.org.cn/MulanPSL2
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 PSL v2 for more details. */

//
// Created by Wangyunlai on 2021/5/24.
//

15
#pragma once
羽飞's avatar
羽飞 已提交
16 17 18 19 20 21 22

#include <stddef.h>
#include <unordered_map>
#include <unordered_set>
#include <mutex>

#include "sql/parser/parse.h"
羽飞's avatar
羽飞 已提交
23
#include "storage/record/record_manager.h"
羽飞's avatar
羽飞 已提交
24 25 26 27
#include "rc.h"

class Table;

28 29
class Operation 
{
羽飞's avatar
羽飞 已提交
30
public:
31
  enum class Type : int {
羽飞's avatar
羽飞 已提交
32 33 34 35 36 37 38
    INSERT,
    UPDATE,
    DELETE,
    UNDEFINED,
  };

public:
39 40
  Operation(Type type, const RID &rid) : type_(type), page_num_(rid.page_num), slot_num_(rid.slot_num)
  {}
羽飞's avatar
羽飞 已提交
41

42 43
  Type type() const
  {
羽飞's avatar
羽飞 已提交
44 45
    return type_;
  }
46 47
  PageNum page_num() const
  {
羽飞's avatar
羽飞 已提交
48 49
    return page_num_;
  }
50 51
  SlotNum slot_num() const
  {
羽飞's avatar
羽飞 已提交
52 53 54 55 56
    return slot_num_;
  }

private:
  Type type_;
57 58
  PageNum page_num_;
  SlotNum slot_num_;
羽飞's avatar
羽飞 已提交
59
};
60 61 62

class OperationHasher 
{
羽飞's avatar
羽飞 已提交
63
public:
64 65
  size_t operator()(const Operation &op) const
  {
羽飞's avatar
羽飞 已提交
66 67 68 69
    return (((size_t)op.page_num()) << 32) | (op.slot_num());
  }
};

70 71
class OperationEqualer 
{
羽飞's avatar
羽飞 已提交
72
public:
73 74 75
  bool operator()(const Operation &op1, const Operation &op2) const
  {
    return op1.page_num() == op2.page_num() && op1.slot_num() == op2.slot_num();
羽飞's avatar
羽飞 已提交
76 77 78 79 80 81 82
  }
};

/**
 * 这里是一个简单的事务实现,可以支持提交/回滚。但是没有对并发访问做控制
 * 可以在这个基础上做备份恢复,当然也可以重写
 */
83 84
class Trx 
{
羽飞's avatar
羽飞 已提交
85
public:
羽飞's avatar
羽飞 已提交
86 87
  static std::atomic<int32_t> trx_id;

羽飞's avatar
羽飞 已提交
88 89
  static int32_t default_trx_id();
  static int32_t next_trx_id();
羽飞's avatar
羽飞 已提交
90 91
  static void set_trx_id(int32_t id);

羽飞's avatar
羽飞 已提交
92 93
  static const char *trx_field_name();
  static AttrType trx_field_type();
94
  static int trx_field_len();
羽飞's avatar
羽飞 已提交
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113

public:
  Trx();
  ~Trx();

public:
  RC insert_record(Table *table, Record *record);
  RC delete_record(Table *table, Record *record);

  RC commit();
  RC rollback();

  RC commit_insert(Table *table, Record &record);
  RC rollback_delete(Table *table, Record &record);

  bool is_visible(Table *table, const Record *record);

  void init_trx_info(Table *table, Record &record);

羽飞's avatar
羽飞 已提交
114 115 116 117
  void next_current_id();

  int32_t get_current_id();

羽飞's avatar
羽飞 已提交
118 119 120 121 122 123 124 125 126 127 128 129 130
private:
  void set_record_trx_id(Table *table, Record &record, int32_t trx_id, bool deleted) const;
  static void get_record_trx_id(Table *table, const Record &record, int32_t &trx_id, bool &deleted);

private:
  using OperationSet = std::unordered_set<Operation, OperationHasher, OperationEqualer>;

  Operation *find_operation(Table *table, const RID &rid);
  void insert_operation(Table *table, Operation::Type type, const RID &rid);
  void delete_operation(Table *table, const RID &rid);

private:
  void start_if_not_started();
131

羽飞's avatar
羽飞 已提交
132
private:
133
  int32_t trx_id_ = 0;
羽飞's avatar
羽飞 已提交
134 135
  std::unordered_map<Table *, OperationSet> operations_;
};