Re: inet increment w/ int8

From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: "Ilya A(dot) Kovalenko" <shadow(at)oganer(dot)net>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: inet increment w/ int8
Date: 2005-04-19 00:58:01
Message-ID: 200504190058.j3J0w1Y21127@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers


Would you modify this so it can go in /contrib or pgfoundry? Is there
general interest for this?

---------------------------------------------------------------------------

Ilya A. Kovalenko wrote:
> Greetings,
>
> I suggest function for "inet" increment w/ int8 (signed).
>
> FUNCTION inet_inc(int, int8) RETURNS inet
>
> Function, useful for making address pools (using also
> existing "inet" compare functions to trap boundaries).
>
> Notes:
> This version lets address wrap around 0-*ff boundary.
> Uses couple of non-POSIX functions - betoh64() and htobe64()
> Tested on i386 with OpenBSD 3.7
> PostgreSQL 8.0.2
>
> -----------------------------------------------------
> #include <sys/types.h>
> #include <sys/socket.h>
> #include <netinet/in.h>
> #include <arpa/inet.h>
>
> #include "postgres.h" /* general Postgres declarations */
>
> #include "fmgr.h" /* for argument/result macros */
> #include "utils/inet.h"
>
> Datum inet_inc(PG_FUNCTION_ARGS);
>
> //------ stolen from backend/utils/adt/network.c --------
>
> #define ip_family(inetptr) \
> (((inet_struct *)VARDATA(inetptr))->family)
> #define ip_bits(inetptr) \
> (((inet_struct *)VARDATA(inetptr))->bits)
> #define ip_type(inetptr) \
> (((inet_struct *)VARDATA(inetptr))->type)
> #define ip_addr(inetptr) \
> (((inet_struct *)VARDATA(inetptr))->ipaddr)
> #define ip_maxbits(inetptr) \
> (ip_family(inetptr) == PGSQL_AF_INET ? 32 : 128)
>
> static int
> ip_addrsize(inet *inetptr)
> {
> switch (ip_family(inetptr))
> {
> case PGSQL_AF_INET:
> return 4;
> case PGSQL_AF_INET6:
> return 16;
> default:
> return 0;
> }
> }
> //-------------------------------------------------------
>
> PG_FUNCTION_INFO_V1(inet_inc);
>
> Datum
> inet_inc(PG_FUNCTION_ARGS)
> {
> inet *src = PG_GETARG_INET_P(0);
> int64 arg = PG_GETARG_INT64(1);
> inet *dst;
> uint64 wsp;
>
> // allocate destination structure
> dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
>
> // copy to destination
> *((inet_struct *)VARDATA(dst)) = *((inet_struct *)VARDATA(src));
>
> if (ip_family(dst) == PGSQL_AF_INET)
> {
> // Increment v4 address w/ item truncated to 32 bits
> *((uint32*)(ip_addr(dst))) =
> htonl(ntohl(*((int32*)(ip_addr(dst)))) + (int32)arg);
> }
> else
> {
> // Increment v6 address low qword (store to workspace)
> wsp = htobe64(betoh64(*((int64*)(ip_addr(dst) + 8))) + arg);
> *((uint64*)(ip_addr(dst) + 8)) = wsp;
>
> // Carry/borrow high qword
> if ( arg > 0 && wsp < *((uint64*)(ip_addr(src) + 8)) )
> { *((int64*)(ip_addr(dst))) =
> htobe64(betoh64(*((int64*)(ip_addr(dst)))) + 1);
> }
> else
> if ( arg < 0 && wsp > *((uint64*)(ip_addr(src) + 8)) )
> { *((int64*)(ip_addr(dst))) =
> htobe64(betoh64(*((int64*)(ip_addr(dst)))) - 1);
> }
> }
>
> // Return result
> VARATT_SIZEP(dst) = VARHDRSZ
> + ((char *) ip_addr(dst) - (char *) VARDATA(dst))
> + ip_addrsize(dst);
>
> PG_RETURN_INET_P(dst);
>
> }
> -----------------------------------------------------
>
> Thank you
>
> Ilya A. Kovalenko (mailto:shadow(at)oganer(dot)net)
> SpecialEQ SW section
> JSC Oganer-Service
>
> P.S. Treat as Public Domain
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Don't 'kill -9' the postmaster
>

--
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Bruce Momjian 2005-04-19 01:25:27 Re: Problem with PITR recovery
Previous Message Simon Riggs 2005-04-19 00:25:28 Re: Problem with PITR recovery