CUBRID Engine  latest
query_bitset.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * query_bitset.c - Bitset operations for sets implemented as machine words
21  */
22 
23 #ident "$Id$"
24 
25 #include "config.h"
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 
31 #include "query_bitset.h"
32 
33 #include "memory_alloc.h"
34 
35 #define NBYTES(n) ((n) * sizeof(BITSET_CARRIER))
36 #define NELEMS(n) ((n) * _WORDSIZE)
37 
38 #define bitset_malloc(env, size) malloc(size)
39 #define bitset_free(ptr) free_and_init(ptr)
40 
41 /*
42  * The number of one bits in a four-bit nibble.
43  */
44 static const char nbits[] = {
45  0, /* 0000 */
46  1, /* 0001 */
47  1, /* 0010 */
48  2, /* 0011 */
49  1, /* 0100 */
50  2, /* 0101 */
51  2, /* 0110 */
52  3, /* 0111 */
53  1, /* 1000 */
54  2, /* 1001 */
55  2, /* 1010 */
56  3, /* 1011 */
57  2, /* 1100 */
58  3, /* 1101 */
59  3, /* 1110 */
60  4, /* 1111 */
61 };
62 
65 
66 #if defined (CUBRID_DEBUG)
67 /*
68  * set_stats () - Print stats about set usage
69  * return: nothing
70  * fp(in): the stream on which to print the statistics
71  */
72 void
73 set_stats (FILE * fp)
74 {
75  fprintf (fp, "Set statistics no longer collected\n");
76 }
77 #endif
78 
79 /******************************************************************************
80  * *
81  * BITSET FUNCTIONS *
82  * *
83  *****************************************************************************/
84 
85 /*
86  * bitset_extend () -
87  * return:
88  * dst(in):
89  * nwords(in):
90  */
91 void
92 bitset_extend (BITSET * dst, int nwords)
93 {
94  BITSET_CARRIER *words;
95 
96  words = (BITSET_CARRIER *) malloc (NBYTES (nwords));
97  if (words == NULL)
98  {
100  return;
101  }
102 
103  memcpy (words, dst->setp, NBYTES (dst->nwords));
104  memset (words + dst->nwords, 0, NBYTES (nwords - dst->nwords));
105  dst->nwords = nwords;
106  if (dst->setp != dst->set.word)
107  {
108  bitset_free (dst->setp);
109  }
110  dst->setp = words;
111 }
112 
113 /*
114  * bitset_assign () -
115  * return:
116  * dst(in):
117  * src(in):
118  */
119 void
120 bitset_assign (BITSET * dst, const BITSET * src)
121 {
122  if (dst->nwords < src->nwords)
123  {
124  bitset_extend (dst, src->nwords);
125  }
126 
127  memcpy (dst->setp, src->setp, NBYTES (src->nwords));
128  memset (dst->setp + src->nwords, 0, NBYTES (dst->nwords - src->nwords));
129 }
130 
131 /*
132  * bitset_add () -
133  * return:
134  * dst(in):
135  * x(in):
136  */
137 void
138 bitset_add (BITSET * dst, int x)
139 {
140  int n;
141 
142  n = _WORD (x);
143  if (n >= dst->nwords)
144  {
145  bitset_extend (dst, n + 1);
146  }
147 
148  dst->setp[n] |= (1L << _BIT (x));
149 }
150 
151 /*
152  * bitset_remove () -
153  * return:
154  * dst(in):
155  * x(in):
156  */
157 void
158 bitset_remove (BITSET * dst, int x)
159 {
160  int n;
161 
162  n = _WORD (x);
163  if (n < dst->nwords)
164  {
165  dst->setp[n] &= ~(1L << _BIT (x));
166  }
167 }
168 
169 /*
170  * bitset_union () -
171  * return:
172  * dst(in):
173  * src(in):
174  */
175 void
176 bitset_union (BITSET * dst, const BITSET * src)
177 {
178  int nwords;
179 
180  if (dst->nwords < src->nwords)
181  {
182  bitset_extend (dst, src->nwords);
183  }
184 
185  nwords = src->nwords;
186  while (nwords)
187  {
188  nwords -= 1;
189  dst->setp[nwords] |= src->setp[nwords];
190  }
191 }
192 
193 /*
194  * bitset_intersect () -
195  * return:
196  * dst(in):
197  * src(in):
198  */
199 void
200 bitset_intersect (BITSET * dst, const BITSET * src)
201 {
202  int nwords;
203 
204  nwords = dst->nwords;
205  while (nwords > src->nwords)
206  {
207  nwords -= 1;
208  dst->setp[nwords] = 0;
209  }
210  while (nwords > 0)
211  {
212  nwords -= 1;
213  dst->setp[nwords] &= src->setp[nwords];
214  }
215 }
216 
217 /*
218  * bitset_difference () -
219  * return:
220  * dst(in):
221  * src(in):
222  */
223 void
224 bitset_difference (BITSET * dst, const BITSET * src)
225 {
226  int nwords;
227 
228  nwords = MIN (dst->nwords, src->nwords);
229  while (nwords)
230  {
231  nwords -= 1;
232  dst->setp[nwords] &= ~src->setp[nwords];
233  }
234 }
235 
236 #if defined (ENABLE_UNUSED_FUNCTION)
237 /*
238  * bitset_invert () -
239  * return:
240  * dst(in):
241  */
242 void
243 bitset_invert (BITSET * dst)
244 {
245  int nwords;
246 
247  nwords = dst->nwords;
248  while (nwords)
249  {
250  nwords -= 1;
251  dst->setp[nwords] = ~dst->setp[nwords];
252  }
253 }
254 #endif /* ENABLE_UNUSED_FUNCTION */
255 
256 /*
257  * bitset_subset () -
258  * return:
259  * r(in):
260  * s(in):
261  */
262 int
263 bitset_subset (const BITSET * r, const BITSET * s)
264 {
265  int nwords;
266 
267  nwords = s->nwords;
268  while (nwords > r->nwords)
269  {
270  nwords -= 1;
271  if (s->setp[nwords])
272  {
273  return 0;
274  }
275  }
276  while (nwords)
277  {
278  nwords -= 1;
279  if ((r->setp[nwords] & s->setp[nwords]) != s->setp[nwords])
280  {
281  return 0;
282  }
283  }
284 
285  return 1;
286 }
287 
288 /*
289  * bitset_intersects () -
290  * return:
291  * r(in):
292  * s(in):
293  */
294 int
295 bitset_intersects (const BITSET * r, const BITSET * s)
296 {
297  int nwords;
298 
299  nwords = MIN (r->nwords, s->nwords);
300  while (nwords)
301  {
302  nwords -= 1;
303  if (r->setp[nwords] & s->setp[nwords])
304  {
305  return 1;
306  }
307  }
308 
309  return 0;
310 }
311 
312 /*
313  * bitset_is_empty () -
314  * return:
315  * s(in):
316  */
317 int
319 {
320  int nwords;
321 
322  nwords = s->nwords;
323  while (nwords)
324  {
325  nwords -= 1;
326  if (s->setp[nwords])
327  {
328  return 0;
329  }
330  }
331 
332  return 1;
333 }
334 
335 /*
336  * bitset_is_equivalent () -
337  * return:
338  * r(in):
339  * s(in):
340  */
341 int
342 bitset_is_equivalent (const BITSET * r, const BITSET * s)
343 {
344  int nwords;
345 
346  if (r->nwords < s->nwords)
347  {
348  nwords = s->nwords;
349  while (nwords > r->nwords)
350  {
351  nwords -= 1;
352  if (s->setp[nwords])
353  {
354  return 0;
355  }
356  }
357  }
358  else if (r->nwords > s->nwords)
359  {
360  nwords = r->nwords;
361  while (nwords > s->nwords)
362  {
363  nwords -= 1;
364  if (r->setp[nwords])
365  {
366  return 0;
367  }
368  }
369  }
370  else
371  {
372  nwords = r->nwords;
373  }
374 
375  while (nwords)
376  {
377  nwords -= 1;
378  if (r->setp[nwords] != s->setp[nwords])
379  {
380  return 0;
381  }
382  }
383 
384  return 1;
385 }
386 
387 /*
388  * bitset_cardinality () -
389  * return:
390  * s(in):
391  */
392 int
394 {
395  int nwords, card;
396 
397  nwords = s->nwords;
398  card = 0;
399 
400  while (nwords)
401  {
402  BITSET_CARRIER word;
403  nwords -= 1;
404  word = s->setp[nwords];
405  while (word)
406  {
407  card += nbits[word & 0xf];
408  word >>= 4;
409  }
410  }
411 
412  return card;
413 }
414 
415 #if defined (ENABLE_UNUSED_FUNCTION)
416 /*
417  * bitset_position () -
418  * return:
419  * s(in):
420  * x(in):
421  */
422 int
423 bitset_position (const BITSET * s, int x)
424 {
425  int pos;
426 
427  if (BITSET_MEMBER (*s, x))
428  {
429  int i, m;
430  BITSET_CARRIER mask, word;
431 
432  pos = 0;
433 
434  for (i = 0, m = _WORD (x); i < m; i++)
435  {
436  for (word = s->setp[i]; word; word >>= 4)
437  {
438  pos += nbits[word & 0xf];
439  }
440  }
441 
442  mask = (1L << x) - 1;
443  for (word = s->setp[m] & mask; word; word >>= 4)
444  {
445  pos += nbits[word & 0xf];
446  }
447  }
448  else
449  {
450  pos = -1;
451  }
452 
453  return pos;
454 }
455 #endif /* ENABLE_UNUSED_FUNCTION */
456 
457 /*
458  * bitset_iterate () -
459  * return:
460  * s(in):
461  * si(in):
462  */
463 int
465 {
466  si->set = s;
467  si->next = 0;
468 
469  return bitset_next_member (si);
470 }
471 
472 /*
473  * bitset_next_member () -
474  * return:
475  * si(in):
476  */
477 int
479 {
480  int nwords;
481  BITSET_CARRIER word;
482  int current, m;
483 
484  current = si->next;
485 
486  if (current < 0)
487  {
488  return -1;
489  }
490 
491  nwords = si->set->nwords;
492  for (m = _WORD (current); m < nwords; current = _WORDSIZE * ++m)
493  {
494  for (word = si->set->setp[m] >> _BIT (current); word; current++, word >>= 1)
495  {
496  if (word & 0x1)
497  {
498  si->next = current + 1;
499  return current;
500  }
501  }
502  }
503 
504  si->next = -1;
505  return -1;
506 }
507 
508 /*
509  * bitset_first_member () -
510  * return:
511  * s(in):
512  */
513 int
515 {
516  BITSET_ITERATOR si;
517  return bitset_iterate (s, &si);
518 }
519 
520 /*
521  * bitset_print () -
522  * return:
523  * s(in):
524  * fp(in):
525  */
526 void
527 bitset_print (const BITSET * s, FILE * fp)
528 {
529  if (bitset_is_empty (s))
530  {
531  (void) fprintf (fp, "empty");
532  }
533  else
534  {
535  int i;
536  BITSET_ITERATOR si;
537 
538  i = bitset_iterate (s, &si);
539  if (i != -1)
540  {
541  (void) fprintf (fp, "%d", i);
542  while ((i = bitset_next_member (&si)) != -1)
543  {
544  (void) fprintf (fp, " %d", i);
545  }
546  }
547  }
548 }
549 
550 /*
551  * bitset_init () -
552  * return:
553  * s(in):
554  * env(in):
555  */
556 void
558 {
559  s->env = env;
560  s->setp = s->set.word;
561  s->nwords = NWORDS;
562  BITSET_CLEAR (*s);
563 }
564 
565 /*
566  * bitset_delset () -
567  * return:
568  * s(in):
569  */
570 void
572 {
573  if (s->setp != s->set.word)
574  {
575  bitset_free (s->setp);
576  s->setp = NULL;
577  }
578 }
unsigned int BITSET_CARRIER
Definition: query_bitset.h:48
int bitset_is_equivalent(const BITSET *r, const BITSET *s)
Definition: query_bitset.c:342
#define _BIT(x)
Definition: query_bitset.h:43
#define _WORD(x)
Definition: query_bitset.h:42
#define BITSET_CLEAR(s)
Definition: query_bitset.h:68
int bitset_intersects(const BITSET *r, const BITSET *s)
Definition: query_bitset.c:295
int bitset_iterate(const BITSET *s, BITSET_ITERATOR *si)
Definition: query_bitset.c:464
#define NBYTES(n)
Definition: query_bitset.c:35
int bitset_is_empty(const BITSET *s)
Definition: query_bitset.c:318
void bitset_difference(BITSET *dst, const BITSET *src)
Definition: query_bitset.c:224
const BITSET * set
Definition: query_bitset.h:64
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
int bitset_subset(const BITSET *r, const BITSET *s)
Definition: query_bitset.c:263
void bitset_print(const BITSET *s, FILE *fp)
Definition: query_bitset.c:527
void bitset_delset(BITSET *s)
Definition: query_bitset.c:571
#define _WORDSIZE
Definition: query_bitset.h:40
void bitset_assign(BITSET *dst, const BITSET *src)
Definition: query_bitset.c:120
void bitset_union(BITSET *dst, const BITSET *src)
Definition: query_bitset.c:176
#define ER_OUT_OF_VIRTUAL_MEMORY
Definition: error_code.h:50
unsigned int BITSET
Definition: esql_misc.h:94
static BITSET_CARRIER empty_set_words[NWORDS]
Definition: query_bitset.c:63
BITSET EMPTY_SET
Definition: query_bitset.c:64
#define NULL
Definition: freelistheap.h:34
#define bitset_free(ptr)
Definition: query_bitset.c:39
void bitset_intersect(BITSET *dst, const BITSET *src)
Definition: query_bitset.c:200
int bitset_next_member(BITSET_ITERATOR *si)
Definition: query_bitset.c:478
void bitset_remove(BITSET *dst, int x)
Definition: query_bitset.c:158
#define ARG_FILE_LINE
Definition: error_manager.h:44
#define NWORDS
Definition: query_bitset.h:45
void bitset_extend(BITSET *dst, int nwords)
Definition: query_bitset.c:92
#define BITSET_MEMBER(s, x)
Definition: query_bitset.h:70
static const char nbits[]
Definition: query_bitset.c:44
int i
Definition: dynamic_load.c:954
void bitset_init(BITSET *s, QO_ENV *env)
Definition: query_bitset.c:557
int bitset_cardinality(const BITSET *s)
Definition: query_bitset.c:393
int bitset_first_member(const BITSET *s)
Definition: query_bitset.c:514
void bitset_add(BITSET *dst, int x)
Definition: query_bitset.c:138