summaryrefslogtreecommitdiffstats
path: root/libglusterfsclient/src/libglusterfsclient-internals.h
diff options
context:
space:
mode:
authorShehjar Tikoo <shehjart@gluster.com>2009-05-28 04:42:58 +0000
committerAnand V. Avati <avati@dev.gluster.com>2009-06-03 00:30:54 -0700
commitb6434aadbe3e862815f4237fdf4c97284680a134 (patch)
tree7b8a87771b9efcf9ea4c85fd7bdbdf90b6a6ef5c /libglusterfsclient/src/libglusterfsclient-internals.h
parent1fea167f86ed4501ed01b5c678cddc7c815f1a5b (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-xlibglusterfsclient/src/libglusterfsclient-internals.h30
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 {