summaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/arrayutils.c
blob: a4253f983fc354e383f4c67834666fc35e71bd1e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*-------------------------------------------------------------------------
 *
 * arrayutils.c--
 *	  This file contains some support routines required for array functions.
 *
 * Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayutils.c,v 1.6 1998/09/01 03:25:47 momjian Exp $
 *
 *-------------------------------------------------------------------------
 */

#define WEAK_C_OPTIMIZER

#include "postgres.h"

#include "utils/array.h"

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;
}