ob_sstable_estimator.h 6.8 KB
Newer Older
O
oceanbase-admin 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/**
 * 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.
 */

#ifndef OCEANBASE_STORAGE_OB_SSTABLE_ESTIMATOR_H
#define OCEANBASE_STORAGE_OB_SSTABLE_ESTIMATOR_H

#include "storage/ob_sstable.h"

namespace oceanbase {
namespace storage {

struct ObSSTableEstimateContext {
G
gm 已提交
22
public:
O
oceanbase-admin 已提交
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
  ObSSTableEstimateContext();
  ~ObSSTableEstimateContext();
  void reset();
  bool is_valid() const;

  ObSSTable* sstable_;
  union {
    const common::ObIArray<common::ObExtStoreRowkey>* rowkeys_;  // for multi get and single get
    const common::ObExtStoreRange* range_;                       // for scan
    const common::ObIArray<common::ObExtStoreRange>* ranges_;    // for multi scan
  };
  common::ObExtStoreRange multi_version_range_;
  blocksstable::ObStorageCacheContext cache_context_;
  static const int64_t LOCAL_ARRAY_SIZE = 16;
  common::ObSEArray<blocksstable::ObMacroBlockCtx, LOCAL_ARRAY_SIZE> macro_blocks_;

  TO_STRING_KV(KP_(sstable), KP_(rowkeys), K_(macro_blocks), K_(multi_version_range));
};

class ObISSTableEstimator {
G
gm 已提交
43
public:
O
oceanbase-admin 已提交
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
  explicit ObISSTableEstimator()
  {}
  virtual ~ObISSTableEstimator()
  {}
  virtual int set_context(ObSSTableEstimateContext& context)
  {
    int ret = common::OB_SUCCESS;
    if (OB_UNLIKELY(!context.is_valid())) {
      ret = common::OB_INVALID_ARGUMENT;
      STORAGE_LOG(WARN, "failed to set context", K(ret), K(context));
    } else {
      context_ = context;
    }
    return ret;
  }
  virtual int estimate_row_count(ObPartitionEst& part_est) = 0;

G
gm 已提交
61
protected:
O
oceanbase-admin 已提交
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
  void reset()
  {
    context_.reset();
  }

  // This method is used for estimate border micro block row count in two cases:
  // 1. consider_multi_version = false in major sstable;
  // 2. consider_multi_version = true in minor major sstable, where multiple versions
  //    of row keys should be considered.
  int estimate_border_row_count(const blocksstable::ObMicroBlockInfo& micro_info,
      const blocksstable::ObMacroBlockCtx& macro_block_ctx, bool consider_multi_version, int64_t& logical_row_count,
      int64_t& physical_row_count);
  static int get_rowkey_column_desc(
      const blocksstable::ObFullMacroBlockMeta& meta, common::ObIArray<share::schema::ObColDesc>& columns);

G
gm 已提交
77
protected:
O
oceanbase-admin 已提交
78 79 80 81
  ObSSTableEstimateContext context_;
};

class ObISSTableEstimatorWrapper {
G
gm 已提交
82
public:
O
oceanbase-admin 已提交
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
  explicit ObISSTableEstimatorWrapper() : estimator_(NULL)
  {}
  virtual ~ObISSTableEstimatorWrapper()
  {
    reset();
  }
  virtual int estimate_row_count(ObPartitionEst& part_est)
  {
    int ret = common::OB_SUCCESS;
    if (OB_ISNULL(estimator_)) {
      ret = common::OB_NOT_INIT;
      STORAGE_LOG(WARN, "estimator is null", K(ret));
    } else if (OB_FAIL(estimator_->estimate_row_count(part_est))) {
      STORAGE_LOG(WARN, "failed to estimate cost", K(ret));
    }
    return ret;
  }

  void reset()
  {
    if (NULL != estimator_) {
      estimator_->~ObISSTableEstimator();
      estimator_ = NULL;
    }
    allocator_.reset();
  }

  int set_context(ObSSTableEstimateContext& context)
  {
    int ret = common::OB_SUCCESS;
    if (!context.is_valid()) {
      ret = common::OB_INVALID_ARGUMENT;
      STORAGE_LOG(WARN, "estimate context is not valid", K(ret), K(context));
    } else if (OB_FAIL(alloc_estimator(*context.sstable_))) {
      STORAGE_LOG(WARN, "failed to alloc estimator", K(ret));
    } else if (OB_FAIL(estimator_->set_context(context))) {
      STORAGE_LOG(WARN, "failed to set context", K(ret), K(context));
    }
    return ret;
  }

G
gm 已提交
124
protected:
O
oceanbase-admin 已提交
125 126
  virtual int alloc_estimator(const ObSSTable& sstable) = 0;

G
gm 已提交
127
protected:
O
oceanbase-admin 已提交
128 129 130 131 132
  common::ObArenaAllocator allocator_;
  ObISSTableEstimator* estimator_;
};

class ObStoreRowMultiGetEstimator : public ObISSTableEstimator {
G
gm 已提交
133
public:
O
oceanbase-admin 已提交
134 135 136 137 138 139 140
  ObStoreRowMultiGetEstimator();
  virtual ~ObStoreRowMultiGetEstimator();
  virtual int set_context(ObSSTableEstimateContext& context) override;
  virtual int estimate_row_count(ObPartitionEst& part_est) override;
};

class ObSSTableScanEstimator : public ObISSTableEstimatorWrapper {
G
gm 已提交
141
public:
O
oceanbase-admin 已提交
142 143 144 145 146 147 148 149
  ObSSTableScanEstimator()
  {}
  virtual ~ObSSTableScanEstimator()
  {}
  virtual int alloc_estimator(const ObSSTable& sstable) override;
};

class ObStoreRowSingleScanEstimator : public ObISSTableEstimator {
G
gm 已提交
150
public:
O
oceanbase-admin 已提交
151 152 153 154 155 156 157
  ObStoreRowSingleScanEstimator();
  virtual ~ObStoreRowSingleScanEstimator();
  int set_context(ObSSTableEstimateContext& context);
  int open();
  void reset();
  virtual int estimate_row_count(ObPartitionEst& part_est);

G
gm 已提交
158
private:
O
oceanbase-admin 已提交
159 160 161 162 163 164 165 166 167 168 169 170
  int estimate_macro_row_count(const blocksstable::ObMacroBlockCtx& macro_block_ctx, const bool is_start_block,
      const bool is_last_block, ObPartitionEst& part_est);
  int estimate_border_cost(const common::ObIArray<blocksstable::ObMicroBlockInfo>& micro_infos,
      const blocksstable::ObMacroBlockCtx& macro_block_ctx, const bool check_start, const int64_t average_row_count,
      const int64_t average_row_size, int64_t& micro_block_count, ObPartitionEst& part_est);
  int estimate_border_count_(const blocksstable::ObMicroBlockInfo& micro_info,
      const blocksstable::ObMacroBlockCtx& macro_block_ctx, const int64_t average_row_size, int64_t& result_row_count,
      int64_t& micro_block_count, ObPartitionEst& part_est);
  static int get_common_prefix_length(
      const common::ObStoreRowkey& key1, const common::ObStoreRowkey& key2, int64_t& length);
  static int get_common_rowkey(const common::ObStoreRange& range, common::ObStoreRowkey& rowkey);

G
gm 已提交
171
private:
O
oceanbase-admin 已提交
172 173 174 175 176
  bool is_empty_scan_;
  bool is_first_scan_;
};

class ObMultiVersionSingleScanEstimator : public ObISSTableEstimator {
G
gm 已提交
177
public:
O
oceanbase-admin 已提交
178 179 180 181 182 183 184 185 186
  ObMultiVersionSingleScanEstimator(common::ObArenaAllocator& allocator) : allocator_(allocator)
  {}
  virtual ~ObMultiVersionSingleScanEstimator()
  {
    reset();
  }
  int set_context(ObSSTableEstimateContext& context) override;
  int estimate_row_count(ObPartitionEst& part_est) override;

G
gm 已提交
187
private:
O
oceanbase-admin 已提交
188 189 190
  int estimate_macro_row_count(const blocksstable::ObMacroBlockCtx& macro_block_ctx, const bool is_left_border,
      const bool is_right_border, ObPartitionEst& part_est, int64_t& gap_size, int64_t& purged_phy_row_count);

G
gm 已提交
191
private:
O
oceanbase-admin 已提交
192 193 194 195
  common::ObArenaAllocator& allocator_;
};

class ObStoreRowMultiScanEstimator : public ObISSTableEstimator {
G
gm 已提交
196
public:
O
oceanbase-admin 已提交
197 198 199 200 201 202 203 204
  ObStoreRowMultiScanEstimator();
  virtual ~ObStoreRowMultiScanEstimator();
  virtual int estimate_row_count(ObPartitionEst& part_est);
};

}  // namespace storage
}  // namespace oceanbase
#endif /* OCEANBASE_STORAGE_OB_SSTABLE_ESTIMATOR_H */