|
@@ -59,6 +59,7 @@ File sorting not implemented yet\n");
|
59
|
59
|
}
|
60
|
60
|
}
|
61
|
61
|
/* TODO begining binary search of date_min */
|
|
62
|
+ ret = _ttail_search_files_binary_search(t, tm, (const struct tm**)ftm);
|
62
|
63
|
|
63
|
64
|
return 0;
|
64
|
65
|
goto _ttail_search_closest_files_err;
|
|
@@ -80,6 +81,129 @@ File sorting not implemented yet\n");
|
80
|
81
|
return -1;
|
81
|
82
|
}
|
82
|
83
|
|
|
84
|
+int _ttail_search_files_binary_search(ttail_t* t, const struct tm* in,
|
|
85
|
+ const struct tm** ftm)
|
|
86
|
+{
|
|
87
|
+ int cmin, cmax;
|
|
88
|
+ size_t valid;
|
|
89
|
+ off_t *off;
|
|
90
|
+ size_t *id;
|
|
91
|
+ off = &(t->session->file.off);
|
|
92
|
+ id = &(t->session->file.id);
|
|
93
|
+ *id = *off = 0;
|
|
94
|
+ valid = 0;
|
|
95
|
+ if(ttail_tm_cmp(&(ftm[0][0]), in) > 0)
|
|
96
|
+ {
|
|
97
|
+ return 1;
|
|
98
|
+ }
|
|
99
|
+ while(1)
|
|
100
|
+ {
|
|
101
|
+ if(!ftm[*id])
|
|
102
|
+ {
|
|
103
|
+ (*id)++;
|
|
104
|
+ continue;
|
|
105
|
+ }
|
|
106
|
+ valid++;
|
|
107
|
+ cmin = ttail_tm_cmp(&(ftm[*id][0]), in);
|
|
108
|
+ cmax = ttail_tm_cmp(&(ftm[*id][1]), in);
|
|
109
|
+ if(!cmin)
|
|
110
|
+ {
|
|
111
|
+ /* found at the begining of the file */
|
|
112
|
+ return 0;
|
|
113
|
+ }
|
|
114
|
+ else if (!cmax)
|
|
115
|
+ {
|
|
116
|
+ /* found at EOF */
|
|
117
|
+ *off = _ttail_from_search_from_end(t, *id, in);
|
|
118
|
+ if(*off < 0)
|
|
119
|
+ {
|
|
120
|
+ *off = 0;
|
|
121
|
+ return -1;
|
|
122
|
+ }
|
|
123
|
+ return 0;
|
|
124
|
+ }
|
|
125
|
+ else if(cmin > 0)
|
|
126
|
+ {
|
|
127
|
+ /* not found */
|
|
128
|
+ *id=0;
|
|
129
|
+ return 1;
|
|
130
|
+ }
|
|
131
|
+ else if(*id == t->logfile_sz - 1 ||
|
|
132
|
+ cmax > 0)
|
|
133
|
+ {
|
|
134
|
+ /* somewhere in current file */
|
|
135
|
+ break;
|
|
136
|
+ }
|
|
137
|
+ (*id)++;
|
|
138
|
+ }
|
|
139
|
+ if(!valid)
|
|
140
|
+ {
|
|
141
|
+ fprintf(stderr, "No files to scan");
|
|
142
|
+ }
|
|
143
|
+ /* the answer is somewhere in *id file */
|
|
144
|
+ *off = _ttail_from_search_from_end(t, *id, in);
|
|
145
|
+ return 0;
|
|
146
|
+}
|
|
147
|
+
|
|
148
|
+inline int _ttail_search_file_binary_search(ttail_t* t, const struct tm* in,
|
|
149
|
+ const struct tm** ftm)
|
|
150
|
+{
|
|
151
|
+ off_t cur, sz, d, prev;
|
|
152
|
+ int ret, cmpres;
|
|
153
|
+ off_t *off;
|
|
154
|
+ size_t id;
|
|
155
|
+ off = &(t->session->file.off);
|
|
156
|
+ id = t->session->file.id;
|
|
157
|
+
|
|
158
|
+ sz = t->session->file.file_sz[id];
|
|
159
|
+ d = cur = sz / 2;
|
|
160
|
+ prev = 0;
|
|
161
|
+ cmpres = 0;
|
|
162
|
+ while(1)
|
|
163
|
+ {
|
|
164
|
+ cur = _ttail_file_next_line(t->logfile[id]);
|
|
165
|
+ if(cur < -1)
|
|
166
|
+ {
|
|
167
|
+ cur = _ttail_file_start_line(t->logfile[id]);
|
|
168
|
+ if(cur < 0)
|
|
169
|
+ {
|
|
170
|
+ return -1;
|
|
171
|
+ }
|
|
172
|
+ }
|
|
173
|
+ if(cur == prev)
|
|
174
|
+ {
|
|
175
|
+ *off = cur;
|
|
176
|
+ return 0;
|
|
177
|
+ }
|
|
178
|
+ prev = cur;
|
|
179
|
+ ret = _ttail_file_cur_cmp(t, id, in, &cmpres);
|
|
180
|
+ if(ret < 0)
|
|
181
|
+ {
|
|
182
|
+ return -1;
|
|
183
|
+ }
|
|
184
|
+ else if(cmpres == 0)
|
|
185
|
+ {
|
|
186
|
+ *off = cur;
|
|
187
|
+ break;
|
|
188
|
+ }
|
|
189
|
+ else if(cmpres < 0)
|
|
190
|
+ {
|
|
191
|
+ ret = _ttail_file_cur_cmp(t, id, in, &cmpres);
|
|
192
|
+ if(cmpres >=0)
|
|
193
|
+ {
|
|
194
|
+ *off = cur;
|
|
195
|
+ break;
|
|
196
|
+ }
|
|
197
|
+ d/=2;
|
|
198
|
+ cur += d;
|
|
199
|
+ cur %= t->session->file.file_sz[id];
|
|
200
|
+ }
|
|
201
|
+ else
|
|
202
|
+ {
|
|
203
|
+ d/=2;
|
|
204
|
+ cur -= d;
|
|
205
|
+ }
|
|
206
|
+ }
|
83
|
207
|
return 0;
|
84
|
208
|
}
|
85
|
209
|
|
|
@@ -87,6 +211,7 @@ int _ttail_search_closest_files_init(ttail_t* t)
|
87
|
211
|
{
|
88
|
212
|
struct stat stat;
|
89
|
213
|
FILE *fp;
|
|
214
|
+ int fd;
|
90
|
215
|
size_t i;
|
91
|
216
|
off_t *file_sz;
|
92
|
217
|
|
|
@@ -114,11 +239,13 @@ int _ttail_search_closest_files_init(ttail_t* t)
|
114
|
239
|
fp = t->logfile[i];
|
115
|
240
|
if(!fp)
|
116
|
241
|
{
|
117
|
|
- if(_ttail_file_reopen(t,i))
|
118
|
|
- {
|
119
|
|
- file_sz[i] = 0;
|
120
|
|
- continue;
|
121
|
|
- }
|
|
242
|
+ file_sz[i] = 0;
|
|
243
|
+ continue;
|
|
244
|
+ }
|
|
245
|
+ if((fd = fileno(fp)) < 0)
|
|
246
|
+ {
|
|
247
|
+ perror("Unable to get fp");
|
|
248
|
+ goto _ttail_search_closest_files_err;
|
122
|
249
|
}
|
123
|
250
|
if(fstat(fileno(fp), &stat))
|
124
|
251
|
{
|
|
@@ -407,6 +534,38 @@ inline off_t _ttail_from_search_from_end(ttail_t* t , size_t id ,
|
407
|
534
|
return -1;
|
408
|
535
|
}
|
409
|
536
|
|
|
537
|
+inline int _ttail_file_off_cmp(ttail_t* t, size_t id, off_t off,
|
|
538
|
+ const struct tm* tm, int *res)
|
|
539
|
+{
|
|
540
|
+ if(fseek(t->logfile[id], off, SEEK_CUR))
|
|
541
|
+ {
|
|
542
|
+ return -1;
|
|
543
|
+ }
|
|
544
|
+ if(ttail_getline(t, id) < 0)
|
|
545
|
+ {
|
|
546
|
+ return -1;
|
|
547
|
+ }
|
|
548
|
+ return _ttail_file_cur_cmp(t, id, tm, res);
|
|
549
|
+}
|
|
550
|
+inline int _ttail_file_cur_cmp(ttail_t* t, size_t id, const struct tm* tm ,
|
|
551
|
+ int* res)
|
|
552
|
+{
|
|
553
|
+ int ret;
|
|
554
|
+ struct tm ctm;
|
|
555
|
+ ret = ttail_logline2date(t, ttail_getline_buf(t), &ctm);
|
|
556
|
+ if(ret < 0)
|
|
557
|
+ {
|
|
558
|
+ return -1;
|
|
559
|
+ }
|
|
560
|
+ else if(ret == 1)
|
|
561
|
+ {
|
|
562
|
+ return 1;
|
|
563
|
+ }
|
|
564
|
+ *res = ttail_tm_cmp(&ctm, tm);
|
|
565
|
+ return 0;
|
|
566
|
+
|
|
567
|
+}
|
|
568
|
+
|
410
|
569
|
void _ttail_search_file_free(ttail_t* t)
|
411
|
570
|
{
|
412
|
571
|
if(!t->session)
|