1 #ifndef CACHE_H
2 #define CACHE_H
3 
4 /**
5  * \file cache.h
6  * \brief cache related structures and functions
7  * \details
8  *   - We store the metadata and the actual data separately in two
9  * separate folders.
10  */
11 
12 #include <pthread.h>
13 
14 /**
15  * \brief cache data type
16  */
17 typedef struct Cache Cache;
18 
19 #include "link.h"
20 
21 /**
22  * \brief Type definition for a cache segment
23  */
24 typedef uint8_t Seg;
25 
26 /**
27  * \brief cache data type in-memory data structure
28  */
29 struct Cache {
30     /** \brief the FILE pointer for the data file*/
31     FILE *dfp;
32     /** \brief the FILE pointer for the metadata */
33     FILE *mfp;
34     /** \brief the path to the local cache file */
35     char *path;
36     /** \brief the Link associated with this cache data set */
37     Link *link;
38     /** \brief the modified time of the file */
39     long time;
40     /** \brief the size of the file */
41     off_t content_length;
42     /** \brief the block size of the data file */
43     int blksz;
44     /** \brief segment array byte count */
45     long segbc;
46     /** \brief the detail of each segment */
47     Seg *seg;
48 
49     /** \brief mutex lock for seek operation */
50     pthread_mutex_t seek_lock;
51     /** \brief mutex lock for write operation */
52     pthread_mutex_t w_lock;
53 
54     /** \brief background download pthread */
55     pthread_t bgt;
56     /**
57      * \brief mutex lock for the background download thread
58      * \note This lock is locked by the foreground thread, but unlocked by the
59      * background thread!
60      */
61     pthread_mutex_t bgt_lock;
62     /** \brief mutex attributes for bgt_lock */
63     pthread_mutexattr_t bgt_lock_attr;
64     /** \brief the offset of the next segment to be downloaded in background*/
65     off_t next_dl_offset;
66 
67     /** \brief the FUSE filesystem path to the remote file*/
68     char *fs_path;
69 };
70 
71 /**
72  * \brief whether the cache system is enabled
73  */
74 extern int CACHE_SYSTEM_INIT;
75 
76 /**
77  * \brief The metadata directory
78  */
79 extern char *META_DIR;
80 
81 /**
82  * \brief initialise the cache system directories
83  * \details This function basically sets up the following variables:
84  *  - META_DIR
85  *  - DATA_DIR
86  *
87  * If these directories do not exist, they will be created.
88  * \note Called by parse_arg_list(), verified to be working
89  */
90 void CacheSystem_init(const char *path, int url_supplied);
91 
92 /**
93  * \brief Create directories under the cache directory structure, if they do
94  * not already exist
95  * \return
96  *  -   -1 failed to create metadata directory.
97  *  -   -2 failed to create data directory.
98  *  -   -3 failed to create both metadata and data directory.
99  * \note Called by LinkTable_new()
100  */
101 int CacheDir_create(const char *fn);
102 
103 /**
104  * \brief open a cache file set
105  * \note This function is called by fs_open()
106  */
107 Cache *Cache_open(const char *fn);
108 
109 /**
110  * \brief Close a cache data structure
111  * \note This function is called by fs_release()
112  */
113 void Cache_close(Cache * cf);
114 
115 /**
116  * \brief create a cache file set if it doesn't exist already
117  * \return
118  *  -   0, if the cache file already exists, or was created successfully.
119  *  -   -1, otherwise
120  * \note Called by fs_open()
121  */
122 int Cache_create(const char *path);
123 
124 /**
125  * \brief delete a cache file set
126  * \note Called by fs_open()
127  */
128 void Cache_delete(const char *fn);
129 
130 /**
131  * \brief Intelligently read from the cache system
132  * \details If the segment does not exist on the local hard disk, download from
133  * the Internet
134  * \param[in] cf the cache in-memory data structure
135  * \param[out] output_buf the output buffer
136  * \param[in] len the requested segment size
137  * \param[in] offset_start the start of the segment
138  * \return the length of the segment the cache system managed to obtain.
139  * \note Called by fs_read(), verified to be working
140  */
141 long Cache_read(Cache * cf, char *const output_buf, const off_t len,
142                 const off_t offset_start);
143 #endif
144