Обсуждение: implemented missing bitSetBit() and bitGetBit()

Поиск
Список
Период
Сортировка

implemented missing bitSetBit() and bitGetBit()

От
David Helgason
Дата:
I needed these, so I went and implemented them myself. I have to admit 
I'm not so wise on PostgreSQL backend stuff, and so I abstained from 
editing the fmgrtab.c and postgres.bki.

Sorry for that, but it just seemed too complicated. Perhaps there 
should really be a script to do this? I could imagine I'm not the only 
one slightly daunted by these files...

There's seems to be no reason for changing the docs since the functions 
are documented as existing :)
I didn't add the other functions that one might expect to exist 
(get-/set_byte and others), since I don't really need them.

I tested this code under 7.4 since that's what I've got here, but 
imagine nothing much changed in this end of the world for 7.4.1...

This is to be appended to src/backend/utils/adt/varbit.c:

/*------------------------------------------------------------- * bitSetBit * * Given an instance of type 'bit' creates
anew one with * the Nth bit set to the given value. * *-------------------------------------------------------------
*/
PG_FUNCTION_INFO_V1(bitSetBit);
Datum bitSetBit(PG_FUNCTION_ARGS)
{VarBit        *arg1 = PG_GETARG_VARBIT_P(0);int32            n = PG_GETARG_INT32(1);int32            newBit =
PG_GETARG_INT32(2);VarBit       *result;int                bitlen,                bytelen,                byteNo,
        bitNo;unsigned char    oldByte,                        newByte;
 
bitlen = VARBITLEN(arg1);

/* * sanity checks! */if (newBit != 0 && newBit != 1)    ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),            errmsg("new bit must be 0 or 1")));
 
if (n < 0 || n >= bitlen)    ereport(ERROR,            (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),             errmsg("bit
%doutside of valid range, 0..%d",                    n, bitlen - 1)));
 

/* Copy input bitstring */bytelen = VARSIZE(arg1);result = (VarBit *) palloc(bytelen);memcpy(VARBITS(result),
VARBITS(arg1),VARBITBYTES(arg1));VARATT_SIZEP(result) = bytelen;VARBITLEN(result) = bitlen;
 
/* * Update the bit. */byteNo = n / 8;bitNo = 7 - (n % 8);
oldByte = ((unsigned char *) VARBITS(result))[byteNo];
if (newBit == 0)    newByte = oldByte & (~(1 << bitNo));else    newByte = oldByte | (1 << bitNo);
((unsigned char *) VARBITS(result))[byteNo] = newByte;PG_RETURN_VARBIT_P(result);
}

/*------------------------------------------------------------- * bitGetBit * * Given an instance of type 'bit' returns
theNth bit. * *------------------------------------------------------------- */
 
PG_FUNCTION_INFO_V1(bitGetBit);
Datum bitGetBit(PG_FUNCTION_ARGS)
{VarBit        *arg1 = PG_GETARG_VARBIT_P(0);int32            n = PG_GETARG_INT32(1);int                bitlen,
      bytelen,                byteNo,                bitNo;unsigned char theByte;
 
bitlen = VARBITLEN(arg1);

/* * sanity check! */if (n < 0 || n >= bitlen)    ereport(ERROR,            (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
        errmsg("bit %d outside of valid range, 0..%d",                    n, bitlen - 1)));
 

/* * Find the target bit */byteNo = n / BITS_PER_BYTE;bitNo = BITS_PER_BYTE - 1 - (n % BITS_PER_BYTE);
theByte = ((unsigned char *) VARBITS(arg1))[byteNo];
/* * Shift a set bit to target position, & with the target byte, shift 
back * to get integer 0 or 1 */PG_RETURN_INT32((int)(theByte & (1 << bitNo)) >> bitNo);
}



Re: implemented missing bitSetBit() and bitGetBit()

От
Neil Conway
Дата:
David Helgason <david@uti.is> writes:
> I needed these, so I went and implemented them myself.

I didn't see any followup to this: do we want to include this in the
main tree, contrib/, or not at all?

-Neil (who has no opinion on the matter, but just wants to make sure
this doesn't fall through the cracks)



Re: implemented missing bitSetBit() and bitGetBit()

От
"Dann Corbit"
Дата:
Bit sets are remarkably useful functionality.   I suggest putting it
into the core product.

> -----Original Message-----
> From: Neil Conway [mailto:neilc@samurai.com]
> Sent: Wednesday, February 04, 2004 11:22 AM
> To: David Helgason
> Cc: pgsql-hackers@postgresql.org
> Subject: Re: [HACKERS] implemented missing bitSetBit() and bitGetBit()
>
>
> David Helgason <david@uti.is> writes:
> > I needed these, so I went and implemented them myself.
>
> I didn't see any followup to this: do we want to include this
> in the main tree, contrib/, or not at all?
>
> -Neil (who has no opinion on the matter, but just wants to
> make sure this doesn't fall through the cracks)
>
>
> ---------------------------(end of
> broadcast)---------------------------
> TIP 5: Have you checked our extensive FAQ?
>               http://www.postgresql.org/docs/faqs/FAQ.html


Re: implemented missing bitSetBit() and bitGetBit()

От
Peter Eisentraut
Дата:
Neil Conway wrote:
> David Helgason <david@uti.is> writes:
> > I needed these, so I went and implemented them myself.
>
> I didn't see any followup to this: do we want to include this in the
> main tree, contrib/, or not at all?

getbit sounds a lot like what substring() does.  So perhaps setbit could 
actually be handled by replace()?  That would be a more general 
solution (since it would handle more than one bit at a time).



Re: implemented missing bitSetBit() and bitGetBit()

От
David Helgason
Дата:
On 4. feb 2004, at 20:51, Peter Eisentraut wrote:
> Neil Conway wrote:
>> David Helgason <david@uti.is> writes:
>>> I needed these, so I went and implemented them myself.
>>
>> I didn't see any followup to this: do we want to include this in the
>> main tree, contrib/, or not at all?
> getbit sounds a lot like what substring() does.  So perhaps setbit 
> could
> actually be handled by replace()?  That would be a more general
> solution (since it would handle more than one bit at a time).

I sort of agree, but it's currently documented like I implemented it 
(afaics), so it's a simple thing to include.

I feel a bit bad for not having done a full patch with test-cases and 
.bki modifications etc., but it seemed a pretty daunting task (for my 
schedule at least).

Hope someone can use it though.

David Helgason,
Over the Edge Entertainments



Re: implemented missing bitSetBit() and bitGetBit()

От
Bruce Momjian
Дата:
Peter Eisentraut wrote:
> Neil Conway wrote:
> > David Helgason <david@uti.is> writes:
> > > I needed these, so I went and implemented them myself.
> >
> > I didn't see any followup to this: do we want to include this in the
> > main tree, contrib/, or not at all?
> 
> getbit sounds a lot like what substring() does.  So perhaps setbit could 
> actually be handled by replace()?  That would be a more general 
> solution (since it would handle more than one bit at a time).

Added to TODO:
* Allow substring/replace() to get/set bit values

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