1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-12 05:01:15 +03:00
Files
postgres/src/backend/utils/adt/arrayutils.c
PostgreSQL Daemon 2ff501590b Tag appropriate files for rc3
Also performed an initial run through of upgrading our Copyright date to
extend to 2005 ... first run here was very simple ... change everything
where: grep 1996-2004 && the word 'Copyright' ... scanned through the
generated list with 'less' first, and after, to make sure that I only
picked up the right entries ...
2004-12-31 22:04:05 +00:00

132 lines
2.9 KiB
C

/*-------------------------------------------------------------------------
*
* arrayutils.c
* This file contains some support routines required for array functions.
*
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayutils.c,v 1.18 2004/12/31 22:01:21 pgsql Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "utils/array.h"
/* Convert subscript list into linear element number (from 0) */
int
ArrayGetOffset(int n, int *dim, int *lb, int *indx)
{
int i,
scale = 1,
offset = 0;
for (i = n - 1; i >= 0; i--)
{
offset += (indx[i] - lb[i]) * scale;
scale *= dim[i];
}
return offset;
}
/* Same, but subscripts are assumed 0-based, and use a scale array
* instead of raw dimension data (see mda_get_prod to create scale array)
*/
int
ArrayGetOffset0(int n, int *tup, int *scale)
{
int i,
lin = 0;
for (i = 0; i < n; i++)
lin += tup[i] * scale[i];
return lin;
}
/* Convert array dimensions into number of elements */
int
ArrayGetNItems(int ndim, int *dims)
{
int i,
ret;
if (ndim <= 0)
return 0;
ret = 1;
for (i = 0; i < ndim; i++)
ret *= dims[i];
return ret;
}
/* Compute ranges (sub-array dimensions) for an array slice */
void
mda_get_range(int n, int *span, int *st, int *endp)
{
int i;
for (i = 0; i < n; i++)
span[i] = endp[i] - st[i] + 1;
}
/* Compute products of array dimensions, ie, scale factors for subscripts */
void
mda_get_prod(int n, int *range, int *prod)
{
int i;
prod[n - 1] = 1;
for (i = n - 2; i >= 0; i--)
prod[i] = prod[i + 1] * range[i + 1];
}
/* From products of whole-array dimensions and spans of a sub-array,
* compute offset distances needed to step through subarray within array
*/
void
mda_get_offset_values(int n, int *dist, int *prod, int *span)
{
int i,
j;
dist[n - 1] = 0;
for (j = n - 2; j >= 0; j--)
{
dist[j] = prod[j] - 1;
for (i = j + 1; i < n; i++)
dist[j] -= (span[i] - 1) * prod[i];
}
}
/*-----------------------------------------------------------------------------
generates the tuple that is lexicographically one greater than the current
n-tuple in "curr", with the restriction that the i-th element of "curr" is
less than the i-th element of "span".
Returns -1 if no next tuple exists, else the subscript position (0..n-1)
corresponding to the dimension to advance along.
-----------------------------------------------------------------------------
*/
int
mda_next_tuple(int n, int *curr, int *span)
{
int i;
if (n <= 0)
return -1;
curr[n - 1] = (curr[n - 1] + 1) % span[n - 1];
for (i = n - 1; i && curr[i] == 0; i--)
curr[i - 1] = (curr[i - 1] + 1) % span[i - 1];
if (i)
return i;
if (curr[0])
return 0;
return -1;
}