summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-04-11 23:10:27 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-04-11 23:10:27 -0700
commit8691fb836b268c622c61281238219fc166f0eee5 (patch)
treedf57303f9d0622617b0f2a407d59a014c77ee7bb /include/linux
parente279bfef94ec8ab13043eee1a185769fd7874473 (diff)
[PATCH] radix-tree tags for selective lookup
Add radix-tree tagging so we can look up dirty or writeback pages in O(log64(n)) time. Each radix-tree node gains two bits for each slot: one for page dirtiness and one for page writebackness. If a tag bit is set on a leaf node, it indicates that item at the corresponding slot is tagged (say, a dirty page). If a tag bit is set in a non-leaf node it indicates that the same tag bit is set in the subtree which lies under the corresponding slot. ie: "there is a dirty page under here somewhere, but you need to search down further to find it". A gang lookup function is provided which can walk the radix tree in logarithmic time looking for items which are tagged, starting from a specified offset. We use this for in-order searches for dirty or writeback pages. There is a userspace test harness for this code at http://www.zip.com.au/~akpm/linux/patches/stuff/rtth.tar.gz
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/radix-tree.h38
1 files changed, 26 insertions, 12 deletions
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index c32a45fd1f0d..8081a281fa5e 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -20,8 +20,7 @@
#define _LINUX_RADIX_TREE_H
#include <linux/preempt.h>
-
-struct radix_tree_node;
+#include <linux/types.h>
struct radix_tree_root {
unsigned int height;
@@ -29,25 +28,40 @@ struct radix_tree_root {
struct radix_tree_node *rnode;
};
-#define RADIX_TREE_INIT(mask) {0, (mask), NULL}
+#define RADIX_TREE_INIT(mask) { \
+ .height = 0, \
+ .gfp_mask = (mask), \
+ .rnode = NULL, \
+}
#define RADIX_TREE(name, mask) \
struct radix_tree_root name = RADIX_TREE_INIT(mask)
-#define INIT_RADIX_TREE(root, mask) \
-do { \
- (root)->height = 0; \
- (root)->gfp_mask = (mask); \
- (root)->rnode = NULL; \
+#define INIT_RADIX_TREE(root, mask) \
+do { \
+ (root)->height = 0; \
+ (root)->gfp_mask = (mask); \
+ (root)->rnode = NULL; \
} while (0)
-extern int radix_tree_insert(struct radix_tree_root *, unsigned long, void *);
-extern void *radix_tree_lookup(struct radix_tree_root *, unsigned long);
-extern void *radix_tree_delete(struct radix_tree_root *, unsigned long);
-extern unsigned int
+int radix_tree_insert(struct radix_tree_root *, unsigned long, void *);
+void *radix_tree_lookup(struct radix_tree_root *, unsigned long);
+void *radix_tree_delete(struct radix_tree_root *, unsigned long);
+unsigned int
radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
unsigned long first_index, unsigned int max_items);
int radix_tree_preload(int gfp_mask);
+void radix_tree_init(void);
+void *radix_tree_tag_set(struct radix_tree_root *root,
+ unsigned long index, int tag);
+void *radix_tree_tag_clear(struct radix_tree_root *root,
+ unsigned long index, int tag);
+int radix_tree_tag_get(struct radix_tree_root *root,
+ unsigned long index, int tag);
+unsigned int
+radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results,
+ unsigned long first_index, unsigned int max_items, int tag);
+int radix_tree_tagged(struct radix_tree_root *root, int tag);
static inline void radix_tree_preload_end(void)
{