2 * This file has been modified for the cdrkit suite.
4 * The behaviour and appearence of the program code below can differ to a major
5 * extent from the version distributed by the original author(s).
7 * For details, see Changelog file distributed with the cdrkit package. If you
8 * received this file from another source then ask the distributing person for
9 * a log of modifications.
13 /* @(#)isort.c 1.14 04/02/20 J. Schilling from cdparanoia-III-alpha9.8 */
15 * Modifications to make the code portable Copyright (c) 2002 J. Schilling
18 * CopyPolicy: GNU Public License 2 applies
19 * Copyright (C) by Monty (xiphmont@mit.edu)
21 * sorted vector abstraction for paranoia
26 * Old isort got a bit complex. This re-constrains complexity to
27 * give a go at speed through a more alpha-6-like mechanism.
39 sort_info *sort_alloc(long size);
40 void sort_unsortall(sort_info * i);
41 void sort_free(sort_info * i);
42 void sort_sort(sort_info * i, long sortlo, long sorthi);
43 void sort_setup(sort_info * i, Int16_t * vector, long *abspos, long size,
44 long sortlo, long sorthi);
45 sort_link *sort_getmatch(sort_info * i, long post, long overlap, int value);
46 sort_link *sort_nextmatch(sort_info * i, sort_link * prev);
49 sort_info *sort_alloc(long size)
51 sort_info *ret = _pcalloc(1, sizeof (sort_info));
58 ret->head = _pcalloc(65536, sizeof (sort_link *));
59 ret->bucketusage = _pmalloc(65536 * sizeof (long));
60 ret->revindex = _pcalloc(size, sizeof (sort_link));
66 void sort_unsortall(sort_info *i)
68 if (i->lastbucket > 2000) { /* a guess */
69 memset(i->head, 0, 65536 * sizeof (sort_link *));
73 for (b = 0; b < i->lastbucket; b++)
74 i->head[i->bucketusage[b]] = NULL;
81 void sort_free(sort_info *i)
85 _pfree(i->bucketusage);
89 void sort_sort(sort_info *i, long sortlo, long sorthi)
93 for (j = sorthi - 1; j >= sortlo; j--) {
94 sort_link **hv = i->head + i->vector[j] + 32768;
95 sort_link *l = i->revindex + j;
98 i->bucketusage[i->lastbucket] = i->vector[j] + 32768;
108 * size *must* be less than i->maxsize
110 void sort_setup(sort_info *i, Int16_t *vector, long *abspos, long size,
111 long sortlo, long sorthi)
113 if (i->sortbegin != -1)
120 i->lo = min(size, max(sortlo - *abspos, 0));
121 i->hi = max(0, min(sorthi - *abspos, size));
124 sort_link *sort_getmatch(sort_info *i, long post, long overlap, int value)
128 if (i->sortbegin == -1)
129 sort_sort(i, i->lo, i->hi);
131 * Now we reuse lo and hi
133 post = max(0, min(i->size, post));
134 i->val = value + 32768;
135 i->lo = max(0, post - overlap); /* absolute position */
136 i->hi = min(i->size, post + overlap); /* absolute position */
138 ret = i->head[i->val];
140 if (ipos(i, ret) < i->lo) {
143 if (ipos(i, ret) >= i->hi)
148 /* i->head[i->val]=ret; */
152 sort_link *sort_nextmatch(sort_info *i, sort_link *prev)
154 sort_link *ret = prev->next;
156 if (!ret || ipos(i, ret) >= i->hi)