patch 4.0

This commit is contained in:
wangzelin.wzl
2022-10-24 10:34:53 +08:00
parent 4ad6e00ec3
commit 93a1074b0c
10533 changed files with 2588271 additions and 2299373 deletions

View File

@ -0,0 +1,796 @@
/**
* 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.
*/
#define USING_LOG_PREFIX COMMON
#include "share/ob_order_perserving_encoder.h"
#include <byteswap.h>
namespace oceanbase
{
namespace share
{
int ObOrderPerservingEncoder::make_order_perserving_encode_from_object(ObObj &obj,
unsigned char *to,
int64_t max_buf_len,
int64_t &to_len)
{
int ret = OB_SUCCESS;
switch (obj.get_type()) {
// for integer values
case ObTinyIntType: {
if (to_len + sizeof(int8_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(obj.get_type()));
} else {
encode_from_int8(obj.get_tinyint(), to, to_len);
}
break;
}
case ObSmallIntType: {
if (to_len + sizeof(int16_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(obj.get_type()));
} else {
encode_from_int16(obj.get_smallint(), to, to_len);
}
break;
}
case ObDateType:
case ObMediumIntType:
case ObInt32Type: {
if (to_len + sizeof(int32_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(obj.get_type()));
} else {
encode_from_int32(obj.get_int32(), to, to_len);
}
break;
}
case ObIntervalYMType:
case ObTimeType:
case ObDateTimeType:
case ObTimestampType:
case ObIntType: {
if (to_len + sizeof(int64_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(obj.get_type()));
} else {
encode_from_int(obj.get_int(), to, to_len);
}
break;
}
case ObYearType:
case ObUTinyIntType: {
if (to_len + sizeof(uint8_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(obj.get_type()));
} else {
encode_from_uint8(obj.get_utinyint(), to, to_len);
}
break;
}
case ObUSmallIntType: {
if (to_len + sizeof(uint16_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(obj.get_type()));
} else {
encode_from_uint16(obj.get_usmallint(), to, to_len);
}
break;
}
case ObUMediumIntType:
case ObUInt32Type: {
if (to_len + sizeof(uint32_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(obj.get_type()));
} else {
encode_from_uint32(obj.get_uint32(), to, to_len);
}
break;
}
case ObUInt64Type: {
if (to_len + sizeof(uint64_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(obj.get_type()));
} else {
encode_from_uint(obj.get_uint64(), to, to_len);
}
break;
}
// for float values
case ObFloatType:
case ObUFloatType: {
if (to_len + sizeof(float) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(obj.get_type()));
} else {
encode_from_float(obj.get_float(), to, to_len);
}
break;
}
case ObDoubleType:
case ObUDoubleType: {
if (to_len + sizeof(double) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(obj.get_type()));
} else {
encode_from_double(obj.get_double(), to, to_len);
}
break;
}
// for obnumber
case ObNumberType:
case ObUNumberType:
case ObNumberFloatType: {
if (OB_FAIL(encode_from_number(obj.get_number(), to, max_buf_len, to_len))) {
if (ret == OB_BUF_NOT_ENOUGH) {
// ignore ret
} else {
LOG_WARN("failed to encode number", K(ret));
}
}
break;
}
// for date
case ObTimestampTZType:
case ObTimestampLTZType:
case ObTimestampNanoType: {
if (to_len + sizeof(int64_t) + sizeof(uint16_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(obj.get_type()));
} else {
encode_from_timestamp(obj.get_otimestamp_value(), to, to_len);
}
break;
}
case ObIntervalDSType: {
if (to_len + sizeof(int64_t) + sizeof(int32_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(obj.get_type()));
} else {
encode_from_interval_ds(obj.get_interval_ds(), to, to_len);
}
break;
}
case ObVarcharType:
case ObNVarchar2Type:
case ObRawType:
case ObNCharType:
case ObCharType: {
if (OB_FAIL(encode_from_string_varlen(obj.get_string(), to, max_buf_len, to_len,
obj.get_collation_type()))) {
if (ret == OB_BUF_NOT_ENOUGH) {
// ignore ret
} else {
LOG_WARN("failed to encode string", K(ret));
}
}
break;
}
case ObURowIDType:
case ObUnknownType:
case ObTinyTextType:
case ObTextType:
case ObMediumTextType:
case ObLongTextType:
case ObBitType:
case ObEnumType:
case ObSetType:
case ObEnumInnerType:
case ObSetInnerType:
case ObLobType:
case ObExtendType:
case ObHexStringType:
default: {
ret = OB_NOT_SUPPORTED;
LOG_WARN("this type cannot make sortkey", K(ret), K(obj.get_type()));
}
}
return ret;
}
int ObOrderPerservingEncoder::make_order_perserving_encode_from_object(
ObDatum &data, unsigned char *to, int64_t max_buf_len, int64_t &to_len, ObEncParam &param)
{
int ret = OB_SUCCESS;
switch (param.type_) {
// for integer values
case ObTinyIntType: {
if (to_len + sizeof(int8_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(param.type_));
} else {
encode_from_int8(data.get_tinyint(), to, to_len);
}
break;
}
case ObSmallIntType: {
if (to_len + sizeof(int16_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(param.type_));
} else {
encode_from_int16(data.get_smallint(), to, to_len);
}
break;
}
case ObDateType:
case ObMediumIntType:
case ObInt32Type: {
if (to_len + sizeof(int32_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(param.type_));
} else {
encode_from_int32(data.get_int32(), to, to_len);
}
break;
}
case ObIntervalYMType:
case ObTimeType:
case ObDateTimeType:
case ObTimestampType:
case ObIntType: {
if (to_len + sizeof(int64_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(param.type_));
} else {
encode_from_int(data.get_int(), to, to_len);
}
break;
}
case ObYearType:
case ObUTinyIntType: {
if (to_len + sizeof(uint8_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(param.type_));
} else {
encode_from_uint8(data.get_utinyint(), to, to_len);
}
break;
}
case ObUSmallIntType: {
if (to_len + sizeof(uint16_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(param.type_));
} else {
encode_from_uint16(data.get_usmallint(), to, to_len);
}
break;
}
case ObUMediumIntType:
case ObUInt32Type: {
if (to_len + sizeof(uint32_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(param.type_));
} else {
encode_from_uint32(data.get_uint32(), to, to_len);
}
break;
}
case ObUInt64Type: {
if (to_len + sizeof(uint64_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(param.type_));
} else {
encode_from_uint(data.get_uint(), to, to_len);
}
break;
}
// for float values
case ObFloatType:
case ObUFloatType: {
if (to_len + sizeof(float) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(param.type_));
} else {
encode_from_float(data.get_float(), to, to_len);
}
break;
}
case ObDoubleType:
case ObUDoubleType: {
if (to_len + sizeof(double) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(param.type_));
} else {
encode_from_double(data.get_double(), to, to_len);
}
break;
}
// for obnumber
case ObNumberType:
case ObUNumberType:
case ObNumberFloatType: {
if (OB_FAIL(encode_from_number(data.get_number(), to, max_buf_len, to_len))) {
if (ret == OB_BUF_NOT_ENOUGH) {
// ignore ret
} else {
LOG_WARN("failed to encode number", K(ret));
}
}
break;
}
// for date
case ObTimestampTZType:
case ObTimestampLTZType:
case ObTimestampNanoType: {
if (to_len + sizeof(int64_t) + sizeof(uint16_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(param.type_));
} else {
encode_from_timestamp(data.get_otimestamp_tz(), to, to_len);
}
break;
}
case ObIntervalDSType: {
if (to_len + sizeof(int64_t) + sizeof(int32_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding", K(ret), K(param.type_));
} else {
encode_from_interval_ds(data.get_interval_ds(), to, to_len);
}
break;
}
case ObVarcharType:
case ObNVarchar2Type: {
if (OB_FAIL(encode_from_string_varlen(data.get_string(), to, max_buf_len, to_len, param))) {
if (ret == OB_BUF_NOT_ENOUGH) {
// ignore ret
} else {
LOG_WARN("failed to encode fix len str", K(ret));
}
}
break;
}
case ObRawType:
case ObNCharType:
case ObCharType: {
if (param.is_var_len_) {
if (OB_FAIL(encode_from_string_varlen(data.get_string(), to, max_buf_len, to_len, param))) {
LOG_WARN("failed to encode varlen str", K(ret));
}
} else {
if (OB_FAIL(encode_from_string_fixlen(data.get_string(), to, max_buf_len, to_len, param))) {
LOG_WARN("failed to encode fix len str", K(ret));
}
}
break;
}
case ObURowIDType:
case ObUnknownType:
case ObTinyTextType:
case ObTextType:
case ObMediumTextType:
case ObLongTextType:
case ObBitType:
case ObEnumType:
case ObSetType:
case ObEnumInnerType:
case ObSetInnerType:
case ObLobType:
case ObExtendType:
case ObHexStringType:
default: {
ret = OB_NOT_SUPPORTED;
LOG_WARN("this type cannot make sortkey", K(ret), K(param.type_));
}
}
return ret;
}
// used for memcmp comparsion
int ObOrderPerservingEncoder::convert_ob_charset_utf8mb4_bin(unsigned char *data,
int64_t len,
unsigned char *to,
int64_t &to_len)
{
unsigned char *d_e = data + len;
while (data < d_e) {
*to = *data;
if (*data == 0x00) {
to++;
to_len++;
*to = 0x01;
}
data++;
to++;
to_len++;
}
*to = 0x00;
*(to + 1) = 0x00;
to_len += 2;
return OB_SUCCESS;
}
// used for space comparsion (0x20)
int ObOrderPerservingEncoder::convert_ob_charset_utf8mb4_bin_sp(unsigned char *data,
int64_t len,
unsigned char *to,
int64_t &to_len)
{
unsigned char *d_e = data + len;
while (*(d_e - 1) == 0x20 && d_e - 1 >= data)
d_e--;
while (data < d_e) {
if (*data == 0x20) {
int16_t sp_cnt = 0;
while (*data == 0x20) {
sp_cnt++;
data++;
if (data == d_e)
sp_cnt = 0;
}
int16_t tmp = (int16_t)((*data) - 0x20);
int16_t x = (~tmp) >> 16;
MEMCPY(to, (unsigned char *)&x, 2);
*to = 0x20;
to += 2;
int16_t sp_cnt_mask = (tmp) >> 16;
sp_cnt = ((sp_cnt) ^ sp_cnt_mask) ^ 0x8000;
sp_cnt = bswap_16(sp_cnt);
MEMCPY(to, (unsigned char *)&sp_cnt, 2);
to += 2;
to_len += 4;
}
*to = *data;
data++;
to++;
to_len++;
}
*to = 0x20;
*(to + 1) = 0x20;
to_len += 2;
return OB_SUCCESS;
}
int ObOrderPerservingEncoder::encode_from_string_varlen(
ObString str, unsigned char *to, int64_t max_buf_len, int64_t &to_len, ObCollationType cs)
{
int ret = OB_SUCCESS;
bool is_valid_uni = false;
bool is_mem = lib::is_oracle_mode();
if ((to_len + 4 * str.length() + 2) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding for string", K(ret));
} else if (cs == CS_TYPE_COLLATION_FREE || cs == CS_TYPE_BINARY || cs == CS_TYPE_UTF8MB4_BIN
|| cs == CS_TYPE_GBK_BIN || cs == CS_TYPE_GB18030_BIN) {
if (is_mem) {
convert_ob_charset_utf8mb4_bin((unsigned char *)str.ptr(), str.length(), to, to_len);
} else {
convert_ob_charset_utf8mb4_bin_sp((unsigned char *)str.ptr(), str.length(), to, to_len);
}
} else if (cs == CS_TYPE_UTF8MB4_GENERAL_CI || cs == CS_TYPE_GBK_CHINESE_CI
|| cs == CS_TYPE_UTF16_GENERAL_CI || cs == CS_TYPE_UTF16_BIN
|| cs == CS_TYPE_GB18030_CHINESE_CI) {
int64_t res_len = ObCharset::sortkey_var_len(cs, str.ptr(), str.length(), (char *)to,
max_buf_len, is_mem, is_valid_uni);
if (res_len < 0) {
ret = OB_NOT_SUPPORTED;
LOG_TRACE("not support collation", K(cs));
} else {
to_len += res_len;
}
} else {
ret = OB_NOT_SUPPORTED;
LOG_TRACE("not support collation", K(cs));
}
return ret;
}
int ObOrderPerservingEncoder::encode_from_string_varlen(
ObString str, unsigned char *to, int64_t max_buf_len, int64_t &to_len, ObEncParam &param)
{
int ret = OB_SUCCESS;
ObCollationType cs = param.cs_type_;
bool is_valid_uni = false;
if ((to_len + 4 * str.length() + 2) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding for string", K(ret));
} else if (cs == CS_TYPE_COLLATION_FREE || cs == CS_TYPE_BINARY || cs == CS_TYPE_UTF8MB4_BIN
|| cs == CS_TYPE_GBK_BIN || cs == CS_TYPE_GB18030_BIN) {
if (param.is_memcmp_) {
convert_ob_charset_utf8mb4_bin((unsigned char *)str.ptr(), str.length(), to, to_len);
} else {
convert_ob_charset_utf8mb4_bin_sp((unsigned char *)str.ptr(), str.length(), to, to_len);
}
} else if (cs == CS_TYPE_UTF8MB4_GENERAL_CI || cs == CS_TYPE_GBK_CHINESE_CI
|| cs == CS_TYPE_UTF16_GENERAL_CI || cs == CS_TYPE_UTF16_BIN
|| cs == CS_TYPE_GB18030_CHINESE_CI) {
int64_t res_len = ObCharset::sortkey_var_len(cs, str.ptr(), str.length(), (char *)to,
max_buf_len, param.is_memcmp_, is_valid_uni);
if (!is_valid_uni) {
// use origninal code to compare
if (param.is_memcmp_) {
convert_ob_charset_utf8mb4_bin((unsigned char *)str.ptr(), str.length(), to, to_len);
} else {
convert_ob_charset_utf8mb4_bin_sp((unsigned char *)str.ptr(), str.length(), to, to_len);
}
} else {
to_len += res_len;
}
} else {
ret = OB_NOT_SUPPORTED;
LOG_TRACE("not support collation", K(cs));
}
return ret;
}
int ObOrderPerservingEncoder::encode_from_string_fixlen(
ObString str, unsigned char *to, int64_t max_buf_len, int64_t &to_len, ObEncParam &param)
{
int ret = OB_SUCCESS;
ObCollationType cs = param.cs_type_;
bool is_valid_uni = false;
if ((to_len + 4 * str.length() + 2) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding for fixed string", K(ret));
} else if (cs == CS_TYPE_COLLATION_FREE || cs == CS_TYPE_BINARY || cs == CS_TYPE_UTF8MB4_BIN
|| cs == CS_TYPE_GBK_BIN || cs == CS_TYPE_GB18030_BIN) {
MEMCPY(to, str.ptr(), str.length());
to_len += str.length();
} else {
to_len
+= ObCharset::sortkey(cs, str.ptr(), str.length(), (char *)to, max_buf_len, is_valid_uni);
}
return ret;
}
int ObOrderPerservingEncoder::encode_from_int8(int8_t val, unsigned char *to, int64_t &to_len)
{
val ^= SIGN_MASK_8;
to_len += sizeof(int8_t);
*to = val;
return OB_SUCCESS;
}
int ObOrderPerservingEncoder::encode_from_int16(int16_t val, unsigned char *to, int64_t &to_len)
{
val ^= SIGN_MASK_16;
val = bswap_16(val);
to_len += sizeof(int16_t);
MEMCPY(to, (unsigned char *)&val, sizeof(val));
return OB_SUCCESS;
}
int ObOrderPerservingEncoder::encode_from_int32(int32_t val, unsigned char *to, int64_t &to_len)
{
val ^= SIGN_MASK_32;
val = bswap_32(val);
to_len += sizeof(int32_t);
MEMCPY(to, (unsigned char *)&val, sizeof(val));
return OB_SUCCESS;
}
int ObOrderPerservingEncoder::encode_from_int(int64_t val, unsigned char *to, int64_t &to_len)
{
val ^= SIGN_MASK_64;
val = bswap_64(val);
to_len += sizeof(int64_t);
MEMCPY(to, (unsigned char *)&val, sizeof(val));
return OB_SUCCESS;
}
int ObOrderPerservingEncoder::encode_from_uint8(uint8_t val, unsigned char *to, int64_t &to_len)
{
to_len += sizeof(uint8_t);
*to = val;
return OB_SUCCESS;
}
int ObOrderPerservingEncoder::encode_from_uint16(uint16_t val, unsigned char *to, int64_t &to_len)
{
val = bswap_16(val);
to_len += sizeof(uint16_t);
MEMCPY(to, (unsigned char *)&val, sizeof(val));
return OB_SUCCESS;
}
int ObOrderPerservingEncoder::encode_from_uint32(uint32_t val, unsigned char *to, int64_t &to_len)
{
val = bswap_32(val);
to_len += sizeof(uint32_t);
MEMCPY(to, (unsigned char *)&val, sizeof(val));
return OB_SUCCESS;
}
int ObOrderPerservingEncoder::encode_from_uint(uint64_t val, unsigned char *to, int64_t &to_len)
{
val = bswap_64(val);
to_len += sizeof(uint64_t);
MEMCPY(to, (unsigned char *)&val, sizeof(val));
return OB_SUCCESS;
}
int ObOrderPerservingEncoder::encode_from_double(double val, unsigned char *to, int64_t &to_len)
{
// to avoid +0 and -0
if (val == 0.0) {
val = 0.0;
}
int64_t val_int;
to_len += sizeof(val);
MEMCPY(&val_int, &val, sizeof(val));
// int: neg pad FF, pos pad 00
val_int = (val_int ^ (val_int >> 63)) | ((~val_int) & 0x8000000000000000ULL);
val_int = bswap_64(val_int);
MEMCPY(to, &val_int, sizeof(val));
return OB_SUCCESS;
}
int ObOrderPerservingEncoder::encode_from_float(float val, unsigned char *to, int64_t &to_len)
{
// to avoid +0 and -0
if (val == 0.0) {
val = 0.0;
}
int32_t val_int;
to_len += sizeof(val);
MEMCPY(&val_int, &val, sizeof(val));
// int: neg pad FF, pos pad 00
val_int = (val_int ^ (val_int >> 31)) | ((~val_int) & 0x80000000U);
val_int = bswap_32(val_int);
MEMCPY(to, &val_int, sizeof(val));
return OB_SUCCESS;
}
int ObOrderPerservingEncoder::encode_from_number(ObNumber val,
unsigned char *to,
int64_t max_buf_len,
int64_t &to_len)
{
int ret = OB_SUCCESS;
ObNumberDesc desc = val.d_;
if (to_len + sizeof(int8_t) + desc.len_ * sizeof(uint32_t) + 2 * sizeof(int32_t) > max_buf_len) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding for obnumber", K(ret));
} else {
int8_t se = desc.se_;
// int: neg pad FF, pos pad 00
*to = se;
to_len++;
to++;
// digits encoding
int32_t digits_mask = (int64_t)((~se) ^ 0x80) >> 8;
uint32_t *digits_ptr = val.get_digits();
for (int64_t i = 0; i < desc.len_; i++) {
uint32_t dig = bswap_32((digits_ptr[i] + 1) ^ digits_mask);
MEMCPY(to, &dig, sizeof(dig));
to_len += sizeof(dig);
to += sizeof(dig);
}
MEMCPY(to, &digits_mask, sizeof(digits_mask));
to_len += sizeof(digits_mask);
to += sizeof(digits_mask);
}
return ret;
}
int ObOrderPerservingEncoder::encode_from_timestamp(ObOTimestampData val,
unsigned char *to,
int64_t &to_len)
{
int64_t time_us = val.time_us_;
uint16_t nsec = val.time_ctx_.tail_nsec_;
time_us ^= SIGN_MASK_64;
time_us = bswap_64(time_us);
MEMCPY(to + to_len, (unsigned char *)&time_us, sizeof(time_us));
to_len += sizeof(time_us);
nsec = bswap_32(nsec);
MEMCPY(to + to_len, (unsigned char *)&nsec, sizeof(nsec));
to_len += sizeof(nsec);
return OB_SUCCESS;
}
int ObOrderPerservingEncoder::encode_from_interval_ds(ObIntervalDSValue val,
unsigned char *to,
int64_t &to_len)
{
int64_t nsec = val.nsecond_;
int32_t frac_nsec = val.fractional_second_;
nsec ^= SIGN_MASK_64;
nsec = bswap_64(nsec);
MEMCPY(to + to_len, (unsigned char *)&nsec, sizeof(nsec));
to_len += sizeof(nsec);
frac_nsec ^= SIGN_MASK_32;
frac_nsec = bswap_32(frac_nsec);
MEMCPY(to + to_len, (unsigned char *)&frac_nsec, sizeof(frac_nsec));
to_len += sizeof(frac_nsec);
return OB_SUCCESS;
}
int ObSortkeyConditioner::process_key_conditioning(
ObDatum &data, unsigned char *to, int64_t max_buf_len, int64_t &to_len, ObEncParam &param)
{
int ret = OB_SUCCESS;
// process null pos
if (OB_ISNULL(to)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid arg", K(ret), K(to));
} else if (max_buf_len < 1) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding for obnumber", K(ret));
} else if (param.is_nullable_) {
if (param.is_null_first_)
*to = (param.type_ == ObNullType || data.is_null()) ? 0x00 : 0x01;
else
*to = (param.type_ == ObNullType || data.is_null()) ? 0x02 : 0x01;
to_len++;
}
if (OB_FAIL(ret)) {
// do nothing
} else if (*to != 0x01) {
// do nothing
} else if (OB_FAIL(share::ObOrderPerservingEncoder::make_order_perserving_encode_from_object(
data, to + to_len, max_buf_len, to_len, param))) {
LOG_WARN("failed to encode sortkey", K(ret));
} else if (!param.is_asc_) {
process_decrease(to + 1, to_len);
}
return ret;
}
int ObSortkeyConditioner::process_key_conditioning(ObObj &obj,
unsigned char *to,
int64_t max_buf_len,
int64_t &to_len)
{
int ret = OB_SUCCESS;
// process null pos
if (OB_ISNULL(to)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid arg", K(ret), K(to));
} else if (max_buf_len < 1) {
ret = OB_BUF_NOT_ENOUGH;
LOG_TRACE("no enough memory to do encoding for obnumber", K(ret));
} else {
*to = (obj.is_null()) ? 0x00 : 0x01;
to_len++;
}
if (OB_FAIL(ret)) {
// do nothing
} else if (*to != 0x01) {
// do nothing
} else if (OB_FAIL(share::ObOrderPerservingEncoder::make_order_perserving_encode_from_object(
obj, to + to_len, max_buf_len, to_len))) {
LOG_WARN("failed to encode sortkey", K(ret));
}
return ret;
}
// simd opt
void ObSortkeyConditioner::process_decrease(unsigned char *to, int64_t to_len)
{
for (int64_t i = 0; i < to_len; i++) {
*(to + i) ^= 0xFF;
}
}
} // namespace share
} // end namespace oceanbase