mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 23:21:59 +00:00
Better code for CIDR to range functions #5095
This commit is contained in:
parent
3fa2784e7c
commit
0381a6a1ec
@ -1453,13 +1453,19 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum Bound
|
||||||
|
{
|
||||||
|
Lower,
|
||||||
|
Upper
|
||||||
|
};
|
||||||
|
|
||||||
constexpr size_t ip_range_tuple_size = 2;
|
constexpr size_t ip_range_tuple_size = 2;
|
||||||
|
|
||||||
class FunctionIPv6CIDRtoIPv6Range : public IFunction
|
class FunctionIPv6CIDRToRange : public IFunction
|
||||||
{
|
{
|
||||||
static constexpr size_t bits_in_uint8 = 8;
|
static constexpr size_t bits_in_uint8 = 8;
|
||||||
public:
|
public:
|
||||||
template <bool lower_range>
|
template <Bound bound>
|
||||||
static void setCIDRMask(const UInt8 * __restrict src, UInt8 * __restrict dst, UInt8 bits_to_keep)
|
static void setCIDRMask(const UInt8 * __restrict src, UInt8 * __restrict dst, UInt8 bits_to_keep)
|
||||||
{
|
{
|
||||||
for (size_t offset = 0, byte_offset = bits_in_uint8; offset != IPV6_BINARY_LENGTH; ++offset, byte_offset += bits_in_uint8)
|
for (size_t offset = 0, byte_offset = bits_in_uint8; offset != IPV6_BINARY_LENGTH; ++offset, byte_offset += bits_in_uint8)
|
||||||
@ -1477,7 +1483,7 @@ public:
|
|||||||
? bits_in_uint8
|
? bits_in_uint8
|
||||||
: byte_offset - bits_to_keep;
|
: byte_offset - bits_to_keep;
|
||||||
|
|
||||||
constexpr UInt8 byte_reference = lower_range ? 0 : std::numeric_limits<UInt8>::max();
|
constexpr UInt8 byte_reference = bound == Lower ? 0 : std::numeric_limits<UInt8>::max();
|
||||||
|
|
||||||
/// Clean the bits we don't want on byte
|
/// Clean the bits we don't want on byte
|
||||||
const UInt16 src_byte_shift = (static_cast<UInt16>(src[offset]) >> shifts_bits) << shifts_bits;
|
const UInt16 src_byte_shift = (static_cast<UInt16>(src[offset]) >> shifts_bits) << shifts_bits;
|
||||||
@ -1490,8 +1496,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static constexpr auto name = "IPv6CIDRtoIPv6Range";
|
static constexpr auto name = "IPv6CIDRToRange";
|
||||||
static FunctionPtr create(const Context &) { return std::make_shared<FunctionIPv6CIDRtoIPv6Range>(); }
|
static FunctionPtr create(const Context &) { return std::make_shared<FunctionIPv6CIDRToRange>(); }
|
||||||
|
|
||||||
String getName() const override { return name; }
|
String getName() const override { return name; }
|
||||||
|
|
||||||
@ -1566,8 +1572,8 @@ public:
|
|||||||
? col_const_cidr_in->getValue<UInt8>()
|
? col_const_cidr_in->getValue<UInt8>()
|
||||||
: col_cidr_in->getData()[offset];
|
: col_cidr_in->getData()[offset];
|
||||||
|
|
||||||
setCIDRMask<true>(&vec_in[offset_ipv6], &vec_res_lower_range[offset_ipv6], cidr);
|
setCIDRMask<Lower>(&vec_in[offset_ipv6], &vec_res_lower_range[offset_ipv6], cidr);
|
||||||
setCIDRMask<false>(&vec_in[offset_ipv6], &vec_res_upper_range[offset_ipv6], cidr);
|
setCIDRMask<Upper>(&vec_in[offset_ipv6], &vec_res_upper_range[offset_ipv6], cidr);
|
||||||
}
|
}
|
||||||
|
|
||||||
tuple_columns[0] = std::move(col_res_lower_range);
|
tuple_columns[0] = std::move(col_res_lower_range);
|
||||||
@ -1587,15 +1593,16 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class FunctionIPv4CIDRtoIPv4Range : public IFunction
|
|
||||||
|
class FunctionIPv4CIDRToRange : public IFunction
|
||||||
{
|
{
|
||||||
static constexpr size_t bits_in_uint32 = 32;
|
static constexpr size_t bits_in_uint32 = 32;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <bool lower_range>
|
template <Bound bound>
|
||||||
static UInt32 setCIDRMask(UInt32 src, UInt8 bits_to_keep)
|
static UInt32 setCIDRMask(UInt32 src, UInt8 bits_to_keep)
|
||||||
{
|
{
|
||||||
UInt32 byte_reference = lower_range ? 0 : std::numeric_limits<UInt32>::max();
|
UInt32 byte_reference = bound == Lower ? 0 : std::numeric_limits<UInt32>::max();
|
||||||
|
|
||||||
if (bits_to_keep >= bits_in_uint32)
|
if (bits_to_keep >= bits_in_uint32)
|
||||||
return src;
|
return src;
|
||||||
@ -1612,8 +1619,8 @@ public:
|
|||||||
return static_cast<UInt32>(src_byte_shift | cidr_mask_byte_shift);
|
return static_cast<UInt32>(src_byte_shift | cidr_mask_byte_shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr auto name = "IPv4CIDRtoIPv4Range";
|
static constexpr auto name = "IPv4CIDRToRange";
|
||||||
static FunctionPtr create(const Context &) { return std::make_shared<FunctionIPv4CIDRtoIPv4Range>(); }
|
static FunctionPtr create(const Context &) { return std::make_shared<FunctionIPv4CIDRToRange>(); }
|
||||||
|
|
||||||
String getName() const override { return name; }
|
String getName() const override { return name; }
|
||||||
|
|
||||||
@ -1677,8 +1684,8 @@ public:
|
|||||||
? col_const_cidr_in->getValue<UInt8>()
|
? col_const_cidr_in->getValue<UInt8>()
|
||||||
: col_cidr_in->getData()[i];
|
: col_cidr_in->getData()[i];
|
||||||
|
|
||||||
vec_res_lower_range[i] = setCIDRMask<true>(vec_in[i], cidr);
|
vec_res_lower_range[i] = setCIDRMask<Lower>(vec_in[i], cidr);
|
||||||
vec_res_upper_range[i] = setCIDRMask<false>(vec_in[i], cidr);
|
vec_res_upper_range[i] = setCIDRMask<Upper>(vec_in[i], cidr);
|
||||||
}
|
}
|
||||||
|
|
||||||
tuple_columns[0] = std::move(col_res_lower_range);
|
tuple_columns[0] = std::move(col_res_lower_range);
|
||||||
|
@ -5,21 +5,21 @@ CREATE TABLE ipv4_range(ip IPv4, cidr UInt8) ENGINE = Memory;
|
|||||||
|
|
||||||
INSERT INTO ipv4_range (ip, cidr) VALUES (toIPv4('192.168.5.2'), 0), (toIPv4('192.168.5.20'), 32), (toIPv4('255.255.255.255'), 16), (toIPv4('192.142.32.2'), 32), (toIPv4('192.172.5.2'), 16), (toIPv4('0.0.0.0'), 8), (toIPv4('255.0.0.0'), 4);
|
INSERT INTO ipv4_range (ip, cidr) VALUES (toIPv4('192.168.5.2'), 0), (toIPv4('192.168.5.20'), 32), (toIPv4('255.255.255.255'), 16), (toIPv4('192.142.32.2'), 32), (toIPv4('192.172.5.2'), 16), (toIPv4('0.0.0.0'), 8), (toIPv4('255.0.0.0'), 4);
|
||||||
|
|
||||||
WITH IPv4CIDRtoIPv4Range(toIPv4('192.168.0.0'), 8) as ip_range SELECT COUNT(*) FROM ipv4_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
|
WITH IPv4CIDRToRange(toIPv4('192.168.0.0'), 8) as ip_range SELECT COUNT(*) FROM ipv4_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
|
||||||
|
|
||||||
WITH IPv4CIDRtoIPv4Range(toIPv4('192.168.0.0'), 13) as ip_range SELECT COUNT(*) FROM ipv4_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
|
WITH IPv4CIDRToRange(toIPv4('192.168.0.0'), 13) as ip_range SELECT COUNT(*) FROM ipv4_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
|
||||||
|
|
||||||
WITH IPv4CIDRtoIPv4Range(toIPv4('192.168.0.0'), 16) as ip_range SELECT COUNT(*) FROM ipv4_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
|
WITH IPv4CIDRToRange(toIPv4('192.168.0.0'), 16) as ip_range SELECT COUNT(*) FROM ipv4_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
|
||||||
|
|
||||||
WITH IPv4CIDRtoIPv4Range(toIPv4('192.168.0.0'), 0) as ip_range SELECT COUNT(*) FROM ipv4_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
|
WITH IPv4CIDRToRange(toIPv4('192.168.0.0'), 0) as ip_range SELECT COUNT(*) FROM ipv4_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
|
||||||
|
|
||||||
WITH IPv4CIDRtoIPv4Range(ip, cidr) as ip_range SELECT ip, cidr, IPv4NumToString(tupleElement(ip_range, 1)), ip_range FROM ipv4_range;
|
WITH IPv4CIDRToRange(ip, cidr) as ip_range SELECT ip, cidr, IPv4NumToString(tupleElement(ip_range, 1)), ip_range FROM ipv4_range;
|
||||||
|
|
||||||
DROP TABLE ipv4_range;
|
DROP TABLE ipv4_range;
|
||||||
|
|
||||||
SELECT IPv4CIDRtoIPv4Range(toIPv4('192.168.5.2'), 0);
|
SELECT IPv4CIDRToRange(toIPv4('192.168.5.2'), 0);
|
||||||
SELEcT IPv4CIDRtoIPv4Range(toIPv4('255.255.255.255'), 8);
|
SELEcT IPv4CIDRToRange(toIPv4('255.255.255.255'), 8);
|
||||||
SELECT IPv4CIDRtoIPv4Range(toIPv4('192.168.5.2'), 32);
|
SELECT IPv4CIDRToRange(toIPv4('192.168.5.2'), 32);
|
||||||
SELECT IPv4CIDRtoIPv4Range(toIPv4('0.0.0.0'), 8);
|
SELECT IPv4CIDRToRange(toIPv4('0.0.0.0'), 8);
|
||||||
SELECT IPv4CIDRtoIPv4Range(toIPv4('255.0.0.0'), 4);
|
SELECT IPv4CIDRToRange(toIPv4('255.0.0.0'), 4);
|
||||||
|
|
||||||
|
@ -5,23 +5,22 @@ CREATE TABLE ipv6_range(ip IPv6, cidr UInt8) ENGINE = Memory;
|
|||||||
|
|
||||||
INSERT INTO ipv6_range (ip, cidr) VALUES (IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 0), (IPv6StringToNum('2001:0db8:0000:85a3:ffff:ffff:ffff:ffff'), 32), (IPv6StringToNum('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), 16), (IPv6StringToNum('2001:df8:0:85a3::ac1f:8001'), 32), (IPv6StringToNum('2001:0db8:85a3:85a3:0000:0000:ac1f:8001'), 16), (IPv6StringToNum('0000:0000:0000:0000:0000:0000:0000:0000'), 8), (IPv6StringToNum('ffff:0000:0000:0000:0000:0000:0000:0000'), 4);
|
INSERT INTO ipv6_range (ip, cidr) VALUES (IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 0), (IPv6StringToNum('2001:0db8:0000:85a3:ffff:ffff:ffff:ffff'), 32), (IPv6StringToNum('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), 16), (IPv6StringToNum('2001:df8:0:85a3::ac1f:8001'), 32), (IPv6StringToNum('2001:0db8:85a3:85a3:0000:0000:ac1f:8001'), 16), (IPv6StringToNum('0000:0000:0000:0000:0000:0000:0000:0000'), 8), (IPv6StringToNum('ffff:0000:0000:0000:0000:0000:0000:0000'), 4);
|
||||||
|
|
||||||
WITH IPv6CIDRtoIPv6Range(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 32) as ip_range SELECT COUNT(*) FROM ipv6_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
|
WITH IPv6CIDRToRange(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 32) as ip_range SELECT COUNT(*) FROM ipv6_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
|
||||||
|
|
||||||
WITH IPv6CIDRtoIPv6Range(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 25) as ip_range SELECT COUNT(*) FROM ipv6_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
|
WITH IPv6CIDRToRange(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 25) as ip_range SELECT COUNT(*) FROM ipv6_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
|
||||||
|
|
||||||
WITH IPv6CIDRtoIPv6Range(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 26) as ip_range SELECT COUNT(*) FROM ipv6_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
|
WITH IPv6CIDRToRange(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 26) as ip_range SELECT COUNT(*) FROM ipv6_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
|
||||||
|
|
||||||
WITH IPv6CIDRtoIPv6Range(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 64) as ip_range SELECT COUNT(*) FROM ipv6_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
|
WITH IPv6CIDRToRange(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 64) as ip_range SELECT COUNT(*) FROM ipv6_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
|
||||||
|
|
||||||
WITH IPv6CIDRtoIPv6Range(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 0) as ip_range SELECT COUNT(*) FROM ipv6_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
|
WITH IPv6CIDRToRange(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 0) as ip_range SELECT COUNT(*) FROM ipv6_range WHERE ip BETWEEN tupleElement(ip_range, 1) AND tupleElement(ip_range, 2);
|
||||||
|
|
||||||
SELECT IPv6NumToString(ip), cidr, IPv6CIDRtoIPv6Range(ip, cidr) FROM ipv6_range;
|
SELECT IPv6NumToString(ip), cidr, IPv6CIDRToRange(ip, cidr) FROM ipv6_range;
|
||||||
|
|
||||||
DROP TABLE ipv6_range;
|
DROP TABLE ipv6_range;
|
||||||
|
|
||||||
SELECT IPv6CIDRtoIPv6Range(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 0);
|
SELECT IPv6CIDRToRange(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 0);
|
||||||
SELECT IPv6CIDRtoIPv6Range(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 128);
|
SELECT IPv6CIDRToRange(IPv6StringToNum('2001:0db8:0000:85a3:0000:0000:ac1f:8001'), 128);
|
||||||
SELECT IPv6CIDRtoIPv6Range(IPv6StringToNum('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), 64);
|
SELECT IPv6CIDRToRange(IPv6StringToNum('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), 64);
|
||||||
SELECT IPv6CIDRtoIPv6Range(IPv6StringToNum('0000:0000:0000:0000:0000:0000:0000:0000'), 8);
|
SELECT IPv6CIDRToRange(IPv6StringToNum('0000:0000:0000:0000:0000:0000:0000:0000'), 8);
|
||||||
SELECT IPv6CIDRtoIPv6Range(IPv6StringToNum('ffff:0000:0000:0000:0000:0000:0000:0000'), 4);
|
SELECT IPv6CIDRToRange(IPv6StringToNum('ffff:0000:0000:0000:0000:0000:0000:0000'), 4);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user