File xasl_spawner.hpp¶
File List > cubrid > src > xasl > xasl_spawner.hpp
Go to the documentation of this file
/*
* Copyright 2008 Search Solution Corporation
* Copyright 2016 CUBRID Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* xasl_spawner.hpp
*/
#pragma once
#include <unordered_map>
#include "dbtype_def.h"
#include "heap_attrinfo.h"
#include "query_list.h"
#include "regu_var.hpp"
#include "xasl_predicate.hpp"
#include "xasl_sp.hpp"
/*
* Forward Declarations
*/
struct qproc_db_value_list;
struct val_descr;
struct val_list_node;
typedef struct qproc_db_value_list *QPROC_DB_VALUE_LIST;
typedef struct val_descr VAL_DESCR;
typedef struct val_list_node VAL_LIST;
/*
* Class Definitions
*/
namespace cubxasl
{
class spawner
{
public:
spawner (cubthread::entry &main_thread_ref);
~spawner ();
PRED_EXPR *spawn (const PRED_EXPR *pred_expr);
int spawn (const PRED *src, PRED *dest);
int spawn (const EVAL_TERM *src, EVAL_TERM *dest);
int spawn (const COMP_EVAL_TERM *src, COMP_EVAL_TERM *dest);
int spawn (const ALSM_EVAL_TERM *src, ALSM_EVAL_TERM *dest);
int spawn (const LIKE_EVAL_TERM *src, LIKE_EVAL_TERM *dest);
int spawn (const RLIKE_EVAL_TERM *src, RLIKE_EVAL_TERM *dest);
cub_compiled_regex *spawn (const cub_compiled_regex *src);
REGU_VARIABLE *spawn (const REGU_VARIABLE *src);
int spawn (const REGU_VARIABLE *src, REGU_VARIABLE *dest);
DB_VALUE *spawn (const DB_VALUE *src);
ARITH_TYPE *spawn (const ARITH_TYPE *src);
struct drand48_data *spawn (const struct drand48_data *src);
int spawn (const ATTR_DESCR *src, ATTR_DESCR *dest);
HEAP_CACHE_ATTRINFO *spawn (const HEAP_CACHE_ATTRINFO *src);
OR_CLASSREP *spawn (const OR_CLASSREP *src); /* TODO: unsupported */
int spawn (const HEAP_ATTRVALUE *src, HEAP_ATTRVALUE *dest);
OR_ATTRIBUTE *spawn (const OR_ATTRIBUTE *src); /* TODO: unsupported */
int spawn (const QFILE_TUPLE_VALUE_POSITION *src, QFILE_TUPLE_VALUE_POSITION *dest);
QFILE_SORTED_LIST_ID *spawn (const QFILE_SORTED_LIST_ID *src);
QFILE_LIST_ID *spawn (const QFILE_LIST_ID *src); /* TODO: unsupported */
FUNCTION_TYPE *spawn (const FUNCTION_TYPE *src);
function_tmp_obj *spawn (const function_tmp_obj *src); /* TODO: unsupported */
REGU_VALUE_LIST *spawn (const REGU_VALUE_LIST *src);
REGU_VALUE_ITEM *spawn (const REGU_VALUE_ITEM *src);
REGU_VARIABLE_LIST spawn (const REGU_VARIABLE_LIST src);
SP_TYPE *spawn (const SP_TYPE *src);
PL_SIGNATURE_TYPE *spawn (const PL_SIGNATURE_TYPE *src); /* TODO: unsupported */
/* (XASL_NODE *)->val_list */
VAL_LIST *spawn (const VAL_LIST *src);
int spawn (const QPROC_DB_VALUE_LIST src, QPROC_DB_VALUE_LIST dest);
/* (XASL_STATE *)->vd */
VAL_DESCR *spawn (const VAL_DESCR *src);
template <typename T>
T *
find (const T *src);
template <typename T>
T *
find (const T *src, int count);
template <typename T>
T *alloc (const T *src);
template <typename T>
T *alloc (const T *src, int count);
private:
struct cached_entry
{
void *ptr = nullptr;
int count = 0;
void (*deleter) (cubthread::entry *thread_p, void *ptr, int count) = nullptr;
};
cubthread::entry &m_thread_ref;
std::unordered_map<const void *, cached_entry> m_cached_ptrs;
template <typename T>
static void cached_entry_deleter (cubthread::entry *thread_p, void *ptr, int count);
bool is_valid_argument (const void *src, const void *dest);
};
} /* namespace cubxasl */
/*
* Function Definitions
*/
namespace cubxasl
{
template <typename T>
T *
spawner::find (const T *src)
{
return spawner::find (src, 1);
}
template <typename T>
T *
spawner::find (const T *src, int count)
{
if (src == nullptr)
{
return nullptr;
}
auto old_it = m_cached_ptrs.find (src);
if (old_it != m_cached_ptrs.end())
{
assert_release_error (old_it->second.count == count);
return static_cast<T *> (old_it->second.ptr);
}
return nullptr;
}
template <typename T>
T *
spawner::alloc (const T *src)
{
return spawner::alloc (src, 1);
}
template <typename T>
T *
spawner::alloc (const T *src, int count)
{
int init_cnt = 0;
if (src == nullptr)
{
return nullptr;
}
T *dest = static_cast<T *> (db_private_alloc (&m_thread_ref, count * sizeof (T)));
if (dest == nullptr )
{
ASSERT_ERROR ();
return nullptr;
}
for (int i = 0; i < count; i++)
{
T *item = dest + i;
try
{
/* placement new */
new (item) T();
++init_cnt;
cached_entry entry;
entry.ptr = item;
entry.count = count;
entry.deleter = (i == 0) ? &cached_entry_deleter<T> : nullptr;
auto [new_it, inserted] = m_cached_ptrs.try_emplace (src + i, std::move (entry));
if (!inserted)
{
/* impossible case */
assert_release_error (false);
throw std::runtime_error ("spawner::alloc failed");
}
}
catch (...)
{
auto it = m_cached_ptrs.find (src);
if (it != m_cached_ptrs.end() && it->second.deleter != nullptr)
{
if (it->second.deleter != nullptr)
{
it->second.deleter (&m_thread_ref, it->second.ptr, init_cnt);
}
m_cached_ptrs.erase (it);
}
return nullptr;
}
}
ASSERT_NO_ERROR_OR_INTERRUPTED ();
return dest;
}
template <typename T>
inline void
spawner::cached_entry_deleter (cubthread::entry *thread_p, void *ptr, int count)
{
if (ptr == nullptr)
{
return;
}
T *typed_ptr = static_cast<T *> (ptr);
/*
* When the spawner is extended to support a new type T:
* - Call pr_clear_value for all non-pointer DB_VALUE members
* - Refer to REGU_VARIABLE and DB_VALUE cases as examples
*/
if constexpr (std::is_same_v<T, REGU_VARIABLE>)
{
if (typed_ptr->type == TYPE_DBVAL)
{
for (int i = 0; i < count; i++)
{
pr_clear_value (&typed_ptr[i].value.dbval);
}
}
}
else if constexpr (std::is_same_v<T, DB_VALUE>)
{
for (int i = 0; i < count; i++)
{
pr_clear_value (&typed_ptr[i]);
}
}
else
{
/* fall through */
}
for (int i = 0; i < count; i++)
{
typed_ptr[i].~T();
}
db_private_free_and_init (thread_p, typed_ptr);
}
} /* namespace cubxasl */