1996-07-09 08:22:35 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* arrayutils.c--
|
|
|
|
* This file contains some support routines required for array functions.
|
|
|
|
*
|
|
|
|
* Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
1996-11-10 04:06:38 +01:00
|
|
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayutils.c,v 1.3 1996/11/10 03:03:03 momjian Exp $
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define WEAK_C_OPTIMIZER
|
|
|
|
|
1996-11-06 07:52:23 +01:00
|
|
|
#include "postgres.h"
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1996-11-10 04:06:38 +01:00
|
|
|
#include "utils/array.h"
|
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
int
|
|
|
|
GetOffset(int n, int dim[], int lb[], int indx[])
|
|
|
|
{
|
|
|
|
int i, scale, offset;
|
|
|
|
for (i = n-1, scale = 1, offset = 0; i >= 0; scale*=dim[i--])
|
|
|
|
offset += (indx[i] - lb[i])*scale;
|
|
|
|
return offset ;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
getNitems(int n, int a[])
|
|
|
|
{
|
|
|
|
int i, ret;
|
|
|
|
for (i = 0, ret = 1; i < n; ret *= a[i++]);
|
|
|
|
if (n == 0) ret = 0;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
compute_size(int st[], int endp[], int n, int base)
|
|
|
|
{
|
|
|
|
int i, ret;
|
|
|
|
for (i = 0, ret = base; i < n; i++)
|
|
|
|
ret *= (endp[i] - st[i] + 1);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
mda_get_offset_values(int n, int dist[], int PC[], int span[])
|
|
|
|
{
|
|
|
|
int i, j;
|
|
|
|
for (j = n-2, dist[n-1]=0; j >= 0; j--)
|
|
|
|
for (i = j+1, dist[j] = PC[j]-1; i < n;
|
|
|
|
dist[j] -= (span[i] - 1)*PC[i], i++);
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
mda_get_prod(int n, int range[], int P[])
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i= n-2, P[n-1] = 1; i >= 0; i--)
|
|
|
|
P[i] = P[i+1] * range[i + 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
tuple2linear(int n, int tup[], int scale[])
|
|
|
|
{
|
|
|
|
int i, lin;
|
|
|
|
for (i= lin = 0; i < n; i++)
|
|
|
|
lin += tup[i]*scale[i];
|
|
|
|
return lin;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
array2chunk_coord(int n, int C[], int a_coord[], int c_coord[])
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i= 0; i < n; i++)
|
|
|
|
c_coord[i] = a_coord[i]/C[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 0 if no next tuple exists
|
|
|
|
1 otherwise
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
int
|
|
|
|
next_tuple(int n, int curr[], int span[])
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!n) return(-1);
|
|
|
|
curr[n-1] = (curr[n-1]+1)%span[n-1];
|
|
|
|
for (i = n-1; i*(!curr[i]); i--)
|
|
|
|
curr[i-1] = (curr[i-1]+1)%span[i-1];
|
|
|
|
|
|
|
|
if (i)
|
|
|
|
return(i);
|
|
|
|
if (curr[0])
|
|
|
|
return(0);
|
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
|