oceanbase

Форк
0
/
ob_pl_allocator.cpp 
215 строк · 7.0 Кб
1
/**
2
 * Copyright (c) 2021 OceanBase
3
 * OceanBase CE is licensed under Mulan PubL v2.
4
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
5
 * You may obtain a copy of Mulan PubL v2 at:
6
 *          http://license.coscl.org.cn/MulanPubL-2.0
7
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10
 * See the Mulan PubL v2 for more details.
11
 */
12

13
#define USING_LOG_PREFIX PL
14

15
#include "ob_pl_allocator.h"
16
#include "ob_pl_package_state.h"
17

18
namespace oceanbase
19
{
20
namespace pl
21
{
22

23
void* ObPLAllocator::alloc(const int64_t size, const ObMemAttr &attr)
24
{
25
  int ret = OB_SUCCESS;
26
  void *ptr = NULL;
27
  if (OB_ISNULL(curr_)) {
28
    ret = OB_ERR_UNEXPECTED;
29
    LOG_ERROR("current allocator is null", K(ret), K(curr_));
30
  } else if (can_shrink_ && curr_->used() > next_threshold_) {
31
    if (OB_FAIL(shrink())) {
32
      LOG_WARN("failed to shrink buffer", K(ret), K(next_threshold_), K(threshold_));
33
    }
34
  }
35
  if (OB_SUCC(ret)) {
36
    ptr = curr_->alloc(size, attr);
37
  }
38
  return ptr;
39
}
40

41
void ObPLAllocator::reset()
42
{
43
  allocator1_.reset();
44
  allocator2_.reset();
45
  curr_ = &allocator1_;
46
  backup_ = &allocator2_;
47
}
48

49
int ObPLAllocator::shrink()
50
{
51
  int ret = OB_SUCCESS;
52
  if (OB_ISNULL(curr_)) {
53
    ret = OB_ERR_UNEXPECTED;
54
    LOG_WARN("current allocator is null", K(ret), K(curr_));
55
  } else if (curr_->used() < next_threshold_) {
56
    // do nothing ...
57
  } else if (OB_FAIL(copy_all_element_with_new_allocator(backup_))) {
58
    LOG_WARN("failed to copy all element",
59
             K(ret), K(next_threshold_), K(curr_->used()), K(backup_->used()));
60
  } else {
61
    // calc next threshold
62
    next_threshold_ = std::max(2 * backup_->used(), threshold_);
63
    LOG_INFO("NOTICE: shrink allocator done!",
64
              K(next_threshold_),
65
              K(threshold_),
66
              K(backup_->used()), K(curr_->used()),
67
              K(curr_), K(backup_));
68
    // replace current allocator
69
    ObIAllocator *tmp = curr_;
70
    curr_->reset();
71
    curr_ = backup_;
72
    backup_ = tmp;
73
  }
74
  return ret;
75
}
76

77
int ObPLCollAllocator::free_child_coll(ObPLCollection &dest)
78
{
79
  int ret = OB_SUCCESS;
80

81
  for (int64_t i = 0; OB_SUCC(ret) && i < dest.get_count(); ++i) {
82
    OZ (ObUserDefinedType::destruct_obj(dest.get_data()[i], NULL));
83
  }
84
  return ret;
85
}
86

87
int ObPLCollAllocator::copy_all_element_with_new_allocator(ObIAllocator *allocator)
88
{
89
  int ret = OB_SUCCESS;
90
#ifndef OB_BUILD_ORACLE_PL
91
    UNUSED(allocator);
92
    ret = OB_NOT_SUPPORTED;
93
    LOG_WARN("not support", K(ret));
94
#else
95
  if (OB_ISNULL(allocator)) {
96
    ret = OB_ERR_UNEXPECTED;
97
    LOG_WARN("copy allocator is null", K(ret), K(allocator));
98
  } else if (OB_ISNULL(coll_)) {
99
    ret = OB_ERR_UNEXPECTED;
100
    LOG_WARN("collection is null", K(ret), K(coll_));
101
  } else {
102

103
#define DEEP_COPY_COLLECTION(type, class) \
104
  case type: { \
105
    if (OB_ISNULL(dest = reinterpret_cast<class*>(allocator->alloc(sizeof(class))))) { \
106
      ret = OB_ALLOCATE_MEMORY_FAILED; \
107
      LOG_WARN("failed to alloc memory for collection", K(ret), K(allocator), KPC(coll_), KPC(dest)); \
108
    } else if (FALSE_IT(dest = new (dest) class(coll_->get_id()))) { \
109
    } else if (OB_FAIL((reinterpret_cast<class*>(dest))->deep_copy(coll_, allocator))) { \
110
      LOG_WARN("failed to deep copy", K(ret), K(allocator), KPC(coll_), KPC(dest)); \
111
      int tmp = ObPLCollAllocator::free_child_coll(reinterpret_cast<ObPLCollection&>(*dest));   \
112
      if (OB_SUCCESS != tmp) {                                      \
113
        LOG_WARN("failed to free child memory", K(tmp));    \
114
      }  \
115
    } \
116
    break; \
117
  }
118
    ObPLCollection* dest = NULL;
119
    switch (coll_->get_type()) {
120
      DEEP_COPY_COLLECTION(PL_NESTED_TABLE_TYPE, ObPLNestedTable);
121
      DEEP_COPY_COLLECTION(PL_ASSOCIATIVE_ARRAY_TYPE, ObPLAssocArray);
122
      DEEP_COPY_COLLECTION(PL_VARRAY_TYPE, ObPLVArray);
123
      default: {
124
        ret = OB_ERR_UNEXPECTED;
125
        LOG_WARN("unknow collection type", K(ret), K(coll_->get_type()), KPC(coll_));
126
        break;
127
      }
128
    }
129
#undef DEEP_COPY_COLLECTION
130

131
    if (OB_SUCC(ret)) {
132
      dest->set_allocator(this);
133
      for (int64_t i = 0; OB_SUCC(ret) && i < coll_->get_count(); ++i) {
134
        if (OB_FAIL(ObUserDefinedType::destruct_obj(coll_->get_data()[i], NULL))) {
135
          LOG_WARN("failed to destruct collection", K(ret), K(coll_->get_data()[i]), K(i));
136
        }
137
      }
138
      if (OB_SUCC(ret)) {
139
        coll_->set_allocator(dest->get_allocator());
140
        coll_->set_data(dest->get_data());
141
        if (PL_ASSOCIATIVE_ARRAY_TYPE == coll_->get_type()) {
142
          ObPLAssocArray* src = static_cast<ObPLAssocArray*>(coll_);
143
          ObPLAssocArray* dst = static_cast<ObPLAssocArray*>(dest);
144
          if (OB_ISNULL(src) || OB_ISNULL(dst)) {
145
            ret = OB_ERR_UNEXPECTED;
146
            LOG_WARN("unexpected associative array pointer", K(ret), KPC(coll_), KPC(dst));
147
          } else {
148
            src->set_key(dst->get_key());
149
            src->set_sort(dst->get_sort());
150
          }
151
        }
152
      }
153
    }
154
    LOG_INFO("copy all element with new allocator in collection", K(ret), KPC(coll_), KPC(dest), K(lbt()));
155
  }
156
#endif
157
  return ret;
158
}
159

160
int ObPLSymbolAllocator::copy_all_element_with_new_allocator(ObIAllocator *allocator)
161
{
162
  int ret = OB_SUCCESS;
163
  if (OB_ISNULL(allocator)) {
164
    ret = OB_ERR_UNEXPECTED;
165
    LOG_WARN("copy allocator is null", K(ret), K(allocator));
166
  } else if (OB_ISNULL(pl_)) {
167
    ret = OB_ERR_UNEXPECTED;
168
  } else if (OB_ISNULL(pl_->params_)) {
169
    ret = OB_ERR_UNEXPECTED;
170
    LOG_WARN("pl symbols is null", K(ret), K(pl_->params_));
171
  } else if (OB_ISNULL(pl_->result_)) {
172
    ret = OB_ERR_UNEXPECTED;
173
    LOG_WARN("pl result is null", K(ret), K(pl_->result_));
174
  } else {
175
    ParamStore *params = pl_->params_;
176
    for (int64_t i = 0; OB_SUCC(ret) && i < params->count(); ++i) {
177
      ObObj dst;
178
      ObObj *src = &(params->at(i));
179
      OZ (deep_copy_obj(*allocator, *src, dst));
180
      CK (params->at(i).apply(dst));
181
      OX (params->at(i).set_param_meta());
182
    }
183
    ObObj dst_result;
184
    OZ (deep_copy_obj(*allocator, *(pl_->result_), dst_result));
185
    OX ((*pl_->result_).apply(dst_result));
186
  }
187
  return ret;
188
}
189

190
int ObPLPkgAllocator::copy_all_element_with_new_allocator(ObIAllocator *allocator)
191
{
192
  int ret = OB_SUCCESS;
193
  LOG_INFO("copy all element with new allocator in package state");
194
  CK (OB_NOT_NULL(allocator));
195
  CK (OB_NOT_NULL(state_));
196
  if (OB_SUCC(ret)) {
197
    ObIArray<ObObj> &vars = state_->get_vars();
198
    for (int64_t i = 0; OB_SUCC(ret) && i < vars.count(); ++i) {
199
      ObObj dst;
200
      if (vars.at(i).is_pl_extend()
201
          && vars.at(i).get_meta().get_extend_type() != PL_CURSOR_TYPE
202
          && vars.at(i).get_meta().get_extend_type() != PL_REF_CURSOR_TYPE) {
203
        OZ (pl::ObUserDefinedType::deep_copy_obj(*allocator, vars.at(i), dst, true));
204
        OZ (pl::ObUserDefinedType::destruct_obj(vars.at(i), nullptr));
205
      } else {
206
        OZ (deep_copy_obj(*allocator, vars.at(i), dst));
207
      }
208
      OX (vars.at(i) = dst);
209
    }
210
  }
211
  return ret;
212
}
213

214
}
215
}
216

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.