diff options
author | Shehjar Tikoo <shehjart@gluster.com> | 2009-05-28 04:42:58 +0000 |
---|---|---|
committer | Anand V. Avati <avati@dev.gluster.com> | 2009-06-03 00:30:54 -0700 |
commit | b6434aadbe3e862815f4237fdf4c97284680a134 (patch) | |
tree | 7b8a87771b9efcf9ea4c85fd7bdbdf90b6a6ef5c /libglusterfsclient/src/libglusterfsclient-internals.h | |
parent | 1fea167f86ed4501ed01b5c678cddc7c815f1a5b (diff) |
libglusterfsclient: Add dirent pre-fetching and caching
The fop interface is such that we're able to extract more than
1 dirent in a readdir fop. This commit now enables libglusterfsclient
to read multiple entries on a glusterfs_readdir call. Once these
have been pre-fetched, they're cached till either glusterfs_closedir
,glusterfs_rewinddir or glusterfs_seekdir are called.
The current implementation is beneficial for sequential directory
reading and probably indifferent to applications that do a lot of seekdir
and rewinddir after opening the directory. This is because
both these calls result in dirent cache invalidation.
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
Diffstat (limited to 'libglusterfsclient/src/libglusterfsclient-internals.h')
-rwxr-xr-x | libglusterfsclient/src/libglusterfsclient-internals.h | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/libglusterfsclient/src/libglusterfsclient-internals.h b/libglusterfsclient/src/libglusterfsclient-internals.h index 42ce5d4cac0..fc79a539d69 100755 --- a/libglusterfsclient/src/libglusterfsclient-internals.h +++ b/libglusterfsclient/src/libglusterfsclient-internals.h @@ -79,6 +79,34 @@ typedef struct { struct stat stbuf; } libglusterfs_client_inode_ctx_t; +/* Our dirent cache is very simplistic when it comes to directory + * reading workloads. It assumes that all directory traversal operations happen + * sequentially and that readdir callers dont go jumping around the directory + * using seekdir, rewinddir. Thats why you'll notice that seekdir, rewinddir + * API in libglusterfsclient only set the offset. The consequence is that when + * libgf_dcache_readdir finds that the offset presented to it, is not + * the same as the offset of the previous dirent returned by dcache (..stored + * in struct direntcache->prev_off..), it realises that a non-sequential + * directory read is in progress and returns 0 to signify that the cache is + * not valid. + * This could be made a bit more intelligent by using a data structure like + * a hash-table or a balanced binary tree that allows us to search for the + * existence of particular offsets in the cache without performing a list or + * array traversal. + * Dont use a simple binary search tree because + * there is no guarantee that offsets in a sequential reading of the directory + * will be just random integers. If for some reason they are sequential, a BST + * will end up becoming a list. + */ +struct direntcache { + gf_dirent_t entries; /* Head of list of cached dirents. */ + gf_dirent_t *next; /* Pointer to the next entry that + * should be sent by readdir */ + uint64_t prev_off; /* Offset where the next read will + * happen. + */ +}; + typedef struct { pthread_mutex_t lock; off_t offset; @@ -88,6 +116,8 @@ typedef struct { * handle. */ struct dirent dirp; + struct direntcache *dcache; + } libglusterfs_client_fd_ctx_t; typedef struct libglusterfs_client_async_local { |