-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcache.c
140 lines (108 loc) · 3.4 KB
/
cache.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include "cache.h"
static dict *d = NULL;
cache_client *cache_client_open(char *filename, __int64 filesize, int blocksize)
{
cache_client *cc;
int len = strlen(filename);
cc = lib_calloc(sizeof(cache_client));
cc->filename = lib_calloc(len + 1);
sprintf(cc->filename, "%s", filename);
cc->cachefile = lib_calloc(len + sizeof(CACHE_CLIENT_CACHE) + 1);
sprintf(cc->cachefile, "%s%s", filename, CACHE_CLIENT_CACHE);
cc->statefile = lib_calloc(len + sizeof(CACHE_CLIENT_STATE) + 1);
sprintf(cc->statefile, "%s%s", filename, CACHE_CLIENT_STATE);
if(!access(cc->cachefile, 0) && !access(cc->statefile, 0)) //有缓存文件
{
cc->cachefp = file_open(cc->cachefile);
cc->statefp = file_open(cc->statefile);
file_read(cc->statefp, &cc->filesize, sizeof(cc->filesize));
file_read(cc->statefp, &cc->blocksize, sizeof(cc->blocksize));
file_read(cc->statefp, &cc->blocknum, sizeof(cc->blocknum));
cc->block = lib_calloc(cc->blocknum * sizeof(cache_block));
file_read(cc->statefp, cc->block, cc->blocknum * sizeof(cache_block));
cc->num = 0;
int i;
for(i = 0; i < cc->blocknum; i++)
cc->num += cc->block[i].sign;
}
else //没有缓存文件
{
file_create(cc->cachefile, filesize);
cc->cachefp = file_open(cc->cachefile);
file_create(cc->statefile, 0);
cc->statefp = file_open(cc->statefile);
cc->filesize = filesize;
cc->blocksize = blocksize;
cc->blocknum = (cc->filesize - 1) / cc->blocksize + 1;
cc->num = 0;
file_write(cc->statefp, &cc->filesize, sizeof(cc->filesize));
file_write(cc->statefp, &cc->blocksize, sizeof(cc->blocksize));
file_write(cc->statefp, &cc->blocknum, sizeof(cc->blocknum));
cc->block = lib_calloc(cc->blocknum * sizeof(cache_block));
file_write(cc->statefp, cc->block, cc->blocknum * sizeof(cache_block));
}
file_seek(cc->statefp, 0, FILE_SEEK_SET);
return cc;
}
int cache_client_close(cache_client *cc)
{
file_close(cc->cachefp);
rename(cc->cachefile, cc->filename);
lib_free(cc->cachefile);
file_close(cc->statefp);
remove(cc->statefile);
lib_free(cc->statefile);
lib_free(cc->block);
dict_del(d, cc->filename);
lib_free(cc->filename);
lib_free(cc);
}
/*
只有缓存时,重新生成状态文件
只有状态时,清空状态文件
*/
cache_client *cache_client_init(char *filename, __int64 filesize, int blocksize)
{
cache_client *cc;
if(d == NULL)
d = dict_new();
cc = dict_get(d, filename);
if(!cc)
{
cc = cache_client_open(filename, filesize, blocksize);
dict_set(d, cc->filename, cc);
}
return cc;
}
int cache_client_update(cache_client *cc, __int64 id)
{
cache_block block;
file_seek(cc->statefp, CACHE_CLIENT_OFFSET_BLOCK + id, FILE_SEEK_SET);
file_read(cc->statefp, &block, sizeof(cache_block));
if(block.sign == 0)
{
block.sign = 1;
cc->block[id] = block;
file_seek(cc->statefp, CACHE_CLIENT_OFFSET_BLOCK + id, FILE_SEEK_SET);
file_write(cc->statefp, &block, sizeof(cache_block));
cc->num++;
}
if(cc->num == cc->blocknum)
cache_client_close(cc);
}
int cache_client_write(cache_client *cc, void *data, __int64 id)
{
int offset = id * cc->blocksize;
int len = cc->blocksize;
file_seek(cc->cachefp, offset, FILE_SEEK_SET);
if(len > cc->filesize - offset)
len = cc->filesize - offset;
file_write(cc->cachefp, data, len);
cache_client_update(cc, id);
}
#ifdef TEST
#include "test.h"
void cache_test()
{
}
#endif