Index: contrib/intarray/_int_tool.c =================================================================== RCS file: /projects/cvsroot/pgsql/contrib/intarray/_int_tool.c,v retrieving revision 1.6 diff -c -r1.6 _int_tool.c *** contrib/intarray/_int_tool.c 19 Nov 2005 03:00:09 -0000 1.6 --- contrib/intarray/_int_tool.c 6 May 2006 17:49:13 -0000 *************** *** 94,103 **** if (ARRISVOID(b)) r = copy_intArrayType(a); ! if (r) ! dr = ARRPTR(r); else { na = ARRNELEMS(a); nb = ARRNELEMS(b); da = ARRPTR(a); --- 94,108 ---- if (ARRISVOID(b)) r = copy_intArrayType(a); ! if (r) /* Only one of the arrays isn't void and it's assigned to r. */ ! { ! if (ARRNELEMS(r) > 1) ! r = _int_unique(r); /* Remove repetitive values. */ ! } else { + int k; + na = ARRNELEMS(a); nb = ARRNELEMS(b); da = ARRPTR(a); *************** *** 106,128 **** r = new_intArrayType(na + nb); dr = ARRPTR(r); ! /* union */ ! i = j = 0; ! while (i < na && j < nb) ! if (da[i] < db[j]) ! *dr++ = da[i++]; ! else ! *dr++ = db[j++]; ! ! while (i < na) ! *dr++ = da[i++]; ! while (j < nb) ! *dr++ = db[j++]; ! } ! if (ARRNELEMS(r) > 1) ! r = _int_unique(r); return r; } --- 111,164 ---- r = new_intArrayType(na + nb); dr = ARRPTR(r); ! /* Move i to next new integer in the array. */ ! #define NEXT_NEW(arr, len, i) \ ! if (i < len) \ ! { \ ! while (++i < len) \ ! if (arr[i] != arr[i-1]) \ ! break; \ } + + /* + * Form sorted union of arrays A and B. + * (Repetitive values will be discarded.) + */ + for (i = j = k = 0; i < na || j < nb; k++) + { + if (i >= na) /* A is exhausted. */ + { + dr[k] = db[j]; + NEXT_NEW(db, nb, j); + } + else if (j >= nb) /* B is exhausted. */ + { + dr[k] = da[i]; + NEXT_NEW(da, na, i); + } + else /* a[] and b[] still isn't exhausted. */ + { + if (da[i] < db[j]) + { + dr[k] = da[i]; + NEXT_NEW(da, na, i); + } + else if (da[i] > db[j]) + { + dr[k] = db[j]; + NEXT_NEW(db, nb, j); + } + else + { + dr[k] = da[i]; + NEXT_NEW(da, na, i); + NEXT_NEW(db, nb, j); + } + } + } ! r = resize_intArrayType(r, k); ! } return r; }