Browse Source

[broken] Files searching function 1st implementation

untested
Yann Weber 7 years ago
parent
commit
5f7d34f9de
2 changed files with 216 additions and 15 deletions
  1. 52
    10
      src/include/ttail_search_files.h
  2. 164
    5
      src/ttail_search_files.c

+ 52
- 10
src/include/ttail_search_files.h View File

@@ -21,15 +21,28 @@ struct _ttail_search_file_s
21 21
 	/*<! Shift width to apply on size to compute stuff */
22 22
 	short sz_div;
23 23
 	#endif
24
-	/*<! Computed files start size */
24
+	/*<! Computed files start size
25
+	 *@todo delete, useless
26
+	 */
25 27
 	off_t *vfile;
26
-	/*<! Computed file sizes sum */
28
+	/*<! Computed file sizes sum 
29
+	 *@todo delete useless
30
+	 */
27 31
 	off_t vsz;
28
-	/*<! Computed position */
32
+	/*<! Computed position 
33
+	 *@todo delete, useless
34
+	 */
29 35
 	off_t vpos;
30 36
 
37
+	/*<! buffer for ttail_getiline() macro */
31 38
 	char *buf;
39
+	/*<! buffer size for ttail_getiline() macro */
32 40
 	size_t buf_sz;
41
+	
42
+	/*<! Current file id */
43
+	size_t id;
44
+	/*<! Current file offset */
45
+	off_t off;
33 46
 };
34 47
 
35 48
 #include "config.h"
@@ -48,6 +61,8 @@ struct _ttail_search_file_s
48 61
 #define ttail_getline_buf(TTAIL) (TTAIL->session->file.buf)
49 62
 
50 63
 /**@brief @ref ttail_search_closest() implementation for logfiles
64
+ *
65
+ *Will set struct _ttail_search_file_s.id and struct _ttail_search_file_s.off
51 66
  *@param ttail_t*
52 67
  *@return 0 if ok -1 if fatal error 1 if not found
53 68
  */
@@ -55,14 +70,27 @@ int _ttail_search_closest_files(ttail_t*);
55 70
 int _ttail_search_closest_files_init(ttail_t*);
56 71
 int _ttail_search_closest_files_set_fsizes(ttail_t*);
57 72
 
58
-/**@brief Test if files are sorted
59
- *
60
- *If not sorted attempt to sort them
61
- *@param ttail_t*
62
- *@return -1 not sorted 0 sorted -3 error
63
- *@todo checks
73
+/**@brief Binary search of the last logline with a date < tm
74
+ *@param ttail ttail_t*
75
+ *@param tm struct tm*
76
+ *param id size_t* result file id
77
+ *@param off off_t* set to -1 if none found
78
+ *@param ftm struct tm** local variable of @ref _ttail_search_closest_files()
79
+ *@return 0 if ok -1 if error 1 if empty result
80
+ */
81
+int _ttail_search_files_binary_search(ttail_t*, const struct tm*,
82
+	const struct tm**);
83
+
84
+/**@brief Binary search of the last logline with a date < tm in a file
85
+ *@param ttail ttail_t*
86
+ *@param tm struct tm*
87
+ *param id size_t the file to search into
88
+ *@param off off_t* set to -1 if none found
89
+ *@param ftm struct tm** local variable of @ref _ttail_search_closest_files()
90
+ *@return 0 if ok -1 if error 1 if empty result
64 91
  */
65
-int _ttail_search_file_sorted(ttail_t*);
92
+int _ttail_search_file_binary_search(ttail_t*, const struct tm*,
93
+	const struct tm**);
66 94
 
67 95
 /**@brief Attempt to reopen a file
68 96
  *@param ttail_t* ttail
@@ -105,6 +133,20 @@ inline long _ttail_file_start_line(FILE*);
105 133
  */
106 134
 inline off_t _ttail_from_search_from_end(ttail_t*, size_t, const struct tm*);
107 135
 
136
+/**@brief Read a line from off and compare its date to tm
137
+ *@param t ttail_t*
138
+ *@param id site_t
139
+ *@param off off_t
140
+ *@param tm const struct tm*
141
+ *@param res int* see return value of @ref ttail_tm_cmp()
142
+ *@return 0 on success -1 on error 1 if no date found
143
+ */
144
+inline int _ttail_file_off_cmp(ttail_t*, size_t, off_t, const struct tm*, int*);
145
+
146
+/**@brief Same than _ttail_file_off_cmp() but from current pos
147
+ *@return 0 on success -1 on error 1 if no date found*/
148
+inline int _ttail_file_cur_cmp(ttail_t*, size_t, const struct tm*, int*);
149
+
108 150
 /**@brief Free the ttail_search_file_t session
109 151
  *@param ttail_t* ttail
110 152
  */

+ 164
- 5
src/ttail_search_files.c View File

@@ -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)

Loading…
Cancel
Save