mariadb/storage/mroonga/lib/mrn_time_converter.cpp
Vicențiu Ciorbaru 08c852026d Apply clang-tidy to remove empty constructors / destructors
This patch is the result of running
run-clang-tidy -fix -header-filter=.* -checks='-*,modernize-use-equals-default' .

Code style changes have been done on top. The result of this change
leads to the following improvements:

1. Binary size reduction.
* For a -DBUILD_CONFIG=mysql_release build, the binary size is reduced by
  ~400kb.
* A raw -DCMAKE_BUILD_TYPE=Release reduces the binary size by ~1.4kb.

2. Compiler can better understand the intent of the code, thus it leads
   to more optimization possibilities. Additionally it enabled detecting
   unused variables that had an empty default constructor but not marked
   so explicitly.

   Particular change required following this patch in sql/opt_range.cc

   result_keys, an unused template class Bitmap now correctly issues
   unused variable warnings.

   Setting Bitmap template class constructor to default allows the compiler
   to identify that there are no side-effects when instantiating the class.
   Previously the compiler could not issue the warning as it assumed Bitmap
   class (being a template) would not be performing a NO-OP for its default
   constructor. This prevented the "unused variable warning".
2023-02-09 16:09:08 +02:00

293 lines
9.9 KiB
C++

/* -*- c-basic-offset: 2 -*- */
/*
Copyright(C) 2010-2013 Kentoku SHIBA
Copyright(C) 2011-2015 Kouhei Sutou <kou@clear-code.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
*/
#include "mrn_time_converter.hpp"
#ifdef min
# undef min
#endif
#ifdef max
# undef max
#endif
#include <limits>
// for debug
#define MRN_CLASS_NAME "mrn::TimeConverter"
namespace mrn {
TimeConverter::TimeConverter() = default;
TimeConverter::~TimeConverter() = default;
time_t TimeConverter::tm_to_time_gm(struct tm *time, bool *truncated) {
MRN_DBUG_ENTER_METHOD();
*truncated = true;
struct tm gmdate;
time->tm_yday = -1;
time->tm_isdst = -1;
time_t sec_t = mktime(time);
if (time->tm_yday == -1) {
DBUG_RETURN(-1);
}
if (!gmtime_r(&sec_t, &gmdate)) {
DBUG_RETURN(-1);
}
int32 mrn_utc_diff_in_seconds =
(
time->tm_mday > 25 && gmdate.tm_mday == 1 ? -1 :
time->tm_mday == 1 && gmdate.tm_mday > 25 ? 1 :
time->tm_mday - gmdate.tm_mday
) * 24 * 60 * 60 +
(time->tm_hour - gmdate.tm_hour) * 60 * 60 +
(time->tm_min - gmdate.tm_min) * 60 +
(time->tm_sec - gmdate.tm_sec);
DBUG_PRINT("info", ("mroonga: time->tm_year=%d", time->tm_year));
DBUG_PRINT("info", ("mroonga: time->tm_mon=%d", time->tm_mon));
DBUG_PRINT("info", ("mroonga: time->tm_mday=%d", time->tm_mday));
DBUG_PRINT("info", ("mroonga: time->tm_hour=%d", time->tm_hour));
DBUG_PRINT("info", ("mroonga: time->tm_min=%d", time->tm_min));
DBUG_PRINT("info", ("mroonga: time->tm_sec=%d", time->tm_sec));
DBUG_PRINT("info", ("mroonga: mrn_utc_diff_in_seconds=%d",
mrn_utc_diff_in_seconds));
if (mrn_utc_diff_in_seconds > 0) {
if (sec_t > std::numeric_limits<time_t>::max() - mrn_utc_diff_in_seconds) {
DBUG_RETURN(-1);
}
} else {
if (sec_t < std::numeric_limits<time_t>::min() - mrn_utc_diff_in_seconds) {
DBUG_RETURN(-1);
}
}
*truncated = false;
DBUG_RETURN(sec_t + mrn_utc_diff_in_seconds);
}
long long int TimeConverter::tm_to_grn_time(struct tm *time, int usec,
bool *truncated) {
MRN_DBUG_ENTER_METHOD();
long long int sec = tm_to_time_gm(time, truncated);
DBUG_PRINT("info", ("mroonga: sec=%lld", sec));
DBUG_PRINT("info", ("mroonga: usec=%d", usec));
long long int grn_time = *truncated ? 0 : GRN_TIME_PACK(sec, usec);
DBUG_RETURN(grn_time);
}
long long int TimeConverter::mysql_time_to_grn_time(MYSQL_TIME *mysql_time,
bool *truncated) {
MRN_DBUG_ENTER_METHOD();
int usec = mysql_time->second_part;
long long int grn_time = 0;
*truncated = false;
switch (mysql_time->time_type) {
case MYSQL_TIMESTAMP_DATE:
{
DBUG_PRINT("info", ("mroonga: MYSQL_TIMESTAMP_DATE"));
struct tm date;
memset(&date, 0, sizeof(struct tm));
date.tm_year = mysql_time->year - TM_YEAR_BASE;
if (mysql_time->month > 0) {
date.tm_mon = mysql_time->month - 1;
} else {
date.tm_mon = 0;
*truncated = true;
}
if (mysql_time->day > 0) {
date.tm_mday = mysql_time->day;
} else {
date.tm_mday = 1;
*truncated = true;
}
DBUG_PRINT("info", ("mroonga: tm_year=%d", date.tm_year));
DBUG_PRINT("info", ("mroonga: tm_mon=%d", date.tm_mon));
DBUG_PRINT("info", ("mroonga: tm_mday=%d", date.tm_mday));
bool tm_truncated = false;
grn_time = tm_to_grn_time(&date, usec, &tm_truncated);
if (tm_truncated) {
*truncated = true;
}
}
break;
case MYSQL_TIMESTAMP_DATETIME:
{
DBUG_PRINT("info", ("mroonga: MYSQL_TIMESTAMP_DATETIME"));
struct tm datetime;
memset(&datetime, 0, sizeof(struct tm));
datetime.tm_year = mysql_time->year - TM_YEAR_BASE;
if (mysql_time->month > 0) {
datetime.tm_mon = mysql_time->month - 1;
} else {
datetime.tm_mon = 0;
*truncated = true;
}
if (mysql_time->day > 0) {
datetime.tm_mday = mysql_time->day;
} else {
datetime.tm_mday = 1;
*truncated = true;
}
datetime.tm_hour = mysql_time->hour;
datetime.tm_min = mysql_time->minute;
datetime.tm_sec = mysql_time->second;
DBUG_PRINT("info", ("mroonga: tm_year=%d", datetime.tm_year));
DBUG_PRINT("info", ("mroonga: tm_mon=%d", datetime.tm_mon));
DBUG_PRINT("info", ("mroonga: tm_mday=%d", datetime.tm_mday));
DBUG_PRINT("info", ("mroonga: tm_hour=%d", datetime.tm_hour));
DBUG_PRINT("info", ("mroonga: tm_min=%d", datetime.tm_min));
DBUG_PRINT("info", ("mroonga: tm_sec=%d", datetime.tm_sec));
bool tm_truncated = false;
grn_time = tm_to_grn_time(&datetime, usec, &tm_truncated);
if (tm_truncated) {
*truncated = true;
}
}
break;
case MYSQL_TIMESTAMP_TIME:
{
DBUG_PRINT("info", ("mroonga: MYSQL_TIMESTAMP_TIME"));
int sec =
mysql_time->hour * 60 * 60 +
mysql_time->minute * 60 +
mysql_time->second;
DBUG_PRINT("info", ("mroonga: sec=%d", sec));
grn_time = GRN_TIME_PACK(sec, usec);
if (mysql_time->neg) {
grn_time = -grn_time;
}
}
break;
default:
DBUG_PRINT("info", ("mroonga: default"));
grn_time = 0;
break;
}
DBUG_RETURN(grn_time);
}
void TimeConverter::grn_time_to_mysql_time(long long int grn_time,
MYSQL_TIME *mysql_time) {
MRN_DBUG_ENTER_METHOD();
long long int sec;
int usec;
GRN_TIME_UNPACK(grn_time, sec, usec);
DBUG_PRINT("info", ("mroonga: sec=%lld", sec));
DBUG_PRINT("info", ("mroonga: usec=%d", usec));
switch (mysql_time->time_type) {
case MYSQL_TIMESTAMP_DATE:
{
DBUG_PRINT("info", ("mroonga: MYSQL_TIMESTAMP_DATE"));
struct tm date;
time_t sec_t = sec;
// TODO: Add error check
gmtime_r(&sec_t, &date);
DBUG_PRINT("info", ("mroonga: tm_year=%d", date.tm_year));
mysql_time->year = date.tm_year + TM_YEAR_BASE;
DBUG_PRINT("info", ("mroonga: tm_mon=%d", date.tm_mon));
mysql_time->month = date.tm_mon + 1;
DBUG_PRINT("info", ("mroonga: tm_mday=%d", date.tm_mday));
mysql_time->day = date.tm_mday;
}
break;
case MYSQL_TIMESTAMP_DATETIME:
{
DBUG_PRINT("info", ("mroonga: MYSQL_TIMESTAMP_DATETIME"));
struct tm date;
time_t sec_t = sec;
// TODO: Add error check
gmtime_r(&sec_t, &date);
DBUG_PRINT("info", ("mroonga: tm_year=%d", date.tm_year));
mysql_time->year = date.tm_year + TM_YEAR_BASE;
DBUG_PRINT("info", ("mroonga: tm_mon=%d", date.tm_mon));
mysql_time->month = date.tm_mon + 1;
DBUG_PRINT("info", ("mroonga: tm_mday=%d", date.tm_mday));
mysql_time->day = date.tm_mday;
DBUG_PRINT("info", ("mroonga: tm_hour=%d", date.tm_hour));
mysql_time->hour = date.tm_hour;
DBUG_PRINT("info", ("mroonga: tm_min=%d", date.tm_min));
mysql_time->minute = date.tm_min;
DBUG_PRINT("info", ("mroonga: tm_sec=%d", date.tm_sec));
mysql_time->second = date.tm_sec;
mysql_time->second_part = usec;
}
break;
case MYSQL_TIMESTAMP_TIME:
DBUG_PRINT("info", ("mroonga: MYSQL_TIMESTAMP_TIME"));
if (sec < 0) {
mysql_time->neg = true;
sec = -sec;
}
mysql_time->hour = static_cast<unsigned int>(sec / 60 / 60);
mysql_time->minute = sec / 60 % 60;
mysql_time->second = sec % 60;
mysql_time->second_part = usec;
break;
default:
DBUG_PRINT("info", ("mroonga: default"));
break;
}
DBUG_VOID_RETURN;
}
long long int TimeConverter::mysql_datetime_to_grn_time(long long int mysql_datetime,
bool *truncated) {
MRN_DBUG_ENTER_METHOD();
MYSQL_TIME mysql_time;
mysql_time.time_type = MYSQL_TIMESTAMP_DATETIME;
mysql_time.neg = 0;
mysql_time.second_part = 0;
mysql_time.second = (mysql_datetime % 100);
mysql_time.minute = (mysql_datetime / 100 % 100);
mysql_time.hour = (mysql_datetime / 10000 % 100);
mysql_time.day = (mysql_datetime / 1000000 % 100);
mysql_time.month = (mysql_datetime / 100000000 % 100);
mysql_time.year = (mysql_datetime / 10000000000LL % 10000);
long long int grn_time = mysql_time_to_grn_time(&mysql_time, truncated);
DBUG_RETURN(grn_time);
}
long long int TimeConverter::grn_time_to_mysql_datetime(long long int grn_time) {
MRN_DBUG_ENTER_METHOD();
MYSQL_TIME mysql_time;
mysql_time.time_type = MYSQL_TIMESTAMP_DATETIME;
grn_time_to_mysql_time(grn_time, &mysql_time);
long long int mysql_datetime =
(mysql_time.second * 1) +
(mysql_time.minute * 100) +
(mysql_time.hour * 10000) +
(mysql_time.day * 1000000) +
(mysql_time.month * 100000000) +
(mysql_time.year * 10000000000LL);
DBUG_RETURN(mysql_datetime);
}
}