aboutsummaryrefslogtreecommitdiff
path: root/contrib/btree_gist/btree_macaddr8.c
diff options
context:
space:
mode:
authorStephen Frost <sfrost@snowman.net>2017-03-15 11:16:25 -0400
committerStephen Frost <sfrost@snowman.net>2017-03-15 11:16:25 -0400
commitc7a9fa399d557c6366222e90b35db31e45d25678 (patch)
tree1c66b20d56331d8ab5160eb75ba37c9e6b8d929e /contrib/btree_gist/btree_macaddr8.c
parent42bdaebf161841c8e248b197b7319779b8730323 (diff)
downloadpostgresql-c7a9fa399d557c6366222e90b35db31e45d25678.tar.gz
postgresql-c7a9fa399d557c6366222e90b35db31e45d25678.zip
Add support for EUI-64 MAC addresses as macaddr8
This adds in support for EUI-64 MAC addresses by adding a new data type called 'macaddr8' (using our usual convention of indicating the number of bytes stored). This was largely a copy-and-paste from the macaddr data type, with appropriate adjustments for having 8 bytes instead of 6 and adding support for converting a provided EUI-48 (6 byte format) to the EUI-64 format. Conversion from EUI-48 to EUI-64 inserts FFFE as the 4th and 5th bytes but does not perform the IPv6 modified EUI-64 action of flipping the 7th bit, but we add a function to perform that specific action for the user as it may be commonly done by users who wish to calculate their IPv6 address based on their network prefix and 48-bit MAC address. Author: Haribabu Kommi, with a good bit of rework of macaddr8_in by me. Reviewed by: Vitaly Burovoy, Kuntal Ghosh Discussion: https://postgr.es/m/CAJrrPGcUi8ZH+KkK+=TctNQ+EfkeCEHtMU_yo1mvX8hsk_ghNQ@mail.gmail.com
Diffstat (limited to 'contrib/btree_gist/btree_macaddr8.c')
-rw-r--r--contrib/btree_gist/btree_macaddr8.c200
1 files changed, 200 insertions, 0 deletions
diff --git a/contrib/btree_gist/btree_macaddr8.c b/contrib/btree_gist/btree_macaddr8.c
new file mode 100644
index 00000000000..13238efe328
--- /dev/null
+++ b/contrib/btree_gist/btree_macaddr8.c
@@ -0,0 +1,200 @@
+/*
+ * contrib/btree_gist/btree_macaddr8.c
+ */
+#include "postgres.h"
+
+#include "btree_gist.h"
+#include "btree_utils_num.h"
+#include "utils/builtins.h"
+#include "utils/inet.h"
+
+typedef struct
+{
+ macaddr8 lower;
+ macaddr8 upper;
+ /* make struct size = sizeof(gbtreekey16) */
+} mac8KEY;
+
+/*
+** OID ops
+*/
+PG_FUNCTION_INFO_V1(gbt_macad8_compress);
+PG_FUNCTION_INFO_V1(gbt_macad8_fetch);
+PG_FUNCTION_INFO_V1(gbt_macad8_union);
+PG_FUNCTION_INFO_V1(gbt_macad8_picksplit);
+PG_FUNCTION_INFO_V1(gbt_macad8_consistent);
+PG_FUNCTION_INFO_V1(gbt_macad8_penalty);
+PG_FUNCTION_INFO_V1(gbt_macad8_same);
+
+
+static bool
+gbt_macad8gt(const void *a, const void *b)
+{
+ return DatumGetBool(DirectFunctionCall2(macaddr8_gt, PointerGetDatum(a), PointerGetDatum(b)));
+}
+static bool
+gbt_macad8ge(const void *a, const void *b)
+{
+ return DatumGetBool(DirectFunctionCall2(macaddr8_ge, PointerGetDatum(a), PointerGetDatum(b)));
+}
+
+static bool
+gbt_macad8eq(const void *a, const void *b)
+{
+ return DatumGetBool(DirectFunctionCall2(macaddr8_eq, PointerGetDatum(a), PointerGetDatum(b)));
+}
+
+static bool
+gbt_macad8le(const void *a, const void *b)
+{
+ return DatumGetBool(DirectFunctionCall2(macaddr8_le, PointerGetDatum(a), PointerGetDatum(b)));
+}
+
+static bool
+gbt_macad8lt(const void *a, const void *b)
+{
+ return DatumGetBool(DirectFunctionCall2(macaddr8_lt, PointerGetDatum(a), PointerGetDatum(b)));
+}
+
+
+static int
+gbt_macad8key_cmp(const void *a, const void *b)
+{
+ mac8KEY *ia = (mac8KEY *) (((const Nsrt *) a)->t);
+ mac8KEY *ib = (mac8KEY *) (((const Nsrt *) b)->t);
+ int res;
+
+ res = DatumGetInt32(DirectFunctionCall2(macaddr8_cmp, Macaddr8PGetDatum(&ia->lower), Macaddr8PGetDatum(&ib->lower)));
+ if (res == 0)
+ return DatumGetInt32(DirectFunctionCall2(macaddr8_cmp, Macaddr8PGetDatum(&ia->upper), Macaddr8PGetDatum(&ib->upper)));
+
+ return res;
+}
+
+
+static const gbtree_ninfo tinfo =
+{
+ gbt_t_macad8,
+ sizeof(macaddr8),
+ 16, /* sizeof(gbtreekey16) */
+ gbt_macad8gt,
+ gbt_macad8ge,
+ gbt_macad8eq,
+ gbt_macad8le,
+ gbt_macad8lt,
+ gbt_macad8key_cmp,
+ NULL
+};
+
+
+/**************************************************
+ * macaddr ops
+ **************************************************/
+
+
+
+static uint64
+mac8_2_uint64(macaddr8 *m)
+{
+ unsigned char *mi = (unsigned char *) m;
+ uint64 res = 0;
+ int i;
+
+ for (i = 0; i < 8; i++)
+ res += (((uint64) mi[i]) << ((uint64) ((7 - i) * 8)));
+ return res;
+}
+
+
+
+Datum
+gbt_macad8_compress(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+
+ PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
+}
+
+Datum
+gbt_macad8_fetch(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+
+ PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
+}
+
+Datum
+gbt_macad8_consistent(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ macaddr8 *query = (macaddr8 *) PG_GETARG_POINTER(1);
+ StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+
+ /* Oid subtype = PG_GETARG_OID(3); */
+ bool *recheck = (bool *) PG_GETARG_POINTER(4);
+ mac8KEY *kkk = (mac8KEY *) DatumGetPointer(entry->key);
+ GBT_NUMKEY_R key;
+
+ /* All cases served by this function are exact */
+ *recheck = false;
+
+ key.lower = (GBT_NUMKEY *) &kkk->lower;
+ key.upper = (GBT_NUMKEY *) &kkk->upper;
+
+ PG_RETURN_BOOL(
+ gbt_num_consistent(&key, (void *) query, &strategy, GIST_LEAF(entry), &tinfo)
+ );
+}
+
+
+Datum
+gbt_macad8_union(PG_FUNCTION_ARGS)
+{
+ GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+ void *out = palloc0(sizeof(mac8KEY));
+
+ *(int *) PG_GETARG_POINTER(1) = sizeof(mac8KEY);
+ PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
+}
+
+
+Datum
+gbt_macad8_penalty(PG_FUNCTION_ARGS)
+{
+ mac8KEY *origentry = (mac8KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
+ mac8KEY *newentry = (mac8KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
+ float *result = (float *) PG_GETARG_POINTER(2);
+ uint64 iorg[2],
+ inew[2];
+
+ iorg[0] = mac8_2_uint64(&origentry->lower);
+ iorg[1] = mac8_2_uint64(&origentry->upper);
+ inew[0] = mac8_2_uint64(&newentry->lower);
+ inew[1] = mac8_2_uint64(&newentry->upper);
+
+ penalty_num(result, iorg[0], iorg[1], inew[0], inew[1]);
+
+ PG_RETURN_POINTER(result);
+
+}
+
+Datum
+gbt_macad8_picksplit(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_POINTER(gbt_num_picksplit(
+ (GistEntryVector *) PG_GETARG_POINTER(0),
+ (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
+ &tinfo
+ ));
+}
+
+Datum
+gbt_macad8_same(PG_FUNCTION_ARGS)
+{
+ mac8KEY *b1 = (mac8KEY *) PG_GETARG_POINTER(0);
+ mac8KEY *b2 = (mac8KEY *) PG_GETARG_POINTER(1);
+ bool *result = (bool *) PG_GETARG_POINTER(2);
+
+ *result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
+ PG_RETURN_POINTER(result);
+}