From 42864e7cdd31b77bb7c30549f124495e091c76fd Mon Sep 17 00:00:00 2001 From: Sudeep Sunthankar Date: Sat, 18 Jun 2016 18:10:53 +1000 Subject: [PATCH] Addition of sources and tests required for Cell Interface. Cell is the Interface for the underlying KeyValue structure, which can be changed based on the requirement. At the moment KeyValue structure is designed as a contiguous array of bytes. --- hbase-native-client/core/bytes.cc | 539 ++++++++++++++++++++++++++++++++++ hbase-native-client/core/bytes.h | 120 ++++++++ hbase-native-client/core/cell-test.cc | 111 +++++++ hbase-native-client/core/cell.cc | 211 +++++++++++++ hbase-native-client/core/cell.h | 76 +++++ hbase-native-client/core/exception.cc | 121 ++++++++ hbase-native-client/core/exception.h | 64 ++++ hbase-native-client/core/key_value.cc | 517 ++++++++++++++++++++++++++++++++ hbase-native-client/core/key_value.h | 215 ++++++++++++++ hbase-native-client/core/utils.cc | 43 +++ hbase-native-client/core/utils.h | 28 ++ 11 files changed, 2045 insertions(+) create mode 100644 hbase-native-client/core/bytes.cc create mode 100644 hbase-native-client/core/bytes.h create mode 100644 hbase-native-client/core/cell-test.cc create mode 100644 hbase-native-client/core/cell.cc create mode 100644 hbase-native-client/core/cell.h create mode 100644 hbase-native-client/core/exception.cc create mode 100644 hbase-native-client/core/exception.h create mode 100644 hbase-native-client/core/key_value.cc create mode 100644 hbase-native-client/core/key_value.h create mode 100644 hbase-native-client/core/utils.cc create mode 100644 hbase-native-client/core/utils.h diff --git a/hbase-native-client/core/bytes.cc b/hbase-native-client/core/bytes.cc new file mode 100644 index 0000000..3d406f8 --- /dev/null +++ b/hbase-native-client/core/bytes.cc @@ -0,0 +1,539 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * + */ +#include "bytes.h" + +#include +#include +#include + +#include "exception.h" + +/** + * Size of boolean in bytes + */ +const int Bytes::SIZEOF_BOOLEAN = sizeof(BYTE_TYPE) / sizeof(BYTE_TYPE); +/** + * Size of byte in bytes + */ +const int Bytes::SIZEOF_BYTE = Bytes::SIZEOF_BOOLEAN; +/** + * Size of char in bytes + */ +const int Bytes::SIZEOF_CHAR = sizeof(short) / sizeof(BYTE_TYPE); +/** + * Size of double in bytes + */ +const int Bytes::SIZEOF_DOUBLE = sizeof(double) / sizeof(BYTE_TYPE); +/** + * Size of float in bytes + */ +const int Bytes::SIZEOF_FLOAT = sizeof(float) / sizeof(BYTE_TYPE); +/** + * Size of int in bytes + */ +const int Bytes::SIZEOF_INT = sizeof(int) / sizeof(BYTE_TYPE); +/** + * Size of long in bytes + */ +const int Bytes::SIZEOF_LONG = sizeof(long) / sizeof(BYTE_TYPE); +/** + * Size of short in bytes + */ +const int Bytes::SIZEOF_SHORT = sizeof(short) / sizeof(BYTE_TYPE); + +const char Bytes::HEX_CHARS[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', + '9', 'a', 'b', 'c', 'd', 'e', 'f', '\0' }; + +Bytes::Bytes() + : offset_(-1), + length_(0) { + + this->byte_array_ = {}; +} + +Bytes::Bytes(const BYTE_ARRAY &bytes) + : Bytes(bytes, 0, bytes.size()) { + +} + +Bytes::Bytes(const BYTE_ARRAY &bytes, const int &offset, const int &length) { + this->byte_array_ = bytes; + this->offset_ = offset; + this->length_ = length; +} + +Bytes::Bytes(const Bytes &cbytes) { + this->byte_array_ = cbytes.byte_array_; + this->offset_ = cbytes.offset_; + this->length_ = cbytes.length_; +} + +Bytes& Bytes::operator=(const Bytes &cbytes) { + this->byte_array_ = cbytes.byte_array_; + this->offset_ = cbytes.offset_; + this->length_ = cbytes.length_; + return *this; +} + +const BYTE_ARRAY &Bytes::Get() const { + return this->byte_array_; +} + +void Bytes::Set(const BYTE_ARRAY &bytes) { + + this->Set(bytes, 0, bytes.size()); +} + +void Bytes::Set(const BYTE_ARRAY &bytes, const int &offset, const int &length) { + + this->byte_array_ = bytes; + this->offset_ = offset; + this->length_ = length; +} + +const int &Bytes::GetOffset() { + + return this->offset_; +} + +const int &Bytes::GetLength() { + + return this->length_; +} + +Bytes::~Bytes() { + // TODO Auto-generated destructor stub +} + +bool Bytes::ByteCompare(const BYTE_TYPE &left, const BYTE_TYPE &right) { + + return (left == right); +} + +void Bytes::DisplayBytes(const BYTE_ARRAY &bytes) { + + std::stringstream bytes_str; + bytes_str.str(""); + bytes_str << "Byte Array["; + for (uint i = 0; i < bytes.size(); ++i) { + bytes_str << bytes[i]; + if (i != bytes.size() - 1) + bytes_str << " "; + } + bytes_str << "]"; + DLOG(INFO)<< bytes_str.str(); + bytes_str.str(""); +} + +size_t Bytes::StrLen(const char *s) { + if (!s || NULL == s) + return 0; + else + return ::strlen(s); +} + +int Bytes::ToBytes(const std::string &str_to_bytes, BYTE_ARRAY &bytes) { + + if (str_to_bytes.size() > 0) + bytes.insert(bytes.end(), str_to_bytes.begin(), str_to_bytes.end()); + + return bytes.size(); +} + +int Bytes::ToBytes(const int &val, BYTE_ARRAY &bytes) { + + for (int i = 0, j = Bytes::SIZEOF_INT - 1; i < Bytes::SIZEOF_INT; i++, j--) { + bytes.push_back(static_cast((val >> (j * 8)) & 0xFF)); + } + return bytes.size(); +} + +int Bytes::ToBytes(const short &val, BYTE_ARRAY &bytes) { + + for (int i = 0, j = Bytes::SIZEOF_SHORT - 1; i < Bytes::SIZEOF_SHORT; + i++, j--) { + bytes.push_back(static_cast((val >> (j * 8)) & 0xFF)); + } + + return bytes.size(); +} + +int Bytes::ToBytes(const long &val, BYTE_ARRAY &bytes) { + for (int i = 0, j = Bytes::SIZEOF_LONG - 1; i < Bytes::SIZEOF_LONG; + i++, j--) { + bytes.push_back(static_cast((val >> (j * 8)) & 0xFF)); + } + return bytes.size(); +} + +int Bytes::ToString(const BYTE_ARRAY &byte, std::string &bytes_to_str) { + + if (0 == byte.size()) + bytes_to_str = ""; + else + bytes_to_str.insert(bytes_to_str.end(), byte.begin(), byte.end()); + return bytes_to_str.size(); + +} + +std::string Bytes::ToString(const BYTE_ARRAY &byte) { + + return Bytes::ToString(byte, 0, byte.size()); +} + +std::string Bytes::ToString(const BYTE_ARRAY &byte, const int &offset) { + + return Bytes::ToString(byte, offset, byte.size()); +} + +std::string Bytes::ToString(const BYTE_ARRAY &byte, const int &offset, + const int &length) { + + std::string bytes_to_str(""); + if (0 == byte.size()) + bytes_to_str = ""; + else + bytes_to_str.insert(bytes_to_str.end(), byte.begin(), byte.end()); + return bytes_to_str; +} + +bool Bytes::Equals(const BYTE_ARRAY &left, const BYTE_ARRAY &right) { + + if (left.size() != right.size()) + return false; + if (std::equal(left.begin(), left.end(), right.begin(), Bytes::ByteCompare)) + return true; + else + return false; + +} + +int Bytes::CopyByteArray(const BYTE_ARRAY &ip_bytes, BYTE_ARRAY &op_bytes, + const int &offset, const int &length) { + int ip_size = ip_bytes.size(); + + if (0 == ip_size) + throw HBaseException("Can't copy empty byte array"); + + if (offset < 0) + throw HBaseException("Offset must be >= 0"); + + if (0 == length) { + throw HBaseException("Cant copy 0 bytes"); + } + + int max_bytes_can_copy = ip_size - offset; + + if (length > max_bytes_can_copy) { + std::stringstream str_error; + str_error.str(""); + str_error << "Cant copy " << length << " bytes as only " + << max_bytes_can_copy << " can be copied." << std::endl; + throw HBaseException(str_error.str()); + } + + op_bytes.resize(length); + BYTE_ARRAY::const_iterator start_itr = ip_bytes.begin() + offset; + BYTE_ARRAY::const_iterator end_itr = start_itr + length; + std::copy(start_itr, end_itr, op_bytes.begin()); + + return op_bytes.size(); +} + +int Bytes::PutInt(BYTE_ARRAY &bytes, const int &offset, const int &val) { + + if ((bytes.size() - offset) < Bytes::SIZEOF_INT) { + std::stringstream str_error; + str_error.str(""); + str_error << "Not enough room to put an int of size " << Bytes::SIZEOF_INT + << " at offset " << offset << " in a " << bytes.size() + << " byte array."; + throw HBaseException(str_error.str()); + } + + for (int i = 0, j = Bytes::SIZEOF_INT - 1; i < Bytes::SIZEOF_INT; i++, j--) { + bytes[offset + i] = static_cast((val >> (j * 8)) & 0xFF); + } + + return offset + Bytes::SIZEOF_INT; +} + +int Bytes::PutShort(BYTE_ARRAY &bytes, const int &offset, const short &val) { + + if ((bytes.size() - offset) < Bytes::SIZEOF_SHORT) { + std::stringstream str_error; + str_error.str(""); + str_error << "Not enough room to put a short of size " + << Bytes::SIZEOF_SHORT << " at offset " << offset << " in a " + << bytes.size() << " byte array."; + throw HBaseException(str_error.str()); + } + + for (int i = 0, j = Bytes::SIZEOF_SHORT - 1; i < Bytes::SIZEOF_SHORT; + i++, j--) { + bytes[offset + i] = static_cast((val >> (j * 8)) & 0xFF); + } + + return offset + Bytes::SIZEOF_SHORT; +} + +int Bytes::PutLong(BYTE_ARRAY &bytes, const int &offset, const long &val) { + + if ((bytes.size() - offset) < Bytes::SIZEOF_LONG) { + std::stringstream str_error; + str_error.str(""); + str_error << "Not enough room to put a long of size " << Bytes::SIZEOF_LONG + << " at offset " << offset << " in a " << bytes.size() + << " byte array."; + throw HBaseException(str_error.str()); + } + + for (int i = 0, j = Bytes::SIZEOF_LONG - 1; i < Bytes::SIZEOF_LONG; + i++, j--) { + bytes[offset + i] = static_cast((val >> (j * 8)) & 0xFF); + } + + return offset + SIZEOF_LONG; +} + +int Bytes::PutByte(BYTE_ARRAY &bytes, const int &offset, const BYTE_TYPE &val) { + + if ((bytes.size() - offset) < Bytes::SIZEOF_BYTE) { + std::stringstream str_error; + str_error.str(""); + str_error << "Not enough room to put a byte of size " << Bytes::SIZEOF_BYTE + << " at offset " << offset << " in a " << bytes.size() + << " byte array."; + throw HBaseException(str_error.str()); + } + + bytes[offset] = static_cast((val)); + return offset + Bytes::SIZEOF_BYTE; +} + +int Bytes::PutBytes(BYTE_ARRAY &dst_bytes, const int &dst_offset, + const BYTE_ARRAY &src_bytes, const int &src_offset, + const int &src_num_bytes) { + + if (src_num_bytes <= 0) { + std::stringstream str_error; + str_error.str(""); + str_error << "Cant add " << src_num_bytes << std::endl; + throw HBaseException(str_error.str()); + } + if (src_num_bytes > static_cast(src_bytes.size())) { + std::stringstream str_error; + str_error.str(""); + str_error << "Cant add " << src_num_bytes + << " bytes from source byte array size of " << src_bytes.size() + << " bytes."; + throw HBaseException(str_error.str()); + } + if (static_cast(dst_bytes.size()) < src_num_bytes) { + + std::stringstream str_error; + str_error.str(""); + str_error << "Cant add " << src_num_bytes + << " bytes to destinaion byte array size of " << dst_bytes.size() + << " bytes."; + throw HBaseException(str_error.str()); + } + + BYTE_ARRAY::const_iterator start_itr = src_bytes.begin() + src_offset; + BYTE_ARRAY::const_iterator end_itr = start_itr + src_num_bytes; + BYTE_ARRAY::iterator start_dest_itr = dst_bytes.begin() + dst_offset; + std::copy(start_itr, end_itr, start_dest_itr); + + return dst_offset + src_num_bytes; +} + +int Bytes::ToInt(const BYTE_ARRAY &bytes) { + return Bytes::ToInt(bytes, 0, SIZEOF_INT); +} + +int Bytes::ToInt(const BYTE_ARRAY &bytes, const int &offset) { + return Bytes::ToInt(bytes, offset, SIZEOF_INT); + +} + +int Bytes::ToInt(const BYTE_ARRAY &bytes, const int &offset, + const int &length) { + int int_val = 0; + if (length != SIZEOF_INT + || static_cast(offset + length) > bytes.size()) { + throw "WrongLengthOrOffset"; //explainWrongLengthOrOffset(bytes, offset, length, SIZEOF_INT); + } else { + for (int i = offset, j = Bytes::SIZEOF_INT - 1; i < (offset + length); + i++, j--) { + int_val |= (bytes[i] & 0XFF) << (j * 8); + } + } + return int_val; +} + +short Bytes::ToShort(const BYTE_ARRAY &bytes) { + return Bytes::ToShort(bytes, 0, SIZEOF_SHORT); +} + +short Bytes::ToShort(const BYTE_ARRAY &bytes, const int &offset) { + return Bytes::ToShort(bytes, offset, SIZEOF_SHORT); + +} + +short Bytes::ToShort(const BYTE_ARRAY &bytes, const int &offset, + const int &length) { + short short_val = 0; + if (length != SIZEOF_SHORT + || static_cast(offset + length) > bytes.size()) { + throw "WrongLengthOrOffset"; //explainWrongLengthOrOffset(bytes, offset, length, SIZEOF_SHORT); + } else { + for (int i = offset, j = Bytes::SIZEOF_SHORT - 1; i < (offset + length); + i++, j--) { + short_val |= (bytes[i] & 0XFF) << (j * 8); + } + } + return short_val; +} + +long Bytes::ToLong(const BYTE_ARRAY &bytes) { + return Bytes::ToLong(bytes, 0, SIZEOF_LONG); +} + +long Bytes::ToLong(const BYTE_ARRAY &bytes, const int &offset) { + return Bytes::ToLong(bytes, offset, SIZEOF_LONG); + +} + +long Bytes::ToLong(const BYTE_ARRAY &bytes, const int &offset, + const int &length) { + + long long_val = 0L; + if (length != SIZEOF_LONG + || static_cast(offset + length) > bytes.size()) { + throw "WrongLengthOrOffset"; //explainWrongLengthOrOffset(bytes, offset, length, SIZEOF_SHORT); + } else { + for (int i = offset, j = Bytes::SIZEOF_LONG - 1; i < (offset + length); + i++, j--) { + long_val <<= 8; + long_val ^= bytes[i] & 0xFF; + } + } + /*const char *pCurrent = &bytes[offset]; + PocoXXXX::UInt64 *pts = (PocoXXXX::UInt64*) pCurrent; + long_val = *pts; + long_val = PocoXXXX::ByteOrder::flipBytes(long_val); + */ + return long_val; +} + +unsigned long Bytes::ToULong(const BYTE_ARRAY &bytes) { + return Bytes::ToULong(bytes, 0, SIZEOF_LONG); +} + +unsigned long Bytes::ToULong(const BYTE_ARRAY &bytes, const int &offset) { + return Bytes::ToULong(bytes, offset, SIZEOF_LONG); + +} + +unsigned long Bytes::ToULong(const BYTE_ARRAY &bytes, const int &offset, + const int &length) { + + unsigned long long_val = 0L; + //const char *pCurrent = &bytes[offset]; + if (length != SIZEOF_LONG + || static_cast(offset + length) > bytes.size()) { + throw "WrongLengthOrOffset"; //explainWrongLengthOrOffset(bytes, offset, length, SIZEOF_SHORT); + } else { + for (int i = offset, j = Bytes::SIZEOF_LONG - 1; i < (offset + length); + i++, j--) { + long_val <<= 8; + long_val ^= bytes[i] & 0xFF; + } + } + /* + DLOG(INFO)<< "SIZEOF_LONG is " << SIZEOF_LONG; + + DLOG(INFO)<< "long_val_tmp is " << long_val_tmp; + + PocoXXXX::UInt64 *pts = (PocoXXXX::UInt64*) pCurrent; + long_val = *pts; + long_val = PocoXXXX::ByteOrder::flipBytes(long_val); + DLOG(INFO)<< "long_val is " << long_val; + */ + return long_val; +} + +std::string Bytes::ToHex(const BYTE_ARRAY &bytes) { + return Bytes::ToHex(bytes, 0, bytes.size()); +} + +std::string Bytes::ToHex(const BYTE_ARRAY &bytes, const int &offset, + const int &length) { + + if (length > (std::numeric_limits::max() / 2)) { + + throw HBaseException( + "Illegal Argument Exception while converting byte array to hex, Check the length passed"); + } + + int num_chars = length * 2; + std::string hex_str; + hex_str.resize(num_chars); + for (int i = 0; i < num_chars; i += 2) { + BYTE_TYPE d = bytes[offset + i / 2]; + hex_str[i] = HEX_CHARS[(d >> 4) & 0x0F]; + hex_str[i + 1] = HEX_CHARS[d & 0x0F]; + } + return hex_str; +} + +BYTE_ARRAY Bytes::ToBytes(const char *charstr_to_bytes) { + + std::string str_to_bytes(""); + if (nullptr != charstr_to_bytes) + str_to_bytes = charstr_to_bytes; + return Bytes::ToBytes(str_to_bytes); +} + +BYTE_ARRAY Bytes::ToBytes(const std::string &str_to_bytes, const bool &change_case_tolower) { + + BYTE_ARRAY bytes; + if (str_to_bytes.size() > 0){ + if(change_case_tolower){ + std::string lower_str = str_to_bytes; + std::transform(lower_str.begin(), lower_str.end(), lower_str.begin(), ::tolower); + bytes.insert(bytes.end(), lower_str.begin(), lower_str.end()); + }else{ + bytes.insert(bytes.end(), str_to_bytes.begin(), str_to_bytes.end()); + } + } + + return bytes; +} + +BYTE_ARRAY Bytes::ToBytes(const bool &val) { + + BYTE_ARRAY bytes; + for (int i = 0, j = Bytes::SIZEOF_BOOLEAN; i < Bytes::SIZEOF_BOOLEAN; + i++, j--) { + bytes.push_back(static_cast((val >> (j * 8)) & 0xFF)); + } + + return bytes; +} diff --git a/hbase-native-client/core/bytes.h b/hbase-native-client/core/bytes.h new file mode 100644 index 0000000..16952de --- /dev/null +++ b/hbase-native-client/core/bytes.h @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include + +using byte = char; +using BYTE_TYPE = char; +using BYTE_ARRAY = std::vector; +using ByteBuffer = std::vector; + +class Bytes { + public: + + static const int SIZEOF_BOOLEAN; + static const int SIZEOF_BYTE; + static const int SIZEOF_CHAR; + static const int SIZEOF_DOUBLE; + static const int SIZEOF_FLOAT; + static const int SIZEOF_INT; + static const int SIZEOF_LONG; + static const int SIZEOF_SHORT; + static const char HEX_CHARS[]; + + Bytes(); + Bytes(const Bytes &bytes); + Bytes& operator= (const Bytes &bytes); + + Bytes(const BYTE_ARRAY &bytes); + Bytes(const BYTE_ARRAY &bytes, const int &offset, const int &length); + const BYTE_ARRAY &Get() const; + void Set(const BYTE_ARRAY &bytes); + void Set(const BYTE_ARRAY &bytes, const int &offset, const int &length); + const int &GetOffset(); + const int &GetLength(); + + virtual ~Bytes(); + + static void DisplayBytes(const BYTE_ARRAY &bytes); + static size_t StrLen(const char *); + + static BYTE_ARRAY ToBytes(const std::string &val, const bool &change_case_tolower = false); + static BYTE_ARRAY ToBytes(const char *charstr_to_bytes); + static BYTE_ARRAY ToBytes(const bool &val); + + + static int ToBytes(const std::string &val, BYTE_ARRAY &bytes); + static int ToBytes(const int &val, BYTE_ARRAY &bytes); + static int ToBytes(const short &val, BYTE_ARRAY &bytes); + static int ToBytes(const long &val, BYTE_ARRAY &bytes); + + static int ToString(const BYTE_ARRAY &byte, std::string &bytes_to_str); + static std::string ToString(const BYTE_ARRAY &byte); + static std::string ToString(const BYTE_ARRAY &bytes, const int &offset); + static std::string ToString(const BYTE_ARRAY &byte, const int &offset, const int &length); + static char ToByte(const BYTE_ARRAY &bytes); + + static int ToInt(const BYTE_ARRAY &bytes); + static int ToInt(const BYTE_ARRAY &bytes, const int &offset); + static int ToInt(const BYTE_ARRAY &bytes, const int &offset, const int &length); + + static short ToShort(const BYTE_ARRAY &bytes); + static short ToShort(const BYTE_ARRAY &bytes, const int &offset); + static short ToShort(const BYTE_ARRAY &bytes, const int &offset, const int &length); + + static long ToLong(const BYTE_ARRAY &bytes); + static long ToLong(const BYTE_ARRAY &bytes, const int &offset); + static long ToLong(const BYTE_ARRAY &bytes, const int &offset, const int &length); + + static unsigned long ToULong(const BYTE_ARRAY &bytes); + static unsigned long ToULong(const BYTE_ARRAY &bytes, const int &offset); + static unsigned long ToULong(const BYTE_ARRAY &bytes, const int &offset, const int &length); + + static float ToFloat(const BYTE_ARRAY &bytes); + static double ToDouble(const BYTE_ARRAY &bytes); + + static std::string ToHex(const BYTE_ARRAY &bytes); + static std::string ToHex(const BYTE_ARRAY &bytes, const int &offset, const int &length); + + static int PutInt(BYTE_ARRAY &bytes, const int &offset, const int &val); + static int PutShort(BYTE_ARRAY &bytes, const int &offset, const short &val); + static int PutLong(BYTE_ARRAY &bytes, const int &offset, const long &val); + static int PutByte(BYTE_ARRAY &bytes, const int &offset, const BYTE_TYPE &val); + static int PutBytes(BYTE_ARRAY &bytes, const int &from_index, const BYTE_ARRAY &bytes_to_put, + const int &offset, const int &num_bytes); + + + static bool Equals(const BYTE_ARRAY &left, const BYTE_ARRAY &right); + static int CopyByteArray( const BYTE_ARRAY &ip_bytes, BYTE_ARRAY &op_bytes, + const int &offset, const int &length); + private: + static bool ByteCompare(const BYTE_TYPE &left, const BYTE_TYPE &right); + + BYTE_ARRAY byte_array_; + int offset_; + int length_; +}; diff --git a/hbase-native-client/core/cell-test.cc b/hbase-native-client/core/cell-test.cc new file mode 100644 index 0000000..60f5557 --- /dev/null +++ b/hbase-native-client/core/cell-test.cc @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * + */ + +#include +#include + +#include "core/cell.h" +#include "core/bytes.h" + +using namespace hbase; + +TEST (CellTest, CellFailureTest) { + + std::string row = "row"; + std::string family = "family"; + std::string column = "column"; + std::string value = "value"; + long timestamp = std::numeric_limits::max(); + std::string tags = ""; + hbase::pb::CellType cell_type = hbase::pb::CellType::PUT; + + Cell cell(row, family, column, timestamp, value, tags, cell_type); + cell.Display(); + + EXPECT_NE("row-value", cell.Row()); + EXPECT_NE("family-value", cell.Family()); + EXPECT_NE("column-value", cell.Qualifier()); + EXPECT_NE("value-value", cell.Value()); + EXPECT_NE(1234567890, cell.Timestamp()); + EXPECT_NE(hbase::pb::CellType::MAXIMUM, cell.TypeByte()); + +} + +TEST (CellTest, CellSuceessTest) { + + std::string row = "row-value"; + std::string family = "family-value"; + std::string column = "column-value"; + std::string value = "value-value"; + long timestamp = std::numeric_limits::max(); + std::string tags = ""; + hbase::pb::CellType cell_type = hbase::pb::CellType::PUT; + + Cell cell(row, family, column, timestamp, value, tags, cell_type); + cell.Display(); + + EXPECT_EQ(row, cell.Row()); + EXPECT_EQ(family, cell.Family()); + EXPECT_EQ(column, cell.Qualifier()); + EXPECT_EQ(value, cell.Value()); + EXPECT_EQ(timestamp, cell.Timestamp()); + EXPECT_EQ(cell_type, cell.TypeByte()); + +} + +TEST (CellTest, MultipleCellsTest) { + + std::vector cells; + for (int i = 0; i < 5; i++) { + std::string row = "row-value"; + std::string family = "family-value"; + std::string column = "column-value"; + std::string value = "value-value"; + long timestamp = std::numeric_limits::max(); + std::string tags = ""; + row += std::to_string(i); + value += std::to_string(i); + + hbase::pb::CellType cell_type = hbase::pb::CellType::PUT; + + Cell *cell = new Cell(row, family, column, timestamp, value, tags, + cell_type); + cells.push_back(cell); + } + int i = 0; + for (auto cell : cells) { + cell->Display(); + std::string row = "row-value"; + std::string value = "value-value"; + row += std::to_string(i); + value += std::to_string(i); + EXPECT_EQ(row, cell->Row()); + EXPECT_EQ("family-value", cell->Family()); + EXPECT_EQ("column-value", cell->Qualifier()); + EXPECT_EQ(value, cell->Value()); + EXPECT_EQ(std::numeric_limits::max(), cell->Timestamp()); + EXPECT_EQ(hbase::pb::CellType::PUT, cell->TypeByte()); + i += 1; + } + for (auto cell : cells) { + delete cell; + } + cells.clear(); + +} diff --git a/hbase-native-client/core/cell.cc b/hbase-native-client/core/cell.cc new file mode 100644 index 0000000..927afcb --- /dev/null +++ b/hbase-native-client/core/cell.cc @@ -0,0 +1,211 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * + */ + +#include "cell.h" +#include +#include +#include "utils.h" + +const long Cell::LATEST_TIMESTAMP = std::numeric_limits::max(); +const BYTE_ARRAY Cell::EMPTY_BYTE_ARRAY { }; + +Cell::~Cell() { + +} + +Cell::Cell(const std::string &row, const std::string &family, + const std::string &column, const long ×tamp, + const std::string &value, const std::string &tags, + const hbase::pb::CellType &cellType):KeyValue( + Bytes::ToBytes(row), Bytes::ToBytes(family), + (0 == column.length() ? Cell::EMPTY_BYTE_ARRAY : Bytes::ToBytes(column)), + timestamp, static_cast(cellType), + (0 == value.length() ? Cell::EMPTY_BYTE_ARRAY : Bytes::ToBytes(value))) { + +} + +Cell::Cell(const Cell &cell) { + +} + +Cell& Cell::operator=(const Cell &cell) { + +} + +void Cell::Display() { + LOG(INFO)<< "Cell Contents: " + << " Row: " << Row() + << "; Family: " << Family() + << "; Qualifer: " << Qualifier() + << "; Value: " << Value() + << "; Timestamp: " << Timestamp() + << "; CellType: " << TypeByte(); +} + +const hbase::pb::CellType Cell::TypeByte() { + return static_cast(static_cast(KeyValue::GetTypeByte())); +} + +const std::string Cell::Row() { + BYTE_ARRAY tmp_rowbytes; + Bytes::CopyByteArray(KeyValue::GetRowArray(), tmp_rowbytes, + GetRowOffset(), + GetRowLength()); + return Bytes::ToString(tmp_rowbytes); +} + +const std::string Cell::Family() { + BYTE_ARRAY tmp_fambytes; + Bytes::CopyByteArray(KeyValue::GetFamilyArray(), tmp_fambytes, + GetFamilyOffset(), + GetFamilyLength()); + return Bytes::ToString(tmp_fambytes); +} + +const std::string Cell::Qualifier() { + BYTE_ARRAY tmp_qualbytes; + Bytes::CopyByteArray(KeyValue::GetQualifierArray(), tmp_qualbytes, + GetQualifierOffset(), + GetQualifierLength()); + return Bytes::ToString(tmp_qualbytes); +} + +const std::string Cell::Value() { + BYTE_ARRAY tmp_valbytes; + Bytes::CopyByteArray(KeyValue::GetValueArray(), tmp_valbytes, + GetValueOffset(), + GetValueLength()); + return Bytes::ToString(tmp_valbytes); +} + +const long Cell::Timestamp() { + return KeyValue::GetTimestamp(); +} + +Cell* Cell::CreateCell(const BYTE_ARRAY &bytes) { + + KeyValue *key_value = new KeyValue(bytes); + + BYTE_ARRAY tmp_rowbytes; + if (key_value->GetRowLength()) + Bytes::CopyByteArray(key_value->GetRowArray(), tmp_rowbytes, + key_value->GetRowOffset(), key_value->GetRowLength()); + + BYTE_ARRAY tmp_fambytes; + if (key_value->GetFamilyLength()) + Bytes::CopyByteArray(key_value->GetFamilyArray(), tmp_fambytes, + key_value->GetFamilyOffset(), + key_value->GetFamilyLength()); + + BYTE_ARRAY tmp_qualbytes; + if (key_value->GetQualifierLength()) + Bytes::CopyByteArray(key_value->GetQualifierArray(), tmp_qualbytes, + key_value->GetQualifierOffset(), + key_value->GetQualifierLength()); + + BYTE_ARRAY tmp_valbytes; + if (key_value->GetValueLength()) + Bytes::CopyByteArray(key_value->GetValueArray(), tmp_valbytes, + key_value->GetValueOffset(), + key_value->GetValueLength()); + + long timestamp = key_value->GetTimestamp(); + unsigned int key_type = static_cast(key_value->GetTypeByte()); + hbase::pb::CellType cell_type = static_cast(key_type); + std::string tags(""); + delete key_value; + + Cell *cell = new Cell(Bytes::ToString(tmp_rowbytes), + Bytes::ToString(tmp_fambytes), + Bytes::ToString(tmp_qualbytes), timestamp, + Bytes::ToString(tmp_valbytes), tags, cell_type); + + DLOG(INFO)<< "row: " << Bytes::ToHex(tmp_rowbytes); + DLOG(INFO)<< "family: " << Bytes::ToHex(tmp_fambytes); + DLOG(INFO)<< "quaifier: " << Bytes::ToHex(tmp_qualbytes); + DLOG(INFO)<< "timestamp: " << timestamp; + DLOG(INFO)<< "value: " << Bytes::ToHex(tmp_valbytes); + DLOG(INFO)<< "cell_type: " << cell_type; + + return cell; +} + +const KeyValue* Cell::GetKeyValue() const { + + return nullptr;//this->key_value_; +} + +Cell* Cell::Parse(ByteBuffer &cell_data) { + + DLOG(INFO)<< "cell_data.size() = " << cell_data.size(); + DLOG(INFO) << "cell_data: " << Bytes::ToHex(cell_data); + int offset = 0; + unsigned int cell_size_length; + const char *pCurrent = &cell_data[offset]; + unsigned int *pSize = (unsigned int*) pCurrent; + cell_size_length = *pSize; + CommonUtils::SwapByteOrder(cell_size_length); + pCurrent += Bytes::SIZEOF_INT; + offset += Bytes::SIZEOF_INT; + DLOG(INFO) << "cell_size: " << cell_size_length; + + BYTE_ARRAY bytes; + bytes.insert(bytes.end(), pCurrent, pCurrent + cell_size_length); + return Cell::CreateCell(bytes); +} + +const int Cell::GetRowOffset() { + return KeyValue::GetRowOffset(); +} + +const short Cell::GetRowLength() { + return KeyValue::GetRowLength(); +} + +const int Cell::GetFamilyOffset() { + return KeyValue::GetFamilyOffset(); +} + +const BYTE_TYPE Cell::GetFamilyLength() { + return KeyValue::GetFamilyLength(); +} + +const int Cell::GetQualifierOffset() { + return KeyValue::GetQualifierOffset(); +} + +const int Cell::GetQualifierLength() { + return KeyValue::GetQualifierLength(); +} + +const int Cell::GetValueOffset() { + return KeyValue::GetValueOffset(); +} + +const int Cell::GetValueLength() { + return KeyValue::GetValueLength(); +} + +const long &Cell::GetSequenceId() const { + return KeyValue::GetSequenceId(); +} + +void Cell::SetSequenceId(const long &seq_id){ + KeyValue::SetSequenceId(seq_id); +} diff --git a/hbase-native-client/core/cell.h b/hbase-native-client/core/cell.h new file mode 100644 index 0000000..5b7681a --- /dev/null +++ b/hbase-native-client/core/cell.h @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * + */ + +#pragma once + +#include + +#include "bytes.h" +#include "key_value.h" +#include "if/Cell.pb.h" + +class Cell : public KeyValue{ + + public: + /** + * Timestamp to use when we want to refer to the latest cell. + * This is the timestamp sent by clients when no timestamp is specified on + * commit. + */ + static const long LATEST_TIMESTAMP; + /** + * An empty instance. + */ + static const BYTE_ARRAY EMPTY_BYTE_ARRAY; + Cell(const std::string &row, const std::string &family, + const std::string &qualifier, const long ×tamp, + const std::string &value, const std::string &tags, + const hbase::pb::CellType &cellType); + Cell(const Cell &cell); + Cell& operator=(const Cell &cell); + + virtual ~Cell(); + + void Display(); + const std::string Row(); + const int GetRowOffset(); + const short GetRowLength(); + + const std::string Family(); + const int GetFamilyOffset(); + const BYTE_TYPE GetFamilyLength(); + + const std::string Qualifier(); + const int GetQualifierOffset(); + const int GetQualifierLength(); + + const std::string Value(); + const int GetValueOffset(); + const int GetValueLength(); + + const hbase::pb::CellType TypeByte(); + const long Timestamp(); + + const KeyValue *GetKeyValue() const; + static Cell *CreateCell(const BYTE_ARRAY &bytes); + static Cell * Parse(ByteBuffer &cell_data); + + const long &GetSequenceId() const; + void SetSequenceId(const long &seq_id); +}; diff --git a/hbase-native-client/core/exception.cc b/hbase-native-client/core/exception.cc new file mode 100644 index 0000000..a35d839 --- /dev/null +++ b/hbase-native-client/core/exception.cc @@ -0,0 +1,121 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * + */ + + +#include "exception.h" +#include + +const HBaseException::EXCEPTIONLIST_MAP HBaseException::EXCEPTIONS = HBaseException::GetExceptionList(); + +HBaseException::EXCEPTIONLIST_MAP HBaseException::GetExceptionList() { + + EXCEPTIONLIST_MAP exc_list; + exc_list.insert(EXCEPTIONLIST_PAIR("org.apache.hadoop.hbase.NotServingRegionException:", + HBaseException::HBASEERRCODES::ERR_REGION_SERVER_NOT_SERVING)); + exc_list.insert(EXCEPTIONLIST_PAIR("org.apache.hadoop.hbase.exceptions.RegionMovedException:", + HBaseException::HBASEERRCODES::ERR_REGION_MOVED)); + return exc_list; +} + +const HBaseException::RETRY_EXCEPTIONLIST_MAP HBaseException::RETRY_EXCEPTIONS = HBaseException::GetRetryExceptionList(); + +HBaseException::RETRY_EXCEPTIONLIST_MAP HBaseException::GetRetryExceptionList() { + + RETRY_EXCEPTIONLIST_MAP retry_list; + retry_list.insert(RETRY_EXCEPTIONLIST_PAIR(HBaseException::HBASEERRCODES::ERR_REGION_SERVER_NOT_SERVING, false)); + retry_list.insert(RETRY_EXCEPTIONLIST_PAIR(HBaseException::HBASEERRCODES::ERR_REGION_MOVED, true)); + return retry_list; +} + +HBaseException::HBaseException(const std::string &error, bool stack_trace): error_(error), + stack_trace_(""), + show_stack_trace_(false), + retry_(false), + err_code_(HBaseException::HBASEERRCODES::ERR_UNKNOWN), + retry_count_(0){ + + if (stack_trace) { + this->stack_trace_ = error; + } + + size_t pos = this->error_.find("at "); + if (std::string::npos != pos){ + this->error_.erase(pos); + } + + for (const auto exception : EXCEPTIONS) { + pos = this->stack_trace_.find(exception.first); + if (std::string::npos != pos){ + this->err_code_ = exception.second; + try { + this->retry_ = RETRY_EXCEPTIONS.at(this->err_code_); + } catch(const std::out_of_range &oor) { + //By default no retries. + this->retry_ = false; + DLOG(WARNING) << "Can't find definition of the occured exception. No retries will ever occur:- " << this->stack_trace_; + } + + break; + } + + } + + this->error_ += "\n"; + this->stack_trace_ += "\n"; +} + +HBaseException::~HBaseException() { + // TODO Auto-generated destructor stub +} + +const char *HBaseException::what() const throw() { + + if (ShowStackTrace()) + return StackTrace(); + + else + return this->error_.c_str(); +} + +const char *HBaseException::StackTrace() const { + + return this->stack_trace_.c_str(); +} + +const bool &HBaseException::ShowStackTrace() const { + + return this->show_stack_trace_; +} + +void HBaseException::SetStackTrace(const bool &show_stack_trace) { + + this->show_stack_trace_ = show_stack_trace; +} + +const HBaseException::HBASEERRCODES &HBaseException::GetHBaseErrorCode() const { + + return this->err_code_; +} + +const bool &HBaseException::RetryException() const { + + return this->retry_; +} + + diff --git a/hbase-native-client/core/exception.h b/hbase-native-client/core/exception.h new file mode 100644 index 0000000..ea1761c --- /dev/null +++ b/hbase-native-client/core/exception.h @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * + */ + +#pragma once +#include +#include +#include + +class HBaseException : public std::exception { + + public: + + enum class HBASEERRCODES{ + ERR_REGION_SERVER_NOT_SERVING, + ERR_REGION_MOVED, + ERR_UNKNOWN + }; + + using EXCEPTIONLIST_MAP = std::map; + using EXCEPTIONLIST_PAIR = std::pair; + using RETRY_EXCEPTIONLIST_MAP = std::map; + using RETRY_EXCEPTIONLIST_PAIR = std::pair; + HBaseException(const std::string &error, bool stack_trace = false); + virtual ~HBaseException(); + virtual const char *what () const throw(); + static RETRY_EXCEPTIONLIST_MAP GetRetryExceptionList(); + static EXCEPTIONLIST_MAP GetExceptionList(); + void SetStackTrace(const bool &show_stack_trace); + const HBaseException::HBASEERRCODES &GetHBaseErrorCode() const; + const bool &RetryException() const; + + + + private: + + static const RETRY_EXCEPTIONLIST_MAP RETRY_EXCEPTIONS; + static const EXCEPTIONLIST_MAP EXCEPTIONS; + const char *StackTrace () const; + const bool &ShowStackTrace() const; + + std::string error_; + std::string stack_trace_; + bool show_stack_trace_; + bool retry_; + HBaseException::HBASEERRCODES err_code_; + mutable int retry_count_; +}; + diff --git a/hbase-native-client/core/key_value.cc b/hbase-native-client/core/key_value.cc new file mode 100644 index 0000000..26d814e --- /dev/null +++ b/hbase-native-client/core/key_value.cc @@ -0,0 +1,517 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * + */ + +#include "key_value.h" + +#include +#include +#include + +const byte KeyValue::COLUMN_FAMILY_DELIMITER = ':'; + +const int KeyValue::KEY_LENGTH_SIZE = Bytes::SIZEOF_INT; + + +const int KeyValue::ROW_LENGTH_SIZE = Bytes::SIZEOF_SHORT; +const int KeyValue::FAMILY_LENGTH_SIZE = Bytes::SIZEOF_BYTE; +const int KeyValue::TIMESTAMP_SIZE = Bytes::SIZEOF_LONG; +const int KeyValue::TYPE_SIZE = Bytes::SIZEOF_BYTE; +const int KeyValue::TIMESTAMP_TYPE_SIZE = TIMESTAMP_SIZE + TYPE_SIZE; +const int KeyValue::KEY_INFRASTRUCTURE_SIZE = ROW_LENGTH_SIZE + FAMILY_LENGTH_SIZE + TIMESTAMP_TYPE_SIZE; + +const int KeyValue::VALUE_LENGTH_SIZE = Bytes::SIZEOF_INT; +const int KeyValue::KEYVALUE_INFRASTRUCTURE_SIZE = KeyValue::KEY_LENGTH_SIZE /*keylength*/ + KeyValue::VALUE_LENGTH_SIZE /*valuelength*/; + +const int KeyValue::ROW_OFFSET = KeyValue::KEYVALUE_INFRASTRUCTURE_SIZE; +const int KeyValue::ROW_KEY_OFFSET = ROW_OFFSET + ROW_LENGTH_SIZE; + +const int KeyValue::TAGS_LENGTH_SIZE = Bytes::SIZEOF_SHORT; +const int KeyValue::KEYVALUE_WITH_TAGS_INFRASTRUCTURE_SIZE = ROW_OFFSET + TAGS_LENGTH_SIZE; + +const BYTE_ARRAY KeyValue::EMPTY_BYTE_ARRAY {}; +const long KeyValue::LATEST_TIMESTAMP = std::numeric_limits< long >::max(); + +KeyValue::KeyValue():offset_(-1), length_(-1), seqid_(0) { + +} + +KeyValue::KeyValue(const KeyValue& ckey_value) { + + //DLOG(INFO) << "KV::Copy Constr"; + this->offset_ = ckey_value.offset_; + this->length_ = ckey_value.length_; + Bytes::CopyByteArray(ckey_value.bytes_, this->bytes_, this->offset_, this->length_); + this->seqid_ = ckey_value.seqid_; +} + +KeyValue& KeyValue::operator= (const KeyValue &ckey_value) { + + //DLOG(INFO) << "KV::Assign Constr" ; + this->offset_ = ckey_value.offset_; + this->length_ = ckey_value.length_; + Bytes::CopyByteArray(ckey_value.bytes_, this->bytes_, this->offset_, this->length_); + this->seqid_ = ckey_value.seqid_; + + return *this; + +} + +KeyValue::KeyValue(const BYTE_ARRAY &bytes): KeyValue(bytes, 0) { + +} + +KeyValue::KeyValue(const BYTE_ARRAY &bytes, const int &offset):KeyValue(bytes, offset, GetLength(bytes, offset)) { + +} + +KeyValue::KeyValue( const BYTE_ARRAY &bytes, const int &offset, const int &length):offset_(offset), length_(length), seqid_(0) { + + Bytes::CopyByteArray(bytes, this->bytes_, this->offset_, this->length_); +} + + +KeyValue::KeyValue(const BYTE_ARRAY &bytes, const int &offset, const int &length, const long &ts): + KeyValue(bytes, offset, length, KeyValue::EMPTY_BYTE_ARRAY, 0, 0, KeyValue::EMPTY_BYTE_ARRAY, 0, 0, ts, + static_cast(KeyValue::KEY_TYPE::Maximum), KeyValue::EMPTY_BYTE_ARRAY, 0, 0){//, null_tags_) { + +} + + +KeyValue::KeyValue(const BYTE_ARRAY &row, const long ×tamp): + KeyValue(row, KeyValue::EMPTY_BYTE_ARRAY, KeyValue::EMPTY_BYTE_ARRAY, timestamp, static_cast(KeyValue::KEY_TYPE::Maximum), KeyValue::EMPTY_BYTE_ARRAY) { + +} + +KeyValue::KeyValue(const BYTE_ARRAY &row, const long ×tamp, const BYTE_TYPE &type): + KeyValue(row, KeyValue::EMPTY_BYTE_ARRAY, KeyValue::EMPTY_BYTE_ARRAY, timestamp, type, KeyValue::EMPTY_BYTE_ARRAY) { + +} + +KeyValue::KeyValue(const BYTE_ARRAY &row, const BYTE_ARRAY &family, const BYTE_ARRAY &qualifier): + KeyValue(row, family, qualifier, KeyValue::LATEST_TIMESTAMP, static_cast(KeyValue::KEY_TYPE::Maximum)) { + +} + +KeyValue::KeyValue( const BYTE_ARRAY &row, const BYTE_ARRAY &family, const BYTE_ARRAY &qualifier, + const BYTE_ARRAY &value): + KeyValue(row, family, qualifier, + KeyValue::LATEST_TIMESTAMP, static_cast(KeyValue::KEY_TYPE::Put), value) { + + +} + +KeyValue::KeyValue( const BYTE_ARRAY &row, const BYTE_ARRAY &family, const BYTE_ARRAY &qualifier, + const long ×tamp, const BYTE_TYPE &type): + KeyValue(row, family, qualifier, timestamp, type, KeyValue::EMPTY_BYTE_ARRAY) { + +} + +KeyValue::KeyValue( const BYTE_ARRAY &row, const BYTE_ARRAY &family, const BYTE_ARRAY &qualifier, + const long ×tamp, const BYTE_ARRAY &value):KeyValue(row, family, qualifier, + timestamp, static_cast(KeyValue::KEY_TYPE::Put), value) { + +} +/* +KeyValue::KeyValue( const BYTE_ARRAY &row, const BYTE_ARRAY &family, const BYTE_ARRAY &qualifier, + const long ×tamp, const BYTE_ARRAY &value, const Tag *tag_ptr): + KeyValue(row, family, qualifier, timestamp, value, null_tags_){ + +} + +KeyValue::KeyValue( const BYTE_ARRAY &row, const BYTE_ARRAY &family, const BYTE_ARRAY &qualifier, + const long ×tamp, const BYTE_ARRAY &value, const std::vector &tags): + KeyValue( row, 0, row.size(), family, 0, family.size(), qualifier, 0, qualifier.size(), + timestamp, static_cast(KeyValue::KEY_TYPE::Put), value, 0, value.size(), tags) { + +} +*/ +KeyValue::KeyValue( const BYTE_ARRAY &row, const BYTE_ARRAY &family, const BYTE_ARRAY &qualifier, + const long ×tamp, const BYTE_TYPE &type, const BYTE_ARRAY &value): + KeyValue(row, 0, row.size(), family, 0, family.size(), qualifier, 0, qualifier.size(), timestamp, type, value, 0, value.size()) { + +} + +/* +KeyValue::KeyValue( const BYTE_ARRAY &row, const BYTE_ARRAY &family, const BYTE_ARRAY &qualifier, + const long ×tamp, const BYTE_TYPE &type, const BYTE_ARRAY &value, const std::vector &tags): + offset_(-1), length_(-1), seqid_(0) { + + KeyValue( row, family, qualifier, 0, qualifier.size(), timestamp, type, value, 0, value.size(), tags); +} +*/ + +/* +KeyValue::KeyValue( const BYTE_ARRAY &row, const BYTE_ARRAY &family, const BYTE_ARRAY &qualifier, + const int &qoffset, const int &qlength, const long ×tamp, + const BYTE_TYPE &type, const BYTE_ARRAY &value, const int &voffset, + const int &vlength, const std::vector &tags):offset_(-1), length_(-1), seqid_(0) { + KeyValue(row, 0, row.size(), family, 0, family.size(), qualifier, qoffset, qlength, timestamp, type, value, voffset, vlength, tags); + +} +*/ +/* +KeyValue::KeyValue( const BYTE_ARRAY &row, const BYTE_ARRAY &family, const BYTE_ARRAY &qualifier, + const long ×tamp, const BYTE_TYPE &type, const BYTE_ARRAY &value, + const BYTE_ARRAY &tag_bytes): + KeyValue(row, family, qualifier, 0, qualifier.size(), timestamp, type, value, 0, value.size()), null_tags_) { + +} +*/ +KeyValue::KeyValue( BYTE_ARRAY &buffer, const int &boffset, + const BYTE_ARRAY &row, const int &roffset, const int &rlength, + const BYTE_ARRAY &family, const int &foffset, const int &flength, + const BYTE_ARRAY &qualifier, const int &qoffset, const int &qlength, + const long ×tamp, const BYTE_TYPE &type, + const BYTE_ARRAY &value, const int &voffset, const int &vlength, + const BYTE_ARRAY &tag_bytes):offset_(-1), length_(-1), seqid_(0) { + +} + +KeyValue::KeyValue( const BYTE_ARRAY &row, const int &row_offset, const int &row_length, + const BYTE_ARRAY &family, const int &family_offset, const int &family_length, + const BYTE_ARRAY &qualifier, const int &qualifier_offset, const int &qualifier_length, + const long ×tamp, const BYTE_TYPE &type, + const BYTE_ARRAY &value, const int &value_offset, const int &value_length, + const BYTE_ARRAY &tag_bytes, const int &tagsOffset, const int &tagsLength):offset_(-1), length_(-1), seqid_(0){ + + + this->length_ = CreateByteArray( this->bytes_, row, row_offset, row_length, + family, family_offset, family_length, + qualifier, qualifier_offset, qualifier_length, + timestamp, type, value, value_offset, value_length, tag_bytes, tagsOffset, tagsLength); + this->offset_ = 0; +} + +KeyValue::KeyValue( const int &rlength, const int &flength, const int &qlength, const long ×tamp, const BYTE_TYPE &type, + const int &vlength):offset_(-1), length_(-1), seqid_(0) { + KeyValue(rlength, flength, qlength, timestamp, type, vlength, 0); +} + +KeyValue::KeyValue( const int &rlength, const int &flength, const int &qlength, + const long ×tamp, const BYTE_TYPE &type, const int &vlength, + const int &tags_length):offset_(-1), length_(-1), seqid_(0) { + +} + +KeyValue::KeyValue( const BYTE_ARRAY &row, const int &roffset, const int &rlength, + const BYTE_ARRAY &family, const int &foffset, const int &flength, + const BYTE_ARRAY &qualifier, const int &qoffset, const int &qlength, + const long ×tamp, const BYTE_TYPE &type, + const BYTE_ARRAY &value, const int &voffset, const int &vlength):offset_(-1), length_(-1), seqid_(0) + /*KeyValue( row, roffset, rlength, family, foffset, flength, qualifier, + qoffset, qlength, timestamp, type, value, voffset, vlength, null_tags_)*/{ + + //Bytes::DisplayBytes(this->bytes_); + this->length_ = CreateByteArray( this->bytes_, row, roffset, rlength, + family, foffset, flength, + qualifier, qoffset, qlength, + timestamp, type, value, voffset, vlength, KeyValue::EMPTY_BYTE_ARRAY, 0, 0); + this->offset_ = 0; +} +/* +KeyValue::KeyValue( const BYTE_ARRAY &row, const int &row_offset, const int &row_length, + const BYTE_ARRAY &family, const int &family_offset, const int &family_length, + const BYTE_ARRAY &qualifier, const int &qualifier_offset, const int &qualifier_length, + const long ×tamp, const BYTE_TYPE &type, + const BYTE_ARRAY &value, const int &value_offset, const int &value_length + ,const std::vector &tags) + :offset_(-1), length_(-1), seqid_(0){ + + this->length_ = CreateByteArray( this->bytes_, row, row_offset, row_length, + family, family_offset, family_length, + qualifier, qualifier_offset, qualifier_length, + timestamp, type, value, value_offset, value_length);//, tags); + this->offset_ = 0; + +} +*/ +int KeyValue::WriteByteArray(BYTE_ARRAY &key_value, const int &boffset, + const BYTE_ARRAY &row, const int &roffset, const int &rlength, + const BYTE_ARRAY &family, const int &foffset, const int &flength, + const BYTE_ARRAY &qualifier, const int &qoffset, const int &qlength, + const long timestamp, const BYTE_TYPE &type, + const BYTE_ARRAY &value, const int &voffset, const int &vlength, const BYTE_ARRAY &tags) { + + int key_length = static_cast(GetKeyDataStructureSize(rlength, flength, qlength)); + int key_value_length = static_cast(GetKeyValueDataStructureSize( rlength, flength, qlength, vlength, tags.size())); + key_value.resize(key_value_length); + // Write key, value and key row length. + int pos = boffset; + pos = Bytes::PutInt(key_value, pos, key_length); + pos = Bytes::PutInt(key_value, pos, vlength); + pos = Bytes::PutShort(key_value, pos, (short)(rlength & 0x0000ffff)); + pos = Bytes::PutBytes(key_value, pos, row, roffset, rlength); + pos = Bytes::PutByte(key_value, pos, (byte) (flength & 0x0000ff)); + if (flength != 0) { + pos = Bytes::PutBytes(key_value, pos, family, foffset, flength); + } + if (qlength != 0) { + pos = Bytes::PutBytes(key_value, pos, qualifier, qoffset, qlength); + } + pos = Bytes::PutLong(key_value, pos, timestamp); + pos = Bytes::PutByte(key_value, pos, type); + if (value.size()> 0) { + pos = Bytes::PutBytes(key_value, pos, value, voffset, vlength); + } + return key_value_length; +} + +/* +int KeyValue::CreateByteArray( BYTE_ARRAY &key_value, + const BYTE_ARRAY &row, const int &row_offset, const int &row_length, + const BYTE_ARRAY &family, const int &family_offset, const int &family_length, + const BYTE_ARRAY &qualifier, const int &qualifier_offset, const int &qualifier_length, + const long ×tamp, const BYTE_TYPE &type, + const BYTE_ARRAY &value, const int &value_offset, const int &value_length), + const std::vector &tags){ + + int key_length = static_cast(GetKeyDataStructureSize(row_length, family_length, qualifier_length)); + int key_value_length = static_cast(GetKeyValueDataStructureSize( row_length, family_length, qualifier_length, + value_length, tags.size())); + key_value.resize(key_value_length); + + int pos = 0; + pos = Bytes::PutInt(key_value, pos, key_length); + pos = Bytes::PutInt(key_value, pos, value_length); + pos = Bytes::PutShort(key_value, pos, static_cast(row_length & 0x0000ffff)); + pos = Bytes::PutBytes(key_value, pos, row, row_offset, row_length); + pos = Bytes::PutByte(key_value, pos, static_cast(family_length & 0x0000FF)); + if(family_length != 0) { + pos = Bytes::PutBytes(key_value, pos, family, family_offset, family_length); + } + if (qualifier_length > 0) { + pos = Bytes::PutBytes(key_value, pos, qualifier, qualifier_offset, qualifier_length); + } + pos = Bytes::PutLong(key_value, pos, timestamp); + pos = Bytes::PutByte(key_value, pos, type); + if (value_length > 0) { + pos = Bytes::PutBytes(key_value, pos, value, value_offset, value_length); + } + return key_value.size(); + +} +*/ + +int KeyValue::CreateByteArray( BYTE_ARRAY &key_value, + const BYTE_ARRAY &row, const int &row_offset, const int &row_length, + const BYTE_ARRAY &family, const int &family_offset, const int &family_length, + const BYTE_ARRAY &qualifier, const int &qualifier_offset, const int &qualifier_length, + const long ×tamp, const BYTE_TYPE &type, + const BYTE_ARRAY &value, const int &value_offset, const int &value_length, + const BYTE_ARRAY &tag_bytes, const int &tag_offset, const int &tag_length){ + + int key_length = static_cast(GetKeyDataStructureSize(row_length, family_length, qualifier_length)); + int key_value_length = static_cast(GetKeyValueDataStructureSize( row_length, family_length, qualifier_length, + value_length, tag_length)); + key_value.resize(key_value_length); + + int pos = 0; + pos = Bytes::PutInt(key_value, pos, key_length); + pos = Bytes::PutInt(key_value, pos, value_length); + pos = Bytes::PutShort(key_value, pos, static_cast(row_length & 0x0000ffff)); + pos = Bytes::PutBytes(key_value, pos, row, row_offset, row_length); + pos = Bytes::PutByte(key_value, pos, static_cast(family_length & 0x0000FF)); + if(family_length != 0) { + pos = Bytes::PutBytes(key_value, pos, family, family_offset, family_length); + } + if (qualifier_length > 0) { + pos = Bytes::PutBytes(key_value, pos, qualifier, qualifier_offset, qualifier_length); + } + pos = Bytes::PutLong(key_value, pos, timestamp); + pos = Bytes::PutByte(key_value, pos, type); + if (value_length > 0) { + pos = Bytes::PutBytes(key_value, pos, value, value_offset, value_length); + } + + return key_value.size(); +} + +KeyValue::~KeyValue() { +} + + +long KeyValue::GetKeyValueDataStructureSize( const int &rlength, + const int &flength, + const int &qlength, + const int &vlength, + const int &tagsLength){ + + long kv_ds_size = 0L; + kv_ds_size = GetKeyDataStructureSize(rlength, flength, qlength) + vlength; + if (0 == tagsLength) { + kv_ds_size += KeyValue::KEYVALUE_INFRASTRUCTURE_SIZE; + }else{ + kv_ds_size += KeyValue::KEYVALUE_WITH_TAGS_INFRASTRUCTURE_SIZE + tagsLength; + } + return kv_ds_size; +} + + +long KeyValue::GetKeyDataStructureSize( const int &rlength, + const int &flength, + const int &qlength) { + return KeyValue::KEY_INFRASTRUCTURE_SIZE + rlength + flength + qlength; +} + +void KeyValue::SetSequenceId(const long &sequence_id){ + + this->seqid_ = sequence_id; +} + + +void KeyValue::DisplayBytes(){ + + Bytes::DisplayBytes(this->bytes_); + DLOG(INFO) << "Hex Vals:: " << Bytes::ToHex(this->bytes_); + +} + +int KeyValue::GetLength(const BYTE_ARRAY &bytes, const int &offset){ + + int klength = KeyValue::ROW_OFFSET + Bytes::ToInt(bytes, offset); + int vlength = Bytes::ToInt(bytes, offset + Bytes::SIZEOF_INT); + return klength + vlength; +} + +const int KeyValue::GetKeyOffset() const{ + return this->offset_ + KeyValue::ROW_OFFSET; +} + +const int KeyValue::GetKeyLength() const{ + + return Bytes::ToInt(this->bytes_, this->offset_); +} + + +const BYTE_ARRAY &KeyValue::GetRowArray() const{ + return this->bytes_; +} + +const int KeyValue::GetRowOffset() const{ + + return this->offset_ + KeyValue::ROW_KEY_OFFSET; +} + +const int KeyValue::GetRowLength() const{ + + return Bytes::ToShort(this->bytes_, GetKeyOffset()); +} + +const BYTE_ARRAY &KeyValue::GetFamilyArray() const{ + return this->bytes_; +} + +const int KeyValue::GetFamilyOffset() const{ + + return GetFamilyOffset(GetRowLength()); +} + +const int KeyValue::GetFamilyOffset(const int &row_length) const{ + + return this->offset_ + KeyValue::ROW_KEY_OFFSET + row_length + KeyValue::FAMILY_LENGTH_SIZE; +} + +const BYTE_TYPE KeyValue::GetFamilyLength() const{ + + return GetFamilyLength(GetFamilyOffset()); +} + +const BYTE_TYPE KeyValue::GetFamilyLength(const int &foffset) const{ + + return this->bytes_[foffset-1]; +} + +const BYTE_ARRAY &KeyValue::GetQualifierArray() const{ + + return this->bytes_; +} + +const int KeyValue::GetQualifierOffset() const{ + + return GetQualifierOffset(GetFamilyOffset()); +} + +const int KeyValue::GetQualifierOffset(const int &foffset) const{ + + return foffset + GetFamilyLength(foffset); +} + +const int KeyValue::GetQualifierLength() const{ + + return GetQualifierLength(GetRowLength(),GetFamilyLength()); + +} + +const int KeyValue::GetQualifierLength(const int &rlength, const int &flength) const{ + + return GetKeyLength() - static_cast(GetKeyDataStructureSize(rlength, flength, 0)); +} + +const int KeyValue::GetTimestampOffset() { + + return GetTimestampOffset(GetKeyLength()); +} + +const int KeyValue::GetTimestampOffset(const int &key_length) const{ + return GetKeyOffset() + key_length - KeyValue::TIMESTAMP_TYPE_SIZE; +} + +const unsigned long KeyValue::GetTimestamp() const{ + + return GetTimestamp(GetKeyLength()); +} + +const unsigned long KeyValue::GetTimestamp(const int &key_length) const{ + + int ts_offset = GetTimestampOffset(key_length); + return Bytes::ToLong(this->bytes_, ts_offset); +} + +const BYTE_TYPE KeyValue::GetTypeByte() const{ + + return this->bytes_[this->offset_ + GetKeyLength() - 1 + KeyValue::ROW_OFFSET]; +} + +const long &KeyValue::GetSequenceId() const{ + + return this->seqid_; +} + +const BYTE_ARRAY &KeyValue::GetValueArray() const{ + + return this->bytes_; +} + +const int KeyValue::GetValueOffset() const{ + + int voffset = GetKeyOffset() + GetKeyLength(); + return voffset; +} + +const int KeyValue::GetValueLength() const{ + + int vlength = Bytes::ToInt(this->bytes_, this->offset_ + KeyValue::KEY_LENGTH_SIZE); + return vlength; +} + + +const int &KeyValue::GetKeyValueLength() const{ + + return this->length_; +} diff --git a/hbase-native-client/core/key_value.h b/hbase-native-client/core/key_value.h new file mode 100644 index 0000000..32ce92e --- /dev/null +++ b/hbase-native-client/core/key_value.h @@ -0,0 +1,215 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * + */ + +#pragma once + +#include "bytes.h" +//#include "tag.h" + +class KeyValue { + public: + enum class KEY_TYPE { + Minimum = static_cast(0), + Put = static_cast(4), + Delete = static_cast(8), + DeleteFamilyVersion = static_cast(10), + DeleteColumn = static_cast(12), + DeleteFamily = static_cast(14), + Maximum = static_cast(255) + }; + const static byte COLUMN_FAMILY_DELIMITER; + /** Size of the key length field in bytes*/ + const static int KEY_LENGTH_SIZE; + /** Size of the row length field in bytes */ + const static int ROW_LENGTH_SIZE; + /** Size of the family length field in bytes */ + const static int FAMILY_LENGTH_SIZE; + /** Size of the timestamp field in bytes */ + const static int TIMESTAMP_SIZE; + /** Size of the key type field in bytes */ + const static int TYPE_SIZE; + // Size of the timestamp and type byte on end of a key -- a long + a byte. + const static int TIMESTAMP_TYPE_SIZE; + // Size of the length shorts and bytes in key. + const static int KEY_INFRASTRUCTURE_SIZE; + // How far into the key the row starts at. First thing to read is the short + // that says how long the row is. + const static int ROW_OFFSET; + const static int ROW_KEY_OFFSET; + // Size of the length ints in a KeyValue datastructure. + const static int KEYVALUE_INFRASTRUCTURE_SIZE; + /** Size of the tags length field in bytes */ + const static int TAGS_LENGTH_SIZE; + const static int KEYVALUE_WITH_TAGS_INFRASTRUCTURE_SIZE; + + const static int VALUE_LENGTH_SIZE; + const static BYTE_ARRAY EMPTY_BYTE_ARRAY; + const static long LATEST_TIMESTAMP; + + KeyValue(); + KeyValue(const KeyValue& ckey_value); + KeyValue& operator=(const KeyValue &ckey_value); + KeyValue(const BYTE_ARRAY &bytes); + KeyValue(const BYTE_ARRAY &bytes, const int &offset); + KeyValue(const BYTE_ARRAY &bytes, const int &offset, const int &length); + KeyValue(const BYTE_ARRAY &bytes, const int &offset, const int &length, + const long &ts); + KeyValue(const BYTE_ARRAY &row, const long ×tamp); + KeyValue(const BYTE_ARRAY &row, const long ×tamp, const BYTE_TYPE &type); + KeyValue(const BYTE_ARRAY &row, const BYTE_ARRAY &family, + const BYTE_ARRAY &qualifier); + KeyValue(const BYTE_ARRAY &row, const BYTE_ARRAY &family, + const BYTE_ARRAY &qualifier, const BYTE_ARRAY &value); + KeyValue(const BYTE_ARRAY &row, const BYTE_ARRAY &family, + const BYTE_ARRAY &qualifier, const long ×tamp, + const BYTE_TYPE &type); + KeyValue(const BYTE_ARRAY &row, const BYTE_ARRAY &family, + const BYTE_ARRAY &qualifier, const long ×tamp, + const BYTE_ARRAY &value); + /*KeyValue(const BYTE_ARRAY &row, const BYTE_ARRAY &family, + const BYTE_ARRAY &qualifier, const long ×tamp, + const BYTE_ARRAY &value, const Tag *tag_ptr); + KeyValue(const BYTE_ARRAY &row, const BYTE_ARRAY &family, + const BYTE_ARRAY &qualifier, const long ×tamp, + const BYTE_ARRAY &value, const std::vector &tags);*/ + KeyValue(const BYTE_ARRAY &row, const BYTE_ARRAY &family, + const BYTE_ARRAY &qualifier, const long ×tamp, + const BYTE_TYPE &type, const BYTE_ARRAY &value); + /*KeyValue(const BYTE_ARRAY &row, const BYTE_ARRAY &family, + const BYTE_ARRAY &qualifier, const long ×tamp, + const BYTE_TYPE &type, const BYTE_ARRAY &value, + const std::vector &tags);*/ + KeyValue(const BYTE_ARRAY &row, const BYTE_ARRAY &family, + const BYTE_ARRAY &qualifier, const int &qoffset, const int &qlength, + const long ×tamp, const BYTE_TYPE &type, + const BYTE_ARRAY &value, const int &voffset, const int & vlength); //, const std::vector &tags); + KeyValue(const BYTE_ARRAY &row, const BYTE_ARRAY &family, + const BYTE_ARRAY &qualifier, const long ×tamp, + const BYTE_TYPE &type, const BYTE_ARRAY &value, + const BYTE_ARRAY &tag_bytes); + KeyValue(BYTE_ARRAY &buffer, const int &boffset, const BYTE_ARRAY &row, + const int &roffset, const int &rlength, const BYTE_ARRAY &family, + const int &foffset, const int &flength, const BYTE_ARRAY &qualifier, + const int &qoffset, const int &qlength, const long ×tamp, + const BYTE_TYPE &type, const BYTE_ARRAY &value, const int &voffset, + const int &vlength, const BYTE_ARRAY &tag_bytes); + KeyValue(const BYTE_ARRAY &row, const int &row_offset, const int &row_length, + const BYTE_ARRAY &family, const int &family_offset, + const int &family_length, const BYTE_ARRAY &qualifier, + const int &qualifier_offset, const int &qualifier_length, + const long ×tamp, const BYTE_TYPE &type, + const BYTE_ARRAY &value, const int &value_offset, + const int &value_length, const BYTE_ARRAY &tag_bytes, + const int &tagsOffset, const int &tagsLength); + KeyValue(const int &rlength, const int &flength, const int &qlength, + const long ×tamp, const BYTE_TYPE &type, const int &vlength); + KeyValue(const int &rlength, const int &flength, const int &qlength, + const long ×tamp, const BYTE_TYPE &type, const int &vlength, + const int &tags_length); + KeyValue(const BYTE_ARRAY &row, const int &roffset, const int &rlength, + const BYTE_ARRAY &family, const int &foffset, const int &flength, + const BYTE_ARRAY &qualifier, const int &qoffset, const int &qlength, + const long ×tamp, const BYTE_TYPE &type, + const BYTE_ARRAY &value, const int &voffset, const int &vlength); + /*KeyValue(const BYTE_ARRAY &row, const int &row_offset, const int &row_length, + const BYTE_ARRAY &family, const int &family_offset, + const int &family_length, const BYTE_ARRAY &qualifier, + const int &qualifier_offset, const int &qualifier_length, + const long ×tamp, const BYTE_TYPE &type, + const BYTE_ARRAY &value, const int &value_offset, + const int &value_length, const std::vector &tags);*/ + const int GetKeyOffset() const; + const int GetKeyLength() const; + const BYTE_ARRAY &GetRowArray() const; + const int GetRowOffset() const; + const int GetRowLength() const; + const BYTE_ARRAY &GetFamilyArray() const; + const int GetFamilyOffset() const; + const BYTE_TYPE GetFamilyLength() const; + const BYTE_ARRAY &GetQualifierArray() const; + const int GetQualifierOffset() const; + const int GetQualifierLength() const; + const int GetTimestampOffset(); + const unsigned long GetTimestamp() const; + const BYTE_TYPE GetTypeByte() const; + const long &GetSequenceId() const; + const BYTE_ARRAY &GetValueArray() const; + const int GetValueOffset() const; + const int GetValueLength() const; + virtual ~KeyValue(); + void SetSequenceId(const long &sequence_id); + void DisplayBytes(); + static long GetKeyValueDataStructureSize(const int &rlength, + const int &flength, + const int &qlength, + const int &vlength, + const int &tagsLength = 0); + static long GetKeyDataStructureSize(const int &rlength, const int &flength, + const int &qlength); + static int CreateByteArray(BYTE_ARRAY &key_value, const BYTE_ARRAY &row, + const int &row_offset, const int &row_length, + const BYTE_ARRAY &family, const int &family_offset, + const int &family_length, + const BYTE_ARRAY &qualifier, + const int &qualifier_offset, + const int &qualifier_length, const long ×tamp, + const BYTE_TYPE &type, const BYTE_ARRAY &value, + const int &value_offset, const int &value_length); //, + //const std::vector &tags); + static int CreateByteArray(BYTE_ARRAY &key_value, const BYTE_ARRAY &row, + const int &row_offset, const int &row_length, + const BYTE_ARRAY &family, const int &family_offset, + const int &family_length, + const BYTE_ARRAY &qualifier, + const int &qualifier_offset, + const int &qualifier_length, const long ×tamp, + const BYTE_TYPE &type, const BYTE_ARRAY &value, + const int &value_offset, const int &value_length, + const BYTE_ARRAY &tag_bytes, const int &tag_offset, + const int &tag_length); + static int WriteByteArray(BYTE_ARRAY &buffer, const int &boffset, + const BYTE_ARRAY &row, const int &roffset, + const int &rlength, const BYTE_ARRAY &family, + const int &foffset, const int &flength, + const BYTE_ARRAY &qualifier, const int &qoffset, + const int &qlength, const long timestamp, + const BYTE_TYPE & type, const BYTE_ARRAY &value, + const int &voffset, const int &vlength, + const BYTE_ARRAY &tag_bytes); + + const int &GetKeyValueLength() const; + const int GetFamilyOffset(const int &row_length) const; + const BYTE_TYPE GetFamilyLength(const int &foffset) const; + const int GetQualifierOffset(const int &foffset) const; + const int GetQualifierLength(const int &rlength, const int &flength) const; + + private: + int offset_; // offset into bytes buffer KV starts at + int length_; // length of the KV starting from offset. + BYTE_ARRAY bytes_; // an immutable byte array that contains the KV + //std::vector null_tags_; + + private: + const static int MAX_TAGS_LENGTH; + long seqid_; + const int GetTimestampOffset(const int &key_length) const; + const unsigned long GetTimestamp(const int &key_length) const; + static int GetLength(const BYTE_ARRAY &bytes, const int &offset); +}; + diff --git a/hbase-native-client/core/utils.cc b/hbase-native-client/core/utils.cc new file mode 100644 index 0000000..97c4479 --- /dev/null +++ b/hbase-native-client/core/utils.cc @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * + */ + +#include "utils.h" + + +CommonUtils::CommonUtils() { + // TODO Auto-generated constructor stub + +} + +CommonUtils::~CommonUtils() { + // TODO Auto-generated destructor stub +} + +void CommonUtils::SwapByteOrder(unsigned int &ui) +{ + ui = (ui >> 24) | + ((ui<<8) & 0x00FF0000) | + ((ui>>8) & 0x0000FF00) | + (ui << 24); +} + +void CommonUtils::SwapByteOrder2Bytes(unsigned short &us) { + us = ( (((us) >> 8) & 0x00FF) | (((us) << 8) & 0xFF00) ); +} + diff --git a/hbase-native-client/core/utils.h b/hbase-native-client/core/utils.h new file mode 100644 index 0000000..8388e90 --- /dev/null +++ b/hbase-native-client/core/utils.h @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * + */ + +#pragma once + +class CommonUtils { + public: + CommonUtils(); + virtual ~CommonUtils(); + static void SwapByteOrder(unsigned int &ui); + static void SwapByteOrder2Bytes(unsigned short &us); +}; -- 1.8.3.1