You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@quickstep.apache.org by ha...@apache.org on 2016/09/07 01:07:01 UTC
incubator-quickstep git commit: [QUICKSTEP-53] New representation and
faster comparison operators for DateLit [Forced Update!]
Repository: incubator-quickstep
Updated Branches:
refs/heads/date-representation 92555fc43 -> 5a9c29004 (forced update)
[QUICKSTEP-53] New representation and faster comparison operators for DateLit
- New representation for DateLit.
- New comparison implementations for DateLit.
Closes #98
Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/5a9c2900
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/5a9c2900
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/5a9c2900
Branch: refs/heads/date-representation
Commit: 5a9c290043051dab9c4fd40db220f266479cf419
Parents: 1d10422
Author: Hakan Memisoglu <ha...@apache.org>
Authored: Tue Sep 6 19:59:26 2016 -0500
Committer: Hakan Memisoglu <ha...@apache.org>
Committed: Tue Sep 6 20:01:57 2016 -0500
----------------------------------------------------------------------
types/DateOperatorOverloads.hpp | 12 ++--
types/DateType.cpp | 8 +--
types/DatetimeLit.hpp | 62 +++++++++++++-------
types/TypedValue.cpp | 9 +--
types/TypedValue.hpp | 4 +-
types/TypedValue.proto | 8 +--
.../unary_operations/DateExtractOperation.cpp | 2 +-
7 files changed, 58 insertions(+), 47 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5a9c2900/types/DateOperatorOverloads.hpp
----------------------------------------------------------------------
diff --git a/types/DateOperatorOverloads.hpp b/types/DateOperatorOverloads.hpp
index b04f44e..e2e5f6a 100644
--- a/types/DateOperatorOverloads.hpp
+++ b/types/DateOperatorOverloads.hpp
@@ -122,8 +122,8 @@ inline DatetimeLit operator+(const YearMonthIntervalLit &lhs, const DatetimeLit
}
inline DateLit operator+(const DateLit &lhs, const YearMonthIntervalLit &rhs) {
- std::int32_t result_year = lhs.year + (rhs.months / 12);
- std::uint8_t result_month = lhs.month + (rhs.months % 12);
+ std::int32_t result_year = lhs.yearField() + (rhs.months / 12);
+ std::uint8_t result_month = static_cast<std::uint8_t>(lhs.monthField()) + (rhs.months % 12);
if (result_month > 11) {
result_month -= 12;
@@ -131,7 +131,7 @@ inline DateLit operator+(const DateLit &lhs, const YearMonthIntervalLit &rhs) {
}
const std::uint8_t result_day = static_cast<std::uint8_t>(
- ClampDayOfMonth(result_year, result_month, lhs.day));
+ ClampDayOfMonth(result_year, result_month, lhs.dayField()));
return DateLit::Create(result_year, result_month, result_day);
}
@@ -187,8 +187,8 @@ inline DatetimeLit operator-(const DatetimeLit &lhs, const YearMonthIntervalLit
}
inline DateLit operator-(const DateLit &lhs, const YearMonthIntervalLit &rhs) {
- std::int32_t result_year = lhs.year - (rhs.months / 12);
- std::int8_t result_month = lhs.month - (rhs.months % 12);
+ std::int32_t result_year = lhs.yearField() - (rhs.months / 12);
+ std::int8_t result_month = static_cast<std::int8_t>(lhs.monthField()) - (rhs.months % 12);
if (result_month < 0) {
--result_year;
@@ -196,7 +196,7 @@ inline DateLit operator-(const DateLit &lhs, const YearMonthIntervalLit &rhs) {
}
const std::uint8_t result_day = static_cast<std::uint8_t>(
- ClampDayOfMonth(result_year, result_month, lhs.day));
+ ClampDayOfMonth(result_year, result_month, lhs.dayField()));
return DateLit::Create(result_year, result_month, result_day);
}
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5a9c2900/types/DateType.cpp
----------------------------------------------------------------------
diff --git a/types/DateType.cpp b/types/DateType.cpp
index 5bb982c..388898e 100644
--- a/types/DateType.cpp
+++ b/types/DateType.cpp
@@ -60,7 +60,7 @@ std::string DateType::printValueToString(const TypedValue &value) const {
DCHECK(!value.isNull());
const DateLit literal = value.getLiteral<DateLit>();
- const std::int32_t year = literal.year;
+ const std::int32_t year = literal.yearField();
char datebuf[DateLit::kIsoChars + 1];
std::size_t chars_written = 0;
@@ -78,9 +78,9 @@ std::string DateType::printValueToString(const TypedValue &value) const {
// All the rest of the ISO 8601 date/time parts.
snprintf_result = snprintf(datebuf + chars_written,
sizeof(datebuf) - chars_written,
- "%02d-%02d",
- literal.month,
- literal.day);
+ "%02u-%02u",
+ literal.monthField(),
+ literal.dayField());
CheckSnprintf(snprintf_result, sizeof(datebuf), &chars_written);
return std::string(datebuf);
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5a9c2900/types/DatetimeLit.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeLit.hpp b/types/DatetimeLit.hpp
index 58c852f..c99dae4 100644
--- a/types/DatetimeLit.hpp
+++ b/types/DatetimeLit.hpp
@@ -36,10 +36,13 @@ namespace quickstep {
* @brief A literal representing the date.
**/
struct DateLit {
- // Note that although there is no year 0 in the Gregorian calendar, ISO 8601
- // has year 0 equivalent to 1 BCE, year -1 equivalent to 2 BCE, and so on.
- std::int32_t year;
- std::uint8_t month, day;
+ // ----------------------------------------------------
+ // | 23 bits | 4 bits | 5 bits |
+ // ----------------------------------------------------
+ // | year | month | day |
+ // | (unsigned) (18 bits used) | (unsigned) |
+ // ----------------------------------------------------
+ std::uint32_t year_month_day;
// The maximum number of characters needed to represent any date in ISO 8601
// notation.
@@ -51,53 +54,70 @@ struct DateLit {
+ 1 // -
+ 2; // Day
+ // Years should be between [-kMaxYear, +kMaxYear] inclusive both end.
+ static constexpr std::int32_t kMaxYear = 99999;
+ static constexpr std::uint8_t kBitsNeededForDay = 5u;
+ static constexpr std::uint8_t kBitsNeededForMonth = 4u;
+
static DateLit Create(const std::int32_t _year,
const std::uint8_t _month,
const std::uint8_t _day) {
DateLit date;
- date.year = _year;
- date.month = _month;
- date.day = _day;
+ // Normalize year by adding kMaxYear value, because we try to
+ // encode signed year value into an unsigned integer.
+ std::uint32_t representation
+ = (static_cast<std::uint32_t>(_year + kMaxYear) << (kBitsNeededForDay + kBitsNeededForMonth))
+ | (_month << kBitsNeededForDay)
+ | _day;
+ date.year_month_day = representation;
+ return date;
+ }
+ static DateLit Create(const std::uint32_t serialized) {
+ DateLit date;
+ date.year_month_day = serialized;
return date;
}
inline bool operator< (const DateLit& rhs) const {
- return (year != rhs.year)
- ? (year < rhs.year)
- : ((month != rhs.month) ? (month < rhs.month) : (day < rhs.day));
+ return year_month_day < rhs.year_month_day;
}
inline bool operator> (const DateLit& rhs) const {
- return (year != rhs.year)
- ? (year > rhs.year)
- : ((month != rhs.month) ? (month > rhs.month) : (day > rhs.day));
+ return year_month_day < rhs.year_month_day;
}
inline bool operator<=(const DateLit& rhs) const {
- return !(*this > rhs);
+ return year_month_day <= rhs.year_month_day;
}
inline bool operator>=(const DateLit& rhs) const {
- return !(*this < rhs);
+ return year_month_day >= rhs.year_month_day;
}
inline bool operator==(const DateLit& rhs) const {
- return (year == rhs.year) &&
- (month == rhs.month) &&
- (day == rhs.day);
+ return year_month_day == rhs.year_month_day;
}
inline bool operator!=(const DateLit& rhs) const {
- return !(*this == rhs);
+ return year_month_day != rhs.year_month_day;
}
inline std::int32_t yearField() const {
+ const std::int32_t year =
+ static_cast<std::int32_t>(year_month_day >>
+ (kBitsNeededForDay + kBitsNeededForMonth)) - kMaxYear;
return year;
}
- inline std::int32_t monthField() const {
- return static_cast<std::int32_t>(month);
+ inline std::uint32_t monthField() const {
+ const std::uint32_t mask = 0x1E0u; // 0b111100000
+ return (year_month_day & mask) >> kBitsNeededForDay;
+ }
+
+ inline std::uint32_t dayField() const {
+ const std::uint32_t mask = 0x1Fu; // 0b11111
+ return year_month_day & mask;
}
};
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5a9c2900/types/TypedValue.cpp
----------------------------------------------------------------------
diff --git a/types/TypedValue.cpp b/types/TypedValue.cpp
index 8dd8b60..ada69c6 100644
--- a/types/TypedValue.cpp
+++ b/types/TypedValue.cpp
@@ -110,10 +110,7 @@ serialization::TypedValue TypedValue::getProto() const {
case kDate:
proto.set_type_id(serialization::Type::DATE);
if (!isNull()) {
- serialization::TypedValue::DateLit *literal_date_proto = proto.mutable_date_value();
- literal_date_proto->set_year(value_union_.date_value.year);
- literal_date_proto->set_month(value_union_.date_value.month);
- literal_date_proto->set_day(value_union_.date_value.day);
+ proto.set_date_value(getLiteral<DateLit>().year_month_day);
}
break;
case kDatetime:
@@ -185,9 +182,7 @@ TypedValue TypedValue::ReconstructFromProto(const serialization::TypedValue &pro
TypedValue(kDouble);
case serialization::Type::DATE:
if (proto.has_date_value()) {
- return TypedValue(DateLit::Create(proto.date_value().year(),
- proto.date_value().month(),
- proto.date_value().day()));
+ return TypedValue(DateLit::Create(proto.date_value()));
} else {
return TypedValue(kDate);
}
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5a9c2900/types/TypedValue.hpp
----------------------------------------------------------------------
diff --git a/types/TypedValue.hpp b/types/TypedValue.hpp
index d75720a..dae8bd8 100644
--- a/types/TypedValue.hpp
+++ b/types/TypedValue.hpp
@@ -393,10 +393,10 @@ class TypedValue {
switch (getTypeID()) {
case kInt:
case kFloat:
+ case kDate:
return sizeof(int);
case kLong:
case kDouble:
- case kDate:
case kDatetime:
case kDatetimeInterval:
case kYearMonthInterval:
@@ -552,6 +552,8 @@ class TypedValue {
// 4 bytes byte-for-byte copy.
*static_cast<int*>(destination) = value_union_.int_value;
break;
+ case kDate:
+ *static_cast<DateLit*>(destination) = value_union_.date_value;
default:
// 8 bytes byte-for-byte copy.
*static_cast<ValueUnion*>(destination) = value_union_;
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5a9c2900/types/TypedValue.proto
----------------------------------------------------------------------
diff --git a/types/TypedValue.proto b/types/TypedValue.proto
index 7f3ab7a..0164688 100644
--- a/types/TypedValue.proto
+++ b/types/TypedValue.proto
@@ -34,11 +34,5 @@ message TypedValue {
optional int64 datetime_interval_value = 8;
optional int64 year_month_interval_value = 9;
- message DateLit {
- required int32 year = 1;
- required uint32 month = 2;
- required uint32 day = 3;
- }
-
- optional DateLit date_value = 10;
+ optional uint32 date_value = 10;
}
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/5a9c2900/types/operations/unary_operations/DateExtractOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/DateExtractOperation.cpp b/types/operations/unary_operations/DateExtractOperation.cpp
index c99e403..585fb85 100644
--- a/types/operations/unary_operations/DateExtractOperation.cpp
+++ b/types/operations/unary_operations/DateExtractOperation.cpp
@@ -444,7 +444,7 @@ TypedValue DateExtractOperation::applyToChecked(const TypedValue &argument,
} else {
// argument type is kDate.
DCHECK_EQ(TypeID::kDate, argument.getTypeID());
- return TypedValue(argument.getLiteral<DateLit>().monthField());
+ return TypedValue(static_cast<std::int32_t>(argument.getLiteral<DateLit>().monthField()));
}
}
case DateExtractUnit::kDay: