blob: 90d0b969c36cbe7588a17137dace509f3895172f [file] [log] [blame]
/*
* 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.
*/
#ifndef UTILS_UTILS_H
#define UTILS_UTILS_H
#include <stdint.h>
#include <stdio.h>
#include <string.h> // memcpy
#include <sys/time.h>
#include <iostream>
#include <sstream>
#include <string>
#include "common/allocator/my_string.h"
#include "common/db_common.h"
#include "utils/util_define.h"
namespace common {
extern TSEncoding get_value_encoder(TSDataType data_type);
extern CompressionType get_default_compressor();
typedef struct FileID {
int64_t seq_; // timestamp when create
int32_t version_;
int32_t merge_;
FileID() : seq_(0), version_(0), merge_(0) {}
void reset() {
seq_ = 0;
version_ = 0;
merge_ = 0;
}
FORCE_INLINE bool is_valid() const { return seq_ != 0; }
FORCE_INLINE bool operator<(const FileID &that) const {
return this->seq_ < that.seq_;
}
FORCE_INLINE bool operator==(const FileID &that) const {
return this->seq_ == that.seq_;
}
#ifndef NDEBUG
friend std::ostream &operator<<(std::ostream &out, const FileID &file_id) {
out << "{seq_=" << file_id.seq_ << ", version_=" << file_id.version_
<< ", merge_=" << file_id.merge_ << "}";
return out;
}
#endif
} FileID;
typedef uint16_t NodeID;
struct TsID {
NodeID db_nid_;
NodeID device_nid_;
NodeID measurement_nid_;
TsID() : db_nid_(0), device_nid_(0), measurement_nid_(0){};
TsID(NodeID db_nid, NodeID device_nid, NodeID measurement_nid)
: db_nid_(db_nid),
device_nid_(device_nid),
measurement_nid_(measurement_nid) {}
/*
* To make TsID to be a trival copyable struct.
*/
#if 0
TsID(const TsID &other) : db_nid_(other.db_nid_),
device_nid_(other.device_nid_),
measurement_nid_(other.measurement_nid_) {}
TsID & operator = (const TsID &other)
{
db_nid_ = other.db_nid_;
device_nid_ = other.device_nid_;
measurement_nid_ = other.measurement_nid_;
return *this;
}
#endif
void reset() {
db_nid_ = 0;
device_nid_ = 0;
measurement_nid_ = 0;
}
bool is_valid() const {
// TODO
return true;
}
FORCE_INLINE bool operator==(const TsID &other) const {
return db_nid_ == other.db_nid_ && device_nid_ == other.device_nid_ &&
measurement_nid_ == other.measurement_nid_;
}
FORCE_INLINE bool operator!=(const TsID &other) const {
return db_nid_ != other.db_nid_ || device_nid_ != other.device_nid_ ||
measurement_nid_ != other.measurement_nid_;
}
FORCE_INLINE int64_t to_int64() const {
int64_t res = db_nid_;
res = (res << 16) | device_nid_;
res = (res << 16) | measurement_nid_;
return res;
}
FORCE_INLINE bool operator<(const TsID &that) const {
return to_int64() < that.to_int64();
}
FORCE_INLINE bool operator>(const TsID &other) {
return to_int64() > other.to_int64();
}
friend std::ostream &operator<<(std::ostream &out, TsID &ti) {
out << "(" << ti.db_nid_ << ", " << ti.device_nid_ << ", "
<< ti.measurement_nid_ << ") ";
return out;
}
FORCE_INLINE void to_string(char *print_buf, int len) const {
snprintf(print_buf, len, "<%d,%d,%d>", db_nid_, device_nid_,
measurement_nid_);
}
FORCE_INLINE std::string to_string() const {
const int buf_len = 32;
char buf[buf_len];
snprintf(buf, buf_len, "<%d,%d,%d>", db_nid_, device_nid_,
measurement_nid_);
// construct std::string will invoke memory allocation and copy.
// try to use first to_string instead.
return std::string(buf);
}
};
/**
* @brief Represents the schema information for a single measurement.
* @brief Represents the category of a column in a table schema.
*
* This enumeration class defines the supported categories for columns within a
* table schema, distinguishing between tag and field columns.
*/
enum class ColumnCategory { TAG = 0, FIELD = 1 };
/**
* @brief Represents the schema information for a single column.
*
* This structure holds the metadata necessary to describe how a specific column
* is stored, including its name, data type, category.
*/
struct ColumnSchema {
std::string column_name_;
TSDataType data_type_;
CompressionType compression_;
TSEncoding encoding_;
ColumnCategory column_category_;
ColumnSchema()
: column_name_(""),
data_type_(INVALID_DATATYPE),
compression_(UNCOMPRESSED),
encoding_(PLAIN) {}
/**
* @brief Constructs a ColumnSchema object with the given parameters.
*
* @param column_name The name of the column. Must be a non-empty string.
* This name is used to identify the column within the
* table.
* @param data_type The data type of the measurement, such as INT32, DOUBLE,
* TEXT, etc. This determines how the data will be stored and interpreted.
* @param column_category The category of the column indicating its role or
* type within the schema, e.g., FIELD, TAG. Defaults to
* ColumnCategory::FIELD if not specified.
* @note It is the responsibility of the caller to ensure that `column_name`
* is not empty.
*/
ColumnSchema(std::string column_name, TSDataType data_type,
CompressionType compression, TSEncoding encoding,
ColumnCategory column_category = ColumnCategory::FIELD)
: column_name_(std::move(column_name)),
data_type_(data_type),
compression_(compression),
encoding_(encoding),
column_category_(column_category) {}
ColumnSchema(std::string column_name, TSDataType data_type,
ColumnCategory column_category = ColumnCategory::FIELD)
: column_name_(std::move(column_name)),
data_type_(data_type),
compression_(get_default_compressor()),
encoding_(get_value_encoder(data_type)),
column_category_(column_category) {}
const std::string &get_column_name() const { return column_name_; }
const TSDataType &get_data_type() const { return data_type_; }
const ColumnCategory &get_column_category() const {
return column_category_;
}
const CompressionType &get_compression() const { return compression_; }
const TSEncoding &get_encoding() const { return encoding_; }
bool operator==(const ColumnSchema &other) const {
return (data_type_ == other.data_type_ &&
encoding_ == other.encoding_ &&
compression_ == other.compression_ &&
column_name_ == other.column_name_);
}
bool operator!=(const ColumnSchema &other) const {
return (data_type_ != other.data_type_ ||
encoding_ != other.encoding_ ||
compression_ != other.compression_ ||
column_name_ != other.column_name_);
}
bool is_valid() const {
return data_type_ != INVALID_DATATYPE &&
encoding_ != INVALID_ENCODING &&
compression_ != INVALID_COMPRESSION;
}
void reset() {
// TODO
}
void get_device_name(char *ret_device_name_buf, const int buf_len,
uint32_t &ret_len) const {
int pos = column_name_.find_last_of('.');
ASSERT(pos > 0 && pos < buf_len);
memcpy(ret_device_name_buf, column_name_.c_str(), pos);
ret_device_name_buf[pos] = '\0';
ret_len = pos;
}
std::string get_device_name_str() const {
int pos = column_name_.find_last_of('.');
ASSERT(pos > 0);
return column_name_.substr(0, pos);
}
void get_device_name(String &device_name) const {
int pos = column_name_.find_last_of('.');
ASSERT(pos > 0);
const char *c_string = column_name_.c_str();
device_name.buf_ = (char *)c_string;
device_name.len_ = pos;
}
void get_measurement_name(char *ret_measurement_name_buf, const int buf_len,
uint32_t &ret_len) const {
int pos = column_name_.find_last_of('.');
ASSERT(pos > 0 && pos < buf_len);
ret_len = column_name_.size() - pos - 1;
memcpy(ret_measurement_name_buf, column_name_.c_str() + pos + 1,
ret_len);
ret_measurement_name_buf[ret_len] = '\0';
}
std::string get_measurement_name_str() const {
int pos = column_name_.find_last_of('.');
ASSERT(pos > 0);
return column_name_.substr(pos + 1, column_name_.size() - pos);
}
// TODO remove
void get_measurement_name(String &measurement_name) const {
int pos = column_name_.find_last_of('.');
ASSERT(pos > 0);
const char *c_string = column_name_.c_str();
measurement_name.buf_ = (char *)c_string + pos + 1;
measurement_name.len_ = column_name_.size() - pos - 1;
}
String get_measurement_name() {
int pos = column_name_.find_last_of('.');
ASSERT(pos > 0);
const char *c_string = column_name_.c_str();
String res;
res.buf_ = (char *)c_string + pos + 1;
res.len_ = column_name_.size() - pos - 1;
return res;
}
#ifdef DEBUG
std::string debug_string() // for debug
{
std::stringstream out;
out << "print ColumnSchema: " << this << std::endl
<< "name: " << column_name_.c_str() << std::endl
<< "datatype: " << get_data_type_name(data_type_) << std::endl
<< "encoding: " << get_encoding_name(encoding_) << std::endl
<< "compression:" << get_compression_name(compression_)
<< std::endl;
return out.str();
}
#endif
};
FORCE_INLINE int64_t get_cur_timestamp() {
int64_t timestamp = 0;
struct timeval tv;
if (gettimeofday(&tv, NULL) >= 0) {
timestamp = (int64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
return timestamp;
}
#if 0
struct DatabaseIdTTL
{
NodeID db_nid_;
int64_t ttl_;
int16_t counter_; // suppose we at most support 64k timeseries.
DatabaseIdTTL() {}
DatabaseIdTTL(NodeID db_nid, int64_t ttl, int16_t counter) : db_nid_(db_nid), ttl_(ttl), counter_(counter) {}
DatabaseIdTTL(const DatabaseIdTTL &other) : db_nid_(other.db_nid_), ttl_(other.ttl_), counter_(other.counter_) {}
DatabaseIdTTL & operator = (const DatabaseIdTTL &other)
{
this->db_nid_ = other.db_nid_;
this->ttl_ = other.ttl_;
this->counter_ = other.counter_;
return *this;
}
bool operator == (const DatabaseIdTTL &other)
{
if (db_nid_ != other.db_nid_ || ttl_ != other.ttl_ || counter_ != other.counter_) {
return false;
}
return true;
}
friend std::ostream& operator << (std::ostream& out, DatabaseIdTTL& di)
{
return out;
}
};
struct DeviceIDWithCounter
{
NodeID device_nid_;
int16_t counter_; // suppose we at most support 64k timeseries.
DeviceIDWithCounter() {}
DeviceIDWithCounter(NodeID device_nid, int16_t counter) : device_nid_(device_nid), counter_(counter) {}
DeviceIDWithCounter(const DeviceIDWithCounter &other) : device_nid_(other.device_nid_), counter_(other.counter_) {}
DeviceIDWithCounter& operator = (const DeviceIDWithCounter &other)
{
this->device_nid_ = other.device_nid_;
this->counter_ = other.counter_;
return *this;
}
bool operator == (const DeviceID &other)
{
if (device_nid_ != other.device_nid_ || counter_ != other.counter_) {
return false;
}
return true;
}
friend std::ostream& operator << (std::ostream& out, DeviceID& di)
{
out << "(" << di.device_nid_ << ", " << di.counter_ << ") ";
return out;
}
};
#endif
} // end namespace common
#endif // UTILS_UTILS_H