2 |
Copyright (C) 2002 Free Software Foundation, Inc. |
Copyright (C) 2002 Free Software Foundation, Inc. |
3 |
Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz). |
Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz). |
4 |
|
|
5 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
6 |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
7 |
the Free Software Foundation; either version 2 of the License, or |
the Free Software Foundation; either version 2 of the License, or |
8 |
(at your option) any later version. |
(at your option) any later version. |
9 |
|
|
10 |
This program is distributed in the hope that it will be useful, |
This program is distributed in the hope that it will be useful, |
11 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 |
GNU General Public License for more details. |
GNU General Public License for more details. |
14 |
|
|
15 |
You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
16 |
along with this program; if not, write to the Free Software |
along with this program; if not, write to the Free Software |
17 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
18 |
|
|
19 |
#ifdef HAVE_CONFIG_H |
#ifdef HAVE_CONFIG_H |
20 |
#include "config.h" |
#include "config.h" |
21 |
#endif |
#endif |
22 |
|
|
23 |
#include "bitset.h" |
#include "bbitset.h" |
24 |
#include "obstack.h" |
#include "obstack.h" |
25 |
#include <stdlib.h> |
#include <stdlib.h> |
26 |
|
|
|
# if WITH_DMALLOC |
|
|
# define DMALLOC_FUNC_CHECK |
|
|
# include <dmalloc.h> |
|
|
# endif /* WITH_DMALLOC */ |
|
|
|
|
27 |
/* This file implements linked-list bitsets. These bitsets can be of |
/* This file implements linked-list bitsets. These bitsets can be of |
28 |
arbitrary length and are more efficient than arrays of bits for |
arbitrary length and are more efficient than arrays of bits for |
29 |
large sparse sets. |
large sparse sets. |
30 |
|
|
31 |
Usually if all the bits in an element are zero we remove the element |
Usually if all the bits in an element are zero we remove the element |
32 |
from the list. However, a side effect of the bit caching is that we |
from the list. However, a side effect of the bit caching is that we |
33 |
do not always notice when an element becomes zero. Hence the |
do not always notice when an element becomes zero. Hence the |
34 |
lbitset_weed function which removes zero elements. */ |
lbitset_weed function which removes zero elements. */ |
35 |
|
|
36 |
|
|
37 |
|
/* Number of words to use for each element. The larger the value the |
38 |
|
greater the size of the cache and the shorter the time to find a given bit |
39 |
|
but the more memory wasted for sparse bitsets and the longer the time |
40 |
|
to search for set bits. */ |
41 |
|
|
42 |
|
#ifndef LBITSET_ELT_WORDS |
43 |
|
#define LBITSET_ELT_WORDS 2 |
44 |
|
#endif |
45 |
|
|
46 |
|
typedef bitset_word lbitset_word; |
47 |
|
|
48 |
|
#define LBITSET_WORD_BITS BITSET_WORD_BITS |
49 |
|
|
50 |
|
/* Number of bits stored in each element. */ |
51 |
|
#define LBITSET_ELT_BITS \ |
52 |
|
((unsigned) (LBITSET_ELT_WORDS * LBITSET_WORD_BITS)) |
53 |
|
|
54 |
|
/* Lbitset element. We use an array of bits for each element. |
55 |
|
These are linked together in a doubly-linked list. */ |
56 |
|
typedef struct lbitset_elt_struct |
57 |
|
{ |
58 |
|
struct lbitset_elt_struct *next; /* Next element. */ |
59 |
|
struct lbitset_elt_struct *prev; /* Previous element. */ |
60 |
|
bitset_windex index; /* bitno / BITSET_WORD_BITS. */ |
61 |
|
bitset_word words[LBITSET_ELT_WORDS]; /* Bits that are set. */ |
62 |
|
} |
63 |
|
lbitset_elt; |
64 |
|
|
65 |
|
|
66 |
|
/* Head of lbitset linked list. */ |
67 |
|
typedef struct lbitset_struct |
68 |
|
{ |
69 |
|
lbitset_elt *head; /* First element in linked list. */ |
70 |
|
lbitset_elt *tail; /* Last element in linked list. */ |
71 |
|
} |
72 |
|
*lbitset; |
73 |
|
|
74 |
|
|
75 |
enum lbitset_find_mode {LBITSET_FIND, LBITSET_CREATE, LBITSET_SUBST}; |
struct bitset_struct |
76 |
|
{ |
77 |
|
struct bbitset_struct b; |
78 |
|
struct lbitset_struct l; |
79 |
|
}; |
80 |
|
|
81 |
static lbitset_elt lbitset_zero_elts[3]; /* Elements of all zero bits. */ |
|
82 |
|
enum lbitset_find_mode |
83 |
|
{ LBITSET_FIND, LBITSET_CREATE, LBITSET_SUBST }; |
84 |
|
|
85 |
|
static lbitset_elt lbitset_zero_elts[3]; /* Elements of all zero bits. */ |
86 |
|
|
87 |
/* Obstack to allocate bitset elements from. */ |
/* Obstack to allocate bitset elements from. */ |
88 |
static struct obstack lbitset_obstack; |
static struct obstack lbitset_obstack; |
89 |
static int lbitset_obstack_init = 0; |
static int lbitset_obstack_init = 0; |
90 |
static lbitset_elt *lbitset_free_list; /* Free list of bitset elements. */ |
static lbitset_elt *lbitset_free_list; /* Free list of bitset elements. */ |
91 |
|
|
92 |
static lbitset_elt *lbitset_elt_alloc PARAMS ((void)); |
static lbitset_elt *lbitset_elt_alloc PARAMS ((void)); |
93 |
static lbitset_elt *lbitset_elt_calloc PARAMS ((void)); |
static lbitset_elt *lbitset_elt_calloc PARAMS ((void)); |
100 |
|
|
101 |
static void lbitset_prune PARAMS ((bitset, lbitset_elt *)); |
static void lbitset_prune PARAMS ((bitset, lbitset_elt *)); |
102 |
static void lbitset_weed PARAMS ((bitset)); |
static void lbitset_weed PARAMS ((bitset)); |
103 |
static void lbitset_zero PARAMS((bitset)); |
static void lbitset_zero PARAMS ((bitset)); |
104 |
static int lbitset_equal_p PARAMS((bitset, bitset)); |
static int lbitset_equal_p PARAMS ((bitset, bitset)); |
105 |
static void lbitset_copy PARAMS((bitset, bitset)); |
static void lbitset_copy PARAMS ((bitset, bitset)); |
106 |
static int lbitset_copy_compare PARAMS((bitset, bitset)); |
static int lbitset_copy_compare PARAMS ((bitset, bitset)); |
107 |
static void lbitset_set PARAMS((bitset, bitset_bindex)); |
static void lbitset_set PARAMS ((bitset, bitset_bindex)); |
108 |
static void lbitset_reset PARAMS((bitset, bitset_bindex)); |
static void lbitset_reset PARAMS ((bitset, bitset_bindex)); |
109 |
static int lbitset_test PARAMS((bitset, bitset_bindex)); |
static int lbitset_test PARAMS ((bitset, bitset_bindex)); |
110 |
static int lbitset_size PARAMS((bitset)); |
static int lbitset_size PARAMS ((bitset)); |
111 |
static int lbitset_op1 PARAMS((bitset, enum bitset_ops)); |
static int lbitset_op1 PARAMS ((bitset, enum bitset_ops)); |
112 |
static int lbitset_op2 PARAMS((bitset, bitset, enum bitset_ops)); |
static int lbitset_op2 PARAMS ((bitset, bitset, enum bitset_ops)); |
113 |
static int lbitset_op3 PARAMS((bitset, bitset, bitset, enum bitset_ops)); |
static int lbitset_op3 PARAMS ((bitset, bitset, bitset, enum bitset_ops)); |
114 |
static int lbitset_op4 PARAMS((bitset, bitset, bitset, bitset, |
static int lbitset_list PARAMS ((bitset, bitset_bindex *, bitset_bindex, |
115 |
enum bitset_ops)); |
bitset_bindex *)); |
116 |
static int lbitset_list PARAMS((bitset, bitset_bindex *, bitset_bindex, |
static int lbitset_reverse_list |
117 |
bitset_bindex *)); |
PARAMS ((bitset, bitset_bindex *, bitset_bindex, bitset_bindex *)); |
118 |
static int lbitset_reverse_list PARAMS((bitset, bitset_bindex *, bitset_bindex, |
static void lbitset_free PARAMS ((bitset)); |
|
bitset_bindex *)); |
|
|
static void lbitset_free PARAMS((bitset)); |
|
119 |
|
|
120 |
|
|
121 |
#define LBITSET_CURRENT1(X) (lbitset_elt *)((char *)(X) + ((char *)&(((lbitset_elt *)(X))->next) - (char *)&(((lbitset_elt *)(X))->words))) |
#define LBITSET_CURRENT1(X) (lbitset_elt *)((char *)(X) + ((char *)&(((lbitset_elt *)(X))->next) - (char *)&(((lbitset_elt *)(X))->words))) |
122 |
|
|
123 |
#define LBITSET_CURRENT(X) LBITSET_CURRENT1((X)->cdata) |
#define LBITSET_CURRENT(X) LBITSET_CURRENT1((X)->b.cdata) |
124 |
|
|
125 |
#define LBITSET_HEAD(X) ((X)->u.l.head) |
#define LBITSET_HEAD(X) ((X)->l.head) |
126 |
#define LBITSET_TAIL(X) ((X)->u.l.tail) |
#define LBITSET_TAIL(X) ((X)->l.tail) |
127 |
|
|
128 |
/* Allocate a lbitset element. The bits are not cleared. */ |
/* Allocate a lbitset element. The bits are not cleared. */ |
129 |
static inline lbitset_elt * |
static inline lbitset_elt * |
146 |
lbitset_obstack_init = 1; |
lbitset_obstack_init = 1; |
147 |
|
|
148 |
/* Let particular systems override the size of a chunk. */ |
/* Let particular systems override the size of a chunk. */ |
149 |
|
|
150 |
#ifndef OBSTACK_CHUNK_SIZE |
#ifndef OBSTACK_CHUNK_SIZE |
151 |
#define OBSTACK_CHUNK_SIZE 0 |
#define OBSTACK_CHUNK_SIZE 0 |
152 |
#endif |
#endif |
153 |
|
|
154 |
/* Let them override the alloc and free routines too. */ |
/* Let them override the alloc and free routines too. */ |
155 |
|
|
156 |
#ifndef OBSTACK_CHUNK_ALLOC |
#ifndef OBSTACK_CHUNK_ALLOC |
157 |
#define OBSTACK_CHUNK_ALLOC xmalloc |
#define OBSTACK_CHUNK_ALLOC xmalloc |
158 |
#endif |
#endif |
159 |
|
|
160 |
#ifndef OBSTACK_CHUNK_FREE |
#ifndef OBSTACK_CHUNK_FREE |
161 |
#define OBSTACK_CHUNK_FREE free |
#define OBSTACK_CHUNK_FREE free |
162 |
#endif |
#endif |
167 |
|
|
168 |
obstack_specify_allocation (&lbitset_obstack, OBSTACK_CHUNK_SIZE, |
obstack_specify_allocation (&lbitset_obstack, OBSTACK_CHUNK_SIZE, |
169 |
__alignof__ (lbitset_elt), |
__alignof__ (lbitset_elt), |
170 |
(void *(*) PARAMS ((long))) OBSTACK_CHUNK_ALLOC, |
(void *(*)PARAMS ((long))) |
171 |
(void (*) PARAMS ((void *))) OBSTACK_CHUNK_FREE); |
OBSTACK_CHUNK_ALLOC, |
172 |
|
(void (*)PARAMS ((void *))) |
173 |
|
OBSTACK_CHUNK_FREE); |
174 |
} |
} |
175 |
|
|
176 |
/* Perhaps we should add a number of new elements to the free |
/* Perhaps we should add a number of new elements to the free |
177 |
list. */ |
list. */ |
178 |
elt = (lbitset_elt *) obstack_alloc (&lbitset_obstack, |
elt = (lbitset_elt *) obstack_alloc (&lbitset_obstack, |
179 |
sizeof (lbitset_elt)); |
sizeof (lbitset_elt)); |
180 |
} |
} |
231 |
{ |
{ |
232 |
if (next) |
if (next) |
233 |
{ |
{ |
234 |
bset->cdata = next->words; |
bset->b.cdata = next->words; |
235 |
bset->cindex = next->index; |
bset->b.cindex = next->index; |
236 |
} |
} |
237 |
else if (prev) |
else if (prev) |
238 |
{ |
{ |
239 |
bset->cdata = prev->words; |
bset->b.cdata = prev->words; |
240 |
bset->cindex = prev->index; |
bset->b.cindex = prev->index; |
241 |
} |
} |
242 |
else |
else |
243 |
{ |
{ |
244 |
bset->csize = 0; |
bset->b.csize = 0; |
245 |
bset->cdata = 0; |
bset->b.cdata = 0; |
246 |
} |
} |
247 |
} |
} |
248 |
|
|
260 |
lbitset_elt *next; |
lbitset_elt *next; |
261 |
|
|
262 |
if (!elt) |
if (!elt) |
263 |
return; |
return; |
264 |
|
|
265 |
if (elt->prev) |
if (elt->prev) |
266 |
{ |
{ |
267 |
LBITSET_TAIL (bset) = elt->prev; |
LBITSET_TAIL (bset) = elt->prev; |
268 |
bset->cdata = elt->prev->words; |
bset->b.cdata = elt->prev->words; |
269 |
bset->cindex = elt->prev->index; |
bset->b.cindex = elt->prev->index; |
270 |
elt->prev->next = 0; |
elt->prev->next = 0; |
271 |
} |
} |
272 |
else |
else |
273 |
{ |
{ |
274 |
LBITSET_HEAD (bset) = 0; |
LBITSET_HEAD (bset) = 0; |
275 |
LBITSET_TAIL (bset) = 0; |
LBITSET_TAIL (bset) = 0; |
276 |
bset->cdata = 0; |
bset->b.cdata = 0; |
277 |
bset->csize = 0; |
bset->b.csize = 0; |
278 |
} |
} |
279 |
|
|
280 |
for (; elt; elt = next) |
for (; elt; elt = next) |
281 |
{ |
{ |
310 |
lbitset_elt *ptr; |
lbitset_elt *ptr; |
311 |
lbitset_elt *current; |
lbitset_elt *current; |
312 |
|
|
313 |
if (bset->csize) |
if (bset->b.csize) |
314 |
current = LBITSET_CURRENT (bset); |
current = LBITSET_CURRENT (bset); |
315 |
else |
else |
316 |
current = LBITSET_HEAD (bset); |
current = LBITSET_HEAD (bset); |
317 |
|
|
318 |
/* If this is the first and only element, add it in. */ |
/* If this is the first and only element, add it in. */ |
319 |
if (LBITSET_HEAD (bset) == 0) |
if (LBITSET_HEAD (bset) == 0) |
325 |
|
|
326 |
/* If this index is less than that of the current element, it goes |
/* If this index is less than that of the current element, it goes |
327 |
somewhere before the current element. */ |
somewhere before the current element. */ |
328 |
else if (index < bset->cindex) |
else if (index < bset->b.cindex) |
329 |
{ |
{ |
330 |
for (ptr = current; |
for (ptr = current; |
331 |
ptr->prev && ptr->prev->index > index; |
ptr->prev && ptr->prev->index > index; ptr = ptr->prev) |
|
ptr = ptr->prev) |
|
332 |
continue; |
continue; |
333 |
|
|
334 |
if (ptr->prev) |
if (ptr->prev) |
345 |
else |
else |
346 |
{ |
{ |
347 |
for (ptr = current; |
for (ptr = current; |
348 |
ptr->next && ptr->next->index < index; |
ptr->next && ptr->next->index < index; ptr = ptr->next) |
|
ptr = ptr->next) |
|
349 |
continue; |
continue; |
350 |
|
|
351 |
if (ptr->next) |
if (ptr->next) |
359 |
} |
} |
360 |
|
|
361 |
/* Set up so this is the first element searched. */ |
/* Set up so this is the first element searched. */ |
362 |
bset->cindex = index; |
bset->b.cindex = index; |
363 |
bset->csize = LBITSET_ELT_WORDS; |
bset->b.csize = LBITSET_ELT_WORDS; |
364 |
bset->cdata = elt->words; |
bset->b.cdata = elt->words; |
365 |
} |
} |
366 |
|
|
367 |
|
|
374 |
lbitset_elt *elt; |
lbitset_elt *elt; |
375 |
lbitset_elt *current; |
lbitset_elt *current; |
376 |
|
|
377 |
if (bset->csize) |
if (bset->b.csize) |
378 |
{ |
{ |
379 |
current = LBITSET_CURRENT (bset); |
current = LBITSET_CURRENT (bset); |
380 |
/* Check if element is the cached element. */ |
/* Check if element is the cached element. */ |
381 |
if ((index - bset->cindex) < bset->csize) |
if ((index - bset->b.cindex) < bset->b.csize) |
382 |
return current; |
return current; |
383 |
} |
} |
384 |
else |
else |
388 |
|
|
389 |
if (current) |
if (current) |
390 |
{ |
{ |
391 |
if (index < bset->cindex) |
if (index < bset->b.cindex) |
392 |
{ |
{ |
393 |
for (elt = current; |
for (elt = current; |
394 |
elt->prev && elt->index > index; |
elt->prev && elt->index > index; elt = elt->prev) |
|
elt = elt->prev) |
|
395 |
continue; |
continue; |
396 |
} |
} |
397 |
else |
else |
406 |
we want, the one we want does not exist. */ |
we want, the one we want does not exist. */ |
407 |
if (elt && (index - elt->index) < LBITSET_ELT_WORDS) |
if (elt && (index - elt->index) < LBITSET_ELT_WORDS) |
408 |
{ |
{ |
409 |
bset->cindex = elt->index; |
bset->b.cindex = elt->index; |
410 |
bset->csize = LBITSET_ELT_WORDS; |
bset->b.csize = LBITSET_ELT_WORDS; |
411 |
bset->cdata = elt->words; |
bset->b.cdata = elt->words; |
412 |
return elt; |
return elt; |
413 |
} |
} |
414 |
} |
} |
492 |
if (delt->words[j] != selt->words[j]) |
if (delt->words[j] != selt->words[j]) |
493 |
return 0; |
return 0; |
494 |
} |
} |
495 |
return ! selt && ! delt; |
return !selt && !delt; |
496 |
} |
} |
497 |
|
|
498 |
|
|
533 |
} |
} |
534 |
LBITSET_TAIL (dst) = tmp; |
LBITSET_TAIL (dst) = tmp; |
535 |
|
|
536 |
dst->csize = LBITSET_ELT_WORDS; |
dst->b.csize = LBITSET_ELT_WORDS; |
537 |
dst->cdata = LBITSET_HEAD (dst)->words; |
dst->b.cdata = LBITSET_HEAD (dst)->words; |
538 |
dst->cindex = LBITSET_HEAD (dst)->index; |
dst->b.cindex = LBITSET_HEAD (dst)->index; |
539 |
} |
} |
540 |
|
|
541 |
|
|
549 |
if (src == dst) |
if (src == dst) |
550 |
return 0; |
return 0; |
551 |
|
|
552 |
if (! LBITSET_HEAD (dst)) |
if (!LBITSET_HEAD (dst)) |
553 |
{ |
{ |
554 |
lbitset_copy (dst, src); |
lbitset_copy (dst, src); |
555 |
return LBITSET_HEAD (src) != 0; |
return LBITSET_HEAD (src) != 0; |
572 |
|
|
573 |
elt = LBITSET_TAIL (src); |
elt = LBITSET_TAIL (src); |
574 |
if (!elt) |
if (!elt) |
575 |
return 0; |
return 0; |
576 |
|
|
577 |
/* Return current size of bitset in bits. */ |
/* Return current size of bitset in bits. */ |
578 |
return (elt->index + LBITSET_ELT_WORDS) * BITSET_WORD_BITS; |
return (elt->index + LBITSET_ELT_WORDS) * BITSET_WORD_BITS; |
589 |
|
|
590 |
lbitset_elt_find (dst, index, LBITSET_CREATE); |
lbitset_elt_find (dst, index, LBITSET_CREATE); |
591 |
|
|
592 |
dst->cdata[index - dst->cindex] |= (1 << (bitno % BITSET_WORD_BITS)); |
dst->b.cdata[index - dst->b.cindex] |= (1 << (bitno % BITSET_WORD_BITS)); |
593 |
} |
} |
594 |
|
|
595 |
|
|
602 |
bitset_windex index = bitno / BITSET_WORD_BITS; |
bitset_windex index = bitno / BITSET_WORD_BITS; |
603 |
|
|
604 |
if (!lbitset_elt_find (dst, index, LBITSET_FIND)) |
if (!lbitset_elt_find (dst, index, LBITSET_FIND)) |
605 |
return; |
return; |
606 |
|
|
607 |
dst->cdata[index - dst->cindex] &= ~(1 << (bitno % BITSET_WORD_BITS)); |
dst->b.cdata[index - dst->b.cindex] &= ~(1 << (bitno % BITSET_WORD_BITS)); |
608 |
|
|
609 |
/* If all the data is zero, perhaps we should unlink it now... */ |
/* If all the data is zero, perhaps we should unlink it now... */ |
610 |
} |
} |
621 |
if (!lbitset_elt_find (src, index, LBITSET_FIND)) |
if (!lbitset_elt_find (src, index, LBITSET_FIND)) |
622 |
return 0; |
return 0; |
623 |
|
|
624 |
return (src->cdata[index - src->cindex] >> (bitno % BITSET_WORD_BITS)) & 1; |
return (src->b. |
625 |
|
cdata[index - src->b.cindex] >> (bitno % BITSET_WORD_BITS)) & 1; |
626 |
} |
} |
627 |
|
|
628 |
|
|
635 |
|
|
636 |
|
|
637 |
/* Find list of up to NUM bits set in BSET starting from and including |
/* Find list of up to NUM bits set in BSET starting from and including |
638 |
*NEXT and store in array LIST. Return with actual number of bits |
*NEXT and store in array LIST. Return with actual number of bits |
639 |
found and with *NEXT indicating where search stopped. */ |
found and with *NEXT indicating where search stopped. */ |
640 |
static int |
static int |
641 |
lbitset_reverse_list (bset, list, num, next) |
lbitset_reverse_list (bset, list, num, next) |
642 |
bitset bset; |
bitset bset; |
662 |
rbitno = *next; |
rbitno = *next; |
663 |
|
|
664 |
if (rbitno >= n_bits) |
if (rbitno >= n_bits) |
665 |
return 0; |
return 0; |
666 |
|
|
667 |
bitno = n_bits - (rbitno + 1); |
bitno = n_bits - (rbitno + 1); |
668 |
|
|
688 |
|
|
689 |
for (; (index - elt->index) < LBITSET_ELT_WORDS; |
for (; (index - elt->index) < LBITSET_ELT_WORDS; |
690 |
index--, bitoff -= BITSET_WORD_BITS, |
index--, bitoff -= BITSET_WORD_BITS, |
691 |
bitcnt = BITSET_WORD_BITS - 1) |
bitcnt = BITSET_WORD_BITS - 1) |
692 |
{ |
{ |
693 |
word = srcp[index - elt->index] << (BITSET_WORD_BITS - 1 - bitcnt); |
word = |
694 |
|
srcp[index - elt->index] << (BITSET_WORD_BITS - 1 - bitcnt); |
695 |
|
|
696 |
for (; word; bitcnt--) |
for (; word; bitcnt--) |
697 |
{ |
{ |
722 |
|
|
723 |
|
|
724 |
/* Find list of up to NUM bits set in BSET starting from and including |
/* Find list of up to NUM bits set in BSET starting from and including |
725 |
*NEXT and store in array LIST. Return with actual number of bits |
*NEXT and store in array LIST. Return with actual number of bits |
726 |
found and with *NEXT indicating where search stopped. */ |
found and with *NEXT indicating where search stopped. */ |
727 |
static int |
static int |
728 |
lbitset_list (bset, list, num, next) |
lbitset_list (bset, list, num, next) |
729 |
bitset bset; |
bitset bset; |
740 |
|
|
741 |
head = LBITSET_HEAD (bset); |
head = LBITSET_HEAD (bset); |
742 |
if (!head) |
if (!head) |
743 |
return 0; |
return 0; |
744 |
|
|
745 |
bitno = *next; |
bitno = *next; |
746 |
count = 0; |
count = 0; |
824 |
word = srcp[0]; |
word = srcp[0]; |
825 |
if (word) |
if (word) |
826 |
{ |
{ |
827 |
if (! (word & 0xffff)) |
if (!(word & 0xffff)) |
828 |
{ |
{ |
829 |
word >>= 16; |
word >>= 16; |
830 |
bitno += 16; |
bitno += 16; |
831 |
} |
} |
832 |
if (! (word & 0xff)) |
if (!(word & 0xff)) |
833 |
{ |
{ |
834 |
word >>= 8; |
word >>= 8; |
835 |
bitno += 8; |
bitno += 8; |
847 |
word = srcp[1]; |
word = srcp[1]; |
848 |
if (word) |
if (word) |
849 |
{ |
{ |
850 |
if (! (word & 0xffff)) |
if (!(word & 0xffff)) |
851 |
{ |
{ |
852 |
word >>= 16; |
word >>= 16; |
853 |
bitno += 16; |
bitno += 16; |
867 |
word = srcp[i]; |
word = srcp[i]; |
868 |
if (word) |
if (word) |
869 |
{ |
{ |
870 |
if (! (word & 0xffff)) |
if (!(word & 0xffff)) |
871 |
{ |
{ |
872 |
word >>= 16; |
word >>= 16; |
873 |
bitno += 16; |
bitno += 16; |
874 |
} |
} |
875 |
if (! (word & 0xff)) |
if (!(word & 0xff)) |
876 |
{ |
{ |
877 |
word >>= 8; |
word >>= 8; |
878 |
bitno += 8; |
bitno += 8; |
938 |
|
|
939 |
switch (op) |
switch (op) |
940 |
{ |
{ |
941 |
case BITSET_ZERO: |
case BITSET_OP_ZERO: |
942 |
lbitset_zero (dst); |
lbitset_zero (dst); |
943 |
break; |
break; |
944 |
|
|
945 |
case BITSET_ONES: |
case BITSET_OP_ONES: |
946 |
/* This is a decidedly unfriendly operation for a linked list |
/* This is a decidedly unfriendly operation for a linked list |
947 |
bitset! */ |
bitset! */ |
948 |
elt = LBITSET_TAIL (dst); |
elt = LBITSET_TAIL (dst); |
959 |
} |
} |
960 |
break; |
break; |
961 |
|
|
962 |
case BITSET_EMPTY_P: |
case BITSET_OP_EMPTY_P: |
963 |
lbitset_weed (dst); |
lbitset_weed (dst); |
964 |
if (LBITSET_HEAD (dst)) |
if (LBITSET_HEAD (dst)) |
965 |
return 0; |
return 0; |
988 |
|
|
989 |
switch (op) |
switch (op) |
990 |
{ |
{ |
991 |
case BITSET_COPY: |
case BITSET_OP_COPY: |
992 |
lbitset_copy (dst, src); |
lbitset_copy (dst, src); |
993 |
break; |
break; |
994 |
|
|
995 |
case BITSET_NOT: |
case BITSET_OP_NOT: |
996 |
/* This is another unfriendly operation for a linked list |
/* This is another unfriendly operation for a linked list |
997 |
bitset! */ |
bitset! */ |
998 |
elt = LBITSET_TAIL (dst); |
elt = LBITSET_TAIL (dst); |
1014 |
lbitset_weed (dst); |
lbitset_weed (dst); |
1015 |
break; |
break; |
1016 |
|
|
1017 |
case BITSET_EQUAL_P: |
/* Return 1 if DST == SRC. */ |
1018 |
|
case BITSET_OP_EQUAL_P: |
1019 |
return lbitset_equal_p (dst, src); |
return lbitset_equal_p (dst, src); |
1020 |
break; |
break; |
1021 |
|
|
1022 |
case BITSET_SUBSET_P: |
/* Return 1 if DST == DST | SRC. */ |
1023 |
|
case BITSET_OP_SUBSET_P: |
1024 |
for (selt = LBITSET_HEAD (src), delt = LBITSET_HEAD (dst); |
for (selt = LBITSET_HEAD (src), delt = LBITSET_HEAD (dst); |
1025 |
selt || delt; selt = selt->next, delt = delt->next) |
selt || delt; selt = selt->next, delt = delt->next) |
1026 |
{ |
{ |
1048 |
} |
} |
1049 |
break; |
break; |
1050 |
|
|
1051 |
|
/* Return 1 if DST & SRC == 0. */ |
1052 |
|
case BITSET_OP_DISJOINT_P: |
1053 |
|
for (selt = LBITSET_HEAD (src), delt = LBITSET_HEAD (dst); |
1054 |
|
selt && delt; selt = selt->next, delt = delt->next) |
1055 |
|
{ |
1056 |
|
if (selt->index != delt->index) |
1057 |
|
{ |
1058 |
|
if (selt->index < delt->index) |
1059 |
|
{ |
1060 |
|
lbitset_zero_elts[2].next = delt; |
1061 |
|
delt = &lbitset_zero_elts[2]; |
1062 |
|
} |
1063 |
|
else |
1064 |
|
{ |
1065 |
|
lbitset_zero_elts[1].next = selt; |
1066 |
|
selt = &lbitset_zero_elts[1]; |
1067 |
|
} |
1068 |
|
} |
1069 |
|
|
1070 |
|
for (j = 0; j < LBITSET_ELT_WORDS; j++) |
1071 |
|
if (selt->words[j] & delt->words[j]) |
1072 |
|
return 0; |
1073 |
|
} |
1074 |
|
break; |
1075 |
|
|
1076 |
default: |
default: |
1077 |
abort (); |
abort (); |
1078 |
} |
} |
1106 |
/* Fast track common, simple cases. */ |
/* Fast track common, simple cases. */ |
1107 |
if (!selt2) |
if (!selt2) |
1108 |
{ |
{ |
1109 |
if (op == BITSET_AND) |
if (op == BITSET_OP_AND) |
1110 |
{ |
{ |
1111 |
lbitset_weed (dst); |
lbitset_weed (dst); |
1112 |
changed = ! LBITSET_HEAD (dst); |
changed = !LBITSET_HEAD (dst); |
1113 |
lbitset_zero (dst); |
lbitset_zero (dst); |
1114 |
return changed; |
return changed; |
1115 |
} |
} |
1116 |
else if (op == BITSET_ANDN || op == BITSET_OR || op == BITSET_XOR) |
else if (op == BITSET_OP_ANDN || op == BITSET_OP_OR |
1117 |
|
|| op == BITSET_OP_XOR) |
1118 |
{ |
{ |
1119 |
return lbitset_copy_compare (dst, src1); |
return lbitset_copy_compare (dst, src1); |
1120 |
} |
} |
1121 |
} |
} |
1122 |
else if (!selt1) |
else if (!selt1) |
1123 |
{ |
{ |
1124 |
if (op == BITSET_AND || op == BITSET_ANDN) |
if (op == BITSET_OP_AND || op == BITSET_OP_ANDN) |
1125 |
{ |
{ |
1126 |
lbitset_weed (dst); |
lbitset_weed (dst); |
1127 |
changed = ! LBITSET_HEAD (dst); |
changed = !LBITSET_HEAD (dst); |
1128 |
lbitset_zero (dst); |
lbitset_zero (dst); |
1129 |
return changed; |
return changed; |
1130 |
} |
} |
1131 |
else if (op == BITSET_OR || op == BITSET_XOR) |
else if (op == BITSET_OP_OR || op == BITSET_OP_XOR) |
1132 |
{ |
{ |
1133 |
return lbitset_copy_compare (dst, src2); |
return lbitset_copy_compare (dst, src2); |
1134 |
} |
} |
1135 |
} |
} |
1136 |
|
|
|
|
|
1137 |
LBITSET_HEAD (dst) = 0; |
LBITSET_HEAD (dst) = 0; |
1138 |
dst->csize = 0; |
dst->b.csize = 0; |
1139 |
|
|
1140 |
index1 = (selt1) ? selt1->index : BITSET_INDEX_MAX; |
index1 = (selt1) ? selt1->index : BITSET_INDEX_MAX; |
1141 |
index2 = (selt2) ? selt2->index : BITSET_INDEX_MAX; |
index2 = (selt2) ? selt2->index : BITSET_INDEX_MAX; |
1195 |
dstp = dtmp->words; |
dstp = dtmp->words; |
1196 |
switch (op) |
switch (op) |
1197 |
{ |
{ |
1198 |
case BITSET_OR: |
case BITSET_OP_OR: |
1199 |
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++) |
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++) |
1200 |
{ |
{ |
1201 |
bitset_word tmp = *srcp1++ | *srcp2++; |
bitset_word tmp = *srcp1++ | *srcp2++; |
1208 |
} |
} |
1209 |
break; |
break; |
1210 |
|
|
1211 |
case BITSET_AND: |
case BITSET_OP_AND: |
1212 |
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++) |
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++) |
1213 |
{ |
{ |
1214 |
bitset_word tmp = *srcp1++ & *srcp2++; |
bitset_word tmp = *srcp1++ & *srcp2++; |
1221 |
} |
} |
1222 |
break; |
break; |
1223 |
|
|
1224 |
case BITSET_XOR: |
case BITSET_OP_XOR: |
1225 |
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++) |
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++) |
1226 |
{ |
{ |
1227 |
bitset_word tmp = *srcp1++ ^ *srcp2++; |
bitset_word tmp = *srcp1++ ^ *srcp2++; |
1234 |
} |
} |
1235 |
break; |
break; |
1236 |
|
|
1237 |
case BITSET_ANDN: |
case BITSET_OP_ANDN: |
1238 |
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++) |
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++) |
1239 |
{ |
{ |
1240 |
bitset_word tmp = *srcp1++ & ~(*srcp2++); |
bitset_word tmp = *srcp1++ & ~(*srcp2++); |
1247 |
} |
} |
1248 |
break; |
break; |
1249 |
|
|
1250 |
case BITSET_ORN: |
case BITSET_OP_ORN: |
1251 |
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++) |
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++) |
1252 |
{ |
{ |
1253 |
bitset_word tmp = *srcp1++ | ~(*srcp2++); |
bitset_word tmp = *srcp1++ | ~(*srcp2++); |
1264 |
abort (); |
abort (); |
1265 |
} |
} |
1266 |
|
|
1267 |
if (! lbitset_elt_zero_p (dtmp)) |
if (!lbitset_elt_zero_p (dtmp)) |
1268 |
{ |
{ |
1269 |
dtmp->index = index; |
dtmp->index = index; |
1270 |
/* Perhaps this could be optimised... */ |
/* Perhaps this could be optimised... */ |
1287 |
} |
} |
1288 |
|
|
1289 |
|
|
|
static int |
|
|
lbitset_op4 (dst, src1, src2, src3, op) |
|
|
bitset dst; |
|
|
bitset src1; |
|
|
bitset src2; |
|
|
bitset src3; |
|
|
enum bitset_ops op; |
|
|
{ |
|
|
int changed = 0; |
|
|
bitset tmp; |
|
|
|
|
|
#ifdef ENABLE_CHECKING |
|
|
/* Check for compatiblity. */ |
|
|
if (src1->ops != dst->ops || src2->ops != dst->ops || src3->ops != dst->ops) |
|
|
abort (); |
|
|
#endif |
|
|
|
|
|
tmp = bitset_create (BITSET_LIST, 0); |
|
|
|
|
|
switch (op) |
|
|
{ |
|
|
case BITSET_OR_AND: |
|
|
bitset_or (tmp, src1, src2); |
|
|
changed = bitset_and (dst, src3, tmp); |
|
|
break; |
|
|
|
|
|
case BITSET_AND_OR: |
|
|
bitset_and (tmp, src1, src2); |
|
|
changed = bitset_or (dst, src3, tmp); |
|
|
break; |
|
|
|
|
|
case BITSET_ANDN_OR: |
|
|
bitset_andn (tmp, src1, src2); |
|
|
changed = bitset_or (dst, src3, tmp); |
|
|
break; |
|
|
|
|
|
default: |
|
|
abort (); |
|
|
} |
|
|
|
|
|
bitset_free (tmp); |
|
|
return changed; |
|
|
} |
|
|
|
|
|
|
|
1290 |
/* Vector of operations for linked-list bitsets. */ |
/* Vector of operations for linked-list bitsets. */ |
1291 |
struct bitset_ops_struct lbitset_ops = |
struct bitset_ops_struct lbitset_ops = { |
1292 |
{ |
lbitset_set, |
1293 |
lbitset_set, |
lbitset_reset, |
1294 |
lbitset_reset, |
lbitset_test, |
1295 |
lbitset_test, |
lbitset_size, |
1296 |
lbitset_size, |
lbitset_op1, |
1297 |
lbitset_op1, |
lbitset_op2, |
1298 |
lbitset_op2, |
lbitset_op3, |
1299 |
lbitset_op3, |
bitset_op4, |
1300 |
lbitset_op4, |
lbitset_list, |
1301 |
lbitset_list, |
lbitset_reverse_list, |
1302 |
lbitset_reverse_list, |
lbitset_free, |
1303 |
lbitset_free, |
BITSET_LIST |
1304 |
BITSET_LIST |
}; |
|
}; |
|
1305 |
|
|
1306 |
|
|
1307 |
/* Return size of initial structure. */ |
/* Return size of initial structure. */ |
1320 |
bitset bset; |
bitset bset; |
1321 |
bitset_bindex n_bits ATTRIBUTE_UNUSED; |
bitset_bindex n_bits ATTRIBUTE_UNUSED; |
1322 |
{ |
{ |
1323 |
LBITSET_HEAD (bset) = 0; |
bset->b.ops = &lbitset_ops; |
|
LBITSET_TAIL (bset) = 0; |
|
|
|
|
|
bset->ops = &lbitset_ops; |
|
|
|
|
|
bset->cindex = 0; |
|
|
/* Disable cache until have some elements allocated. |
|
|
If we have variable length arrays, then we may |
|
|
need to allocate dummy element. */ |
|
|
bset->csize = 0; |
|
|
bset->cdata = 0; |
|
1324 |
return bset; |
return bset; |
1325 |
} |
} |
1326 |
|
|