Line data Source code
1 : #include "../../burp.h"
2 : #include "../../alloc.h"
3 : #include "../../cmd.h"
4 : #include "../../fzp.h"
5 : #include "../../hexmap.h"
6 : #include "../../iobuf.h"
7 : #include "../../log.h"
8 : #include "../../prepend.h"
9 : #include "../../protocol2/blk.h"
10 : #include "rblk.h"
11 :
12 : static ssize_t rblk_mem=0;
13 : static ssize_t rblk_mem_max=0;
14 :
15 : // For retrieving stored data.
16 : struct rblk
17 : {
18 : uint64_t hash_key;
19 : struct iobuf readbuf[DATA_FILE_SIG_MAX];
20 : uint16_t readbuflen;
21 : UT_hash_handle hh;
22 : };
23 :
24 56 : static void rblk_free_content(struct rblk *rblk)
25 : {
26 229432 : for(int j=0; j<DATA_FILE_SIG_MAX; j++)
27 : {
28 229376 : rblk_mem-=rblk->readbuf[j].len;
29 229376 : iobuf_free_content(&rblk->readbuf[j]);
30 : }
31 56 : }
32 :
33 56 : static void rblk_free(struct rblk **rblk)
34 : {
35 : /*
36 : uint16_t datno;
37 : char *x;
38 : x=uint64_to_savepathstr_with_sig_uint((*rblk)->savepath, &datno);
39 : printf(" free: %s\n", x);
40 : */
41 56 : rblk_free_content(*rblk);
42 56 : rblk_mem-=sizeof(struct rblk);
43 56 : free_v((void **)rblk);
44 56 : }
45 :
46 : static struct rblk *rblk_hash=NULL;
47 :
48 316 : static struct rblk *rblk_hash_find(uint64_t savepath)
49 : {
50 : struct rblk *rblk;
51 316 : HASH_FIND_INT(rblk_hash, &savepath, rblk);
52 316 : return rblk;
53 : }
54 :
55 56 : static void rblk_hash_add(struct rblk *rblk)
56 : {
57 62 : HASH_ADD_INT(rblk_hash, hash_key, rblk);
58 56 : }
59 :
60 56 : static struct rblk *rblk_alloc(void)
61 : {
62 : struct rblk *rblk;
63 56 : rblk=(struct rblk *)calloc_w(1, sizeof(struct rblk), __func__);
64 56 : if(rblk)
65 56 : rblk_mem+=sizeof(struct rblk);
66 56 : return rblk;
67 : }
68 :
69 6 : void rblks_init(ssize_t rblk_memory_max)
70 : {
71 6 : rblk_mem_max=rblk_memory_max;
72 6 : }
73 :
74 7 : void rblks_free(void)
75 : {
76 : struct rblk *tmp;
77 : struct rblk *rblk;
78 :
79 63 : HASH_ITER(hh, rblk_hash, rblk, tmp)
80 : {
81 56 : HASH_DEL(rblk_hash, rblk);
82 56 : rblk_free(&rblk);
83 : }
84 7 : rblk_hash=NULL;
85 7 : }
86 :
87 0 : static int rblks_free_one(void)
88 : {
89 0 : uint64_t before=rblk_mem;
90 : struct rblk *tmp;
91 : struct rblk *rblk;
92 :
93 0 : HASH_ITER(hh, rblk_hash, rblk, tmp)
94 : {
95 0 : HASH_DEL(rblk_hash, rblk);
96 0 : rblk_free(&rblk);
97 0 : break;
98 : }
99 0 : if(before!=rblk_mem)
100 : return 0;
101 0 : return -1;
102 : }
103 :
104 56 : static int rblk_load_from_disk(struct rblk *rblk, const char *fulldatpath)
105 : {
106 : int r;
107 56 : int ret=-1;
108 56 : int done=0;
109 56 : struct fzp *fzp=NULL;
110 : struct iobuf rbuf;
111 :
112 56 : iobuf_init(&rbuf);
113 :
114 56 : if(!(fzp=fzp_open(fulldatpath, "rb")))
115 : goto end;
116 360 : for(r=0; r<DATA_FILE_SIG_MAX; r++)
117 : {
118 416 : switch(iobuf_fill_from_fzp_data(&rbuf, fzp))
119 : {
120 360 : case 0: if(rbuf.cmd!=CMD_DATA)
121 : {
122 0 : logp("unknown cmd in %s: %c\n",
123 : __func__, rbuf.cmd);
124 0 : goto end;
125 : }
126 360 : iobuf_free_content(&rblk->readbuf[r]);
127 360 : iobuf_move(&rblk->readbuf[r], &rbuf);
128 360 : rblk_mem+=rblk->readbuf[r].len;
129 360 : continue;
130 : case 1: done++;
131 : break;
132 : default: goto end;
133 : }
134 : if(done) break;
135 : }
136 56 : rblk->readbuflen=r;
137 56 : ret=0;
138 : end:
139 56 : fzp_close(&fzp);
140 56 : return ret;
141 : }
142 :
143 56 : static int rblk_init(struct rblk *rblk, struct blk *blk,
144 : uint64_t hash_key, const char *datpath, const char *savepathstr)
145 : {
146 56 : int ret=-1;
147 56 : char *fulldatpath=NULL;
148 :
149 56 : rblk->hash_key=hash_key;
150 56 : if(!(fulldatpath=prepend_s(datpath, savepathstr)))
151 : goto end;
152 56 : logp("load: %s\n", savepathstr);
153 56 : if(rblk_load_from_disk(rblk, fulldatpath))
154 : goto end;
155 56 : ret=0;
156 : end:
157 56 : free_w(&fulldatpath);
158 56 : return ret;
159 : }
160 :
161 316 : int rblk_retrieve_data(struct asfd *asfd, struct cntr *cntr,
162 : struct blk *blk, const char *datpath)
163 : {
164 316 : uint16_t datno=0;
165 : uint64_t hash_key;
166 : char *savepathstr;
167 316 : struct rblk *rblk=NULL;
168 :
169 316 : hash_key=uint64_to_savepath_hash_key(blk->savepath);
170 316 : savepathstr=uint64_to_savepathstr_with_sig_uint(blk->savepath, &datno);
171 :
172 316 : if(!(rblk=rblk_hash_find(hash_key)))
173 : {
174 56 : if(!(rblk=rblk_alloc())
175 56 : || rblk_init(rblk, blk, hash_key, datpath, savepathstr))
176 : {
177 0 : rblk_free(&rblk);
178 0 : return -1;
179 : }
180 56 : while(rblk_mem>rblk_mem_max)
181 : {
182 0 : if(rblks_free_one())
183 : {
184 0 : logw(asfd, cntr,
185 : "rblk_memory_max is too low!\n");
186 0 : break;
187 : }
188 : }
189 56 : rblk_hash_add(rblk);
190 : }
191 :
192 : // printf("lookup: %s (%u)\n", savepathstr, datno);
193 316 : if(datno>rblk->readbuflen)
194 : {
195 0 : logp("dat index %d is greater than readbuflen: %d\n",
196 : datno, rblk->readbuflen);
197 0 : return -1;
198 : }
199 316 : blk->data=rblk->readbuf[datno].buf;
200 316 : blk->length=rblk->readbuf[datno].len;
201 : // printf("length: %d\n", blk->length);
202 :
203 316 : return 0;
204 : }
|