From: Jim Houston <jim.houston@comcast.net>

- Adds idr_get_new_above(), whihc permits us to do a first-fit search
  from a specified offset rather than always from zero.

- Add IDR_INIT() DEFINE_IDR() constructors.  Often idr's are singletons
  and having to cook up an initcall for them is a pain.


---

 25-akpm/include/linux/idr.h |   12 ++
 25-akpm/lib/idr.c           |  192 ++++++++++++++++++++++++++------------------
 2 files changed, 128 insertions(+), 76 deletions(-)

diff -puN include/linux/idr.h~idr-extra-features include/linux/idr.h
--- 25/include/linux/idr.h~idr-extra-features	Fri Mar 12 14:32:34 2004
+++ 25-akpm/include/linux/idr.h	Fri Mar 12 14:32:34 2004
@@ -23,6 +23,7 @@
 # error "BITS_PER_LONG is not 32 or 64"
 #endif
 
+#define IDR_SIZE (1 << IDR_BITS)
 #define IDR_MASK ((1 << IDR_BITS)-1)
 
 /* Define the size of the id's */
@@ -53,6 +54,17 @@ struct idr {
 	spinlock_t	  lock;
 };
 
+#define IDR_INIT(name)	\
+{								\
+	.top		= NULL,					\
+	.id_free	= NULL,					\
+	.count		= 0,					\
+	.layers 	= 0,					\
+	.id_free_cnt	= 0,					\
+	.lock		= SPIN_LOCK_UNLOCKED,			\
+}
+#define DEFINE_IDR(name)	struct idr name = IDR_INIT(name)
+
 /*
  * This is what we export.
  */
diff -puN lib/idr.c~idr-extra-features lib/idr.c
--- 25/lib/idr.c~idr-extra-features	Fri Mar 12 14:32:34 2004
+++ 25-akpm/lib/idr.c	Fri Mar 12 14:32:34 2004
@@ -109,7 +109,7 @@ static kmem_cache_t *idr_layer_cache;
 
 
 
-static inline struct idr_layer *alloc_layer(struct idr *idp)
+static struct idr_layer *alloc_layer(struct idr *idp)
 {
 	struct idr_layer *p;
 
@@ -123,7 +123,7 @@ static inline struct idr_layer *alloc_la
 	return(p);
 }
 
-static inline void free_layer(struct idr *idp, struct idr_layer *p)
+static void free_layer(struct idr *idp, struct idr_layer *p)
 {
 	/*
 	 * Depends on the return element being zeroed.
@@ -137,7 +137,7 @@ static inline void free_layer(struct idr
 
 int idr_pre_get(struct idr *idp, unsigned gfp_mask)
 {
-	while (idp->id_free_cnt < idp->layers + 1) {
+	while (idp->id_free_cnt < IDR_FREE_MAX) {
 		struct idr_layer *new;
 		new = kmem_cache_alloc(idr_layer_cache, gfp_mask);
 		if(new == NULL)
@@ -148,91 +148,125 @@ int idr_pre_get(struct idr *idp, unsigne
 }
 EXPORT_SYMBOL(idr_pre_get);
 
-static inline int sub_alloc(struct idr *idp, int shift, void *ptr)
+static int sub_alloc(struct idr *idp, void *ptr, int *starting_id)
 {
-	int n, v = 0;
-	struct idr_layer *p;
-	struct idr_layer **pa[MAX_LEVEL];
-	struct idr_layer ***paa = &pa[0];
-	
-	*paa = NULL;
-	*++paa = &idp->top;
-
-	/*
-	 * By keeping each pointer in an array we can do the 
-	 * "after" recursion processing.  In this case, that means
-	 * we can update the upper level bit map.
-	 */
-	
-	while (1){
-		p = **paa;
-		n = ffz(p->bitmap);
-		if (shift){
-			/*
-			 * We run around this while until we
-			 * reach the leaf node...
-			 */
-			if (!p->ary[n]){
-				/*
-				 * If no node, allocate one, AFTER
-				 * we insure that we will not
-				 * intrude on the reserved bit field.
-				 */
-				if ((n << shift) >= MAX_ID_BIT)
-					return -1;
-				p->ary[n] = alloc_layer(idp);
-				p->count++;
+	int n, m, sh;
+	struct idr_layer *p, *new;
+	struct idr_layer *pa[MAX_LEVEL];
+	int l, id;
+	long bm;
+
+	id = *starting_id;
+	p = idp->top;
+	l = idp->layers;
+	pa[l--] = NULL;
+	while (1) {
+		/*
+		 * We run around this while until we reach the leaf node...
+		 */
+		n = (id >> (IDR_BITS*l)) & IDR_MASK;
+		bm = ~p->bitmap;
+		m = find_next_bit(&bm, IDR_SIZE, n);
+		if (m == IDR_SIZE) {
+			/* no space available go back to previous layer. */
+			l++;
+			id = (id | ((1 << (IDR_BITS*l))-1)) + 1;
+			if (!(p = pa[l])) {
+				*starting_id = id;
+				return -2;
 			}
-			*++paa = &p->ary[n];
-			v += (n << shift);
-			shift -= IDR_BITS;
-		} else {
-			/*
-			 * We have reached the leaf node, plant the
-			 * users pointer and return the raw id.
-			 */
-			p->ary[n] = (struct idr_layer *)ptr;
-			__set_bit(n, &p->bitmap);
-			v += n;
+			continue;
+		}
+		if (m != n) {
+			sh = IDR_BITS*l;
+			id = ((id >> sh) ^ n ^ m) << sh;
+		}
+		if (id >= MAX_ID_BIT)
+			return -1;
+		if (l == 0)
+			break;
+		/*
+		 * Create the layer below if it is missing.
+		 */
+		if (!p->ary[m]) {
+			if (!(new = alloc_layer(idp)))
+				return -1;
+			p->ary[m] = new;
 			p->count++;
-			/*
-			 * This is the post recursion processing.  Once
-			 * we find a bitmap that is not full we are
-			 * done
-			 */
-			while (*(paa-1) && (**paa)->bitmap == IDR_FULL){
-				n = *paa - &(**(paa-1))->ary[0];
-				__set_bit(n, &(**--paa)->bitmap);
-			}
-			return(v);
 		}
+		pa[l--] = p;
+		p = p->ary[m];
 	}
+	/*
+	 * We have reached the leaf node, plant the
+	 * users pointer and return the raw id.
+	 */
+	p->ary[m] = (struct idr_layer *)ptr;
+	__set_bit(m, &p->bitmap);
+	p->count++;
+	/*
+	 * If this layer is full mark the bit in the layer above
+	 * to show that this part of the radix tree is full.
+	 * This may complete the layer above and require walking
+	 * up the radix tree.
+	 */
+	n = id;
+	while (p->bitmap == IDR_FULL) {
+		if (!(p = pa[++l]))
+			break;
+		n = n >> IDR_BITS;
+		__set_bit((n & IDR_MASK), &p->bitmap);
+	}
+	return(id);
 }
 
-int idr_get_new(struct idr *idp, void *ptr)
+int idr_get_new_above(struct idr *idp, void *ptr, int starting_id)
 {
-	int v;
+	struct idr_layer *p, *new;
+	int layers, v, id;
 	
-	if (idp->id_free_cnt < idp->layers + 1) 
-		return (-1);
+	id = starting_id;
+build_up:
+	p = idp->top;
+	layers = idp->layers;
+	if (unlikely(!p)) {
+		if (!(p = alloc_layer(idp)))
+			return -1;
+		layers = 1;
+	}
 	/*
-	 * Add a new layer if the array is full 
+	 * Add a new layer to the top of the tree if the requested
+	 * id is larger than the currently allocated space.
 	 */
-	if (unlikely(!idp->top || idp->top->bitmap == IDR_FULL)){
-		/*
-		 * This is a bit different than the lower layers because
-		 * we have one branch already allocated and full.
-		 */
-		struct idr_layer *new = alloc_layer(idp);
-		new->ary[0] = idp->top;
-		if ( idp->top)
-			++new->count;
-		idp->top = new;
-		if ( idp->layers++ )
+	while (id >= (1 << (layers*IDR_BITS))) {
+		layers++;
+		if (!p->count)
+			continue;
+		if (!(new = alloc_layer(idp))) {
+			/*
+			 * The allocation failed.  If we built part of
+			 * the structure tear it down.
+			 */
+			for (new = p; p && p != idp->top; new = p) {
+				p = p->ary[0];
+				new->ary[0] = 0;
+				new->bitmap = new->count = 0;
+				free_layer(idp, new);
+			}
+			return -1;
+		}
+		new->ary[0] = p;
+		new->count = 1;
+		if (p->bitmap == IDR_FULL)
 			__set_bit(0, &new->bitmap);
+		p = new;
 	}
-	v = sub_alloc(idp,  (idp->layers - 1) * IDR_BITS, ptr);
-	if ( likely(v >= 0 )){
+	idp->top = p;
+	idp->layers = layers;
+	v = sub_alloc(idp, ptr, &id);
+	if (v == -2)
+		goto build_up;
+	if ( likely(v >= 0 )) {
 		idp->count++;
 		v += (idp->count << MAX_ID_SHIFT);
 		if ( unlikely( v == -1 ))
@@ -240,10 +274,16 @@ int idr_get_new(struct idr *idp, void *p
 	}
 	return(v);
 }
+EXPORT_SYMBOL(idr_get_new_above);
+
+int idr_get_new(struct idr *idp, void *ptr)
+{
+	return idr_get_new_above(idp, ptr, 0);
+}
 EXPORT_SYMBOL(idr_get_new);
 
 
-static inline void sub_remove(struct idr *idp, int shift, int id)
+static void sub_remove(struct idr *idp, int shift, int id)
 {
 	struct idr_layer *p = idp->top;
 	struct idr_layer **pa[MAX_LEVEL];

_