| 1 | /*	$NetBSD: bitset.c,v 1.1.1.1 2008/12/22 00:18:36 haad Exp $	*/ | 
| 2 |  | 
| 3 | /* | 
| 4 |  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.   | 
| 5 |  * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | 
| 6 |  * | 
| 7 |  * This file is part of the device-mapper userspace tools. | 
| 8 |  * | 
| 9 |  * This copyrighted material is made available to anyone wishing to use, | 
| 10 |  * modify, copy, or redistribute it subject to the terms and conditions | 
| 11 |  * of the GNU Lesser General Public License v.2.1. | 
| 12 |  * | 
| 13 |  * You should have received a copy of the GNU Lesser General Public License | 
| 14 |  * along with this program; if not, write to the Free Software Foundation, | 
| 15 |  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | 
| 16 |  */ | 
| 17 |  | 
| 18 | #include "dmlib.h" | 
| 19 |  | 
| 20 | /* FIXME: calculate this. */ | 
| 21 | #define INT_SHIFT 5 | 
| 22 |  | 
| 23 | dm_bitset_t dm_bitset_create(struct dm_pool *mem, unsigned num_bits) | 
| 24 | { | 
| 25 | 	unsigned n = (num_bits / DM_BITS_PER_INT) + 2; | 
| 26 | 	size_t size = sizeof(int) * n; | 
| 27 | 	dm_bitset_t bs; | 
| 28 | 	 | 
| 29 | 	if (mem) | 
| 30 | 		bs = dm_pool_zalloc(mem, size); | 
| 31 | 	else | 
| 32 | 		bs = dm_malloc(size); | 
| 33 |  | 
| 34 | 	if (!bs) | 
| 35 | 		return NULL; | 
| 36 |  | 
| 37 | 	*bs = num_bits; | 
| 38 |  | 
| 39 | 	if (!mem) | 
| 40 | 		dm_bit_clear_all(bs); | 
| 41 |  | 
| 42 | 	return bs; | 
| 43 | } | 
| 44 |  | 
| 45 | void dm_bitset_destroy(dm_bitset_t bs) | 
| 46 | { | 
| 47 | 	dm_free(bs); | 
| 48 | } | 
| 49 |  | 
| 50 | void dm_bit_union(dm_bitset_t out, dm_bitset_t in1, dm_bitset_t in2) | 
| 51 | { | 
| 52 | 	int i; | 
| 53 | 	for (i = (in1[0] / DM_BITS_PER_INT) + 1; i; i--) | 
| 54 | 		out[i] = in1[i] | in2[i]; | 
| 55 | } | 
| 56 |  | 
| 57 | /* | 
| 58 |  * FIXME: slow | 
| 59 |  */ | 
| 60 | static inline int _test_word(uint32_t test, int bit) | 
| 61 | { | 
| 62 | 	while (bit < (int) DM_BITS_PER_INT) { | 
| 63 | 		if (test & (0x1 << bit)) | 
| 64 | 			return bit; | 
| 65 | 		bit++; | 
| 66 | 	} | 
| 67 |  | 
| 68 | 	return -1; | 
| 69 | } | 
| 70 |  | 
| 71 | int dm_bit_get_next(dm_bitset_t bs, int last_bit) | 
| 72 | { | 
| 73 | 	int bit, word; | 
| 74 | 	uint32_t test; | 
| 75 |  | 
| 76 | 	last_bit++;		/* otherwise we'll return the same bit again */ | 
| 77 |  | 
| 78 | 	/* | 
| 79 | 	 * bs[0] holds number of bits | 
| 80 | 	 */ | 
| 81 | 	while (last_bit < (int) bs[0]) { | 
| 82 | 		word = last_bit >> INT_SHIFT; | 
| 83 | 		test = bs[word + 1]; | 
| 84 | 		bit = last_bit & (DM_BITS_PER_INT - 1); | 
| 85 |  | 
| 86 | 		if ((bit = _test_word(test, bit)) >= 0) | 
| 87 | 			return (word * DM_BITS_PER_INT) + bit; | 
| 88 |  | 
| 89 | 		last_bit = last_bit - (last_bit & (DM_BITS_PER_INT - 1)) + | 
| 90 | 		    DM_BITS_PER_INT; | 
| 91 | 	} | 
| 92 |  | 
| 93 | 	return -1; | 
| 94 | } | 
| 95 |  | 
| 96 | int dm_bit_get_first(dm_bitset_t bs) | 
| 97 | { | 
| 98 | 	return dm_bit_get_next(bs, -1); | 
| 99 | } | 
| 100 |  |