/[LeafOK_CVS]/lbbs/src/article_view_log.c
ViewVC logotype

Contents of /lbbs/src/article_view_log.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (show annotations)
Sat Jun 7 08:07:07 2025 UTC (9 months, 1 week ago) by sysadm
Branch: MAIN
Changes since 1.1: +14 -1 lines
Content type: text/x-csrc
Update

1 /***************************************************************************
2 article_view_log.c - description
3 -------------------
4 Copyright : (C) 2004-2025 by Leaflet
5 Email : leaflet@leafok.com
6 ***************************************************************************/
7
8 /***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 3 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
17 #include "article_view_log.h"
18 #include "log.h"
19 #include "common.h"
20 #include "database.h"
21 #include <stdlib.h>
22
23 #define _XOPEN_SOURCE 500
24 #define _POSIX_C_SOURCE 200809L
25 #include <string.h>
26
27 int article_view_log_load(int uid, ARTICLE_VIEW_LOG *p_view_log, int keep_inc)
28 {
29 MYSQL *db;
30 MYSQL_RES *rs;
31 MYSQL_ROW row;
32 char sql[SQL_BUFFER_LEN];
33
34 if (p_view_log == NULL)
35 {
36 log_error("article_view_log_load() error: NULL pointer\n");
37 return -1;
38 }
39
40 if (uid == 0)
41 {
42 p_view_log->aid_base_cnt = 0;
43 p_view_log->aid_base = NULL;
44
45 if (!keep_inc)
46 {
47 p_view_log->aid_inc_cnt = 0;
48 }
49
50 return 0;
51 }
52
53 if ((db = db_open()) == NULL)
54 {
55 log_error("article_view_log_load() error: Unable to open DB\n");
56 return -2;
57 }
58
59 snprintf(sql, sizeof(sql),
60 "SELECT AID FROM view_article_log WHERE UID = %d "
61 "ORDER BY AID",
62 uid);
63 if (mysql_query(db, sql) != 0)
64 {
65 log_error("Query view_article_log error: %s\n", mysql_error(db));
66 return -3;
67 }
68 if ((rs = mysql_store_result(db)) == NULL)
69 {
70 log_error("Get view_article_log data failed\n");
71 return -3;
72 }
73
74 p_view_log->aid_base_cnt = 0;
75 p_view_log->aid_base = malloc(sizeof(int32_t) * mysql_num_rows(rs));
76 if (p_view_log->aid_base == NULL)
77 {
78 log_error("malloc(INT32 * %d) error: OOM\n", mysql_num_rows(rs));
79 mysql_free_result(rs);
80 mysql_close(db);
81 return -4;
82 }
83
84 while ((row = mysql_fetch_row(rs)))
85 {
86 p_view_log->aid_base[(p_view_log->aid_base_cnt)++] = atoi(row[0]);
87 }
88 mysql_free_result(rs);
89
90 mysql_close(db);
91
92 if (!keep_inc)
93 {
94 p_view_log->aid_inc_cnt = 0;
95 }
96
97 return 0;
98 }
99
100 int article_view_log_unload(ARTICLE_VIEW_LOG *p_view_log)
101 {
102 if (p_view_log == NULL)
103 {
104 log_error("article_view_log_unload() error: NULL pointer\n");
105 return -1;
106 }
107
108 if (p_view_log->aid_base != NULL)
109 {
110 free(p_view_log->aid_base);
111 p_view_log->aid_base = NULL;
112 p_view_log->aid_base_cnt = 0;
113 }
114
115 return 0;
116 }
117
118 int article_view_log_save_inc(int uid, const ARTICLE_VIEW_LOG *p_view_log)
119 {
120 MYSQL *db;
121 char sql[SQL_BUFFER_LEN];
122 char tuple_tmp[LINE_BUFFER_LEN];
123 int i;
124
125 if (p_view_log == NULL)
126 {
127 log_error("article_view_log_save_inc() error: NULL pointer\n");
128 return -1;
129 }
130
131 if ((db = db_open()) == NULL)
132 {
133 log_error("article_view_log_load() error: Unable to open DB\n");
134 return -2;
135 }
136
137 snprintf(sql, sizeof(sql),
138 "INSERT INTO view_article_log(AID, UID, dt) ");
139
140 for (i = 0; i < p_view_log->aid_inc_cnt; i++)
141 {
142 snprintf(tuple_tmp, sizeof(tuple_tmp),
143 "(%d, %d, NOW())",
144 p_view_log->aid_inc[i], uid);
145 strncat(sql, tuple_tmp, sizeof(sql) - 1 - strnlen(sql, sizeof(sql)));
146
147 if (i % 100 == 0) // Insert 100 records per query
148 {
149 strncat(sql, " ON DUPLICATE KEY UPDATE 0 + 0", sizeof(sql) - 1 - strnlen(sql, sizeof(sql)));
150
151 if (mysql_query(db, sql) != 0)
152 {
153 log_error("Add view_article_log error: %s\n", mysql_error(db));
154 return -3;
155 }
156
157 snprintf(sql, sizeof(sql),
158 "INSERT INTO view_article_log(AID, UID, dt) ");
159 }
160 else
161 {
162 strncat(sql, ", ", sizeof(sql) - 1 - strnlen(sql, sizeof(sql)));
163 }
164 }
165
166 mysql_close(db);
167
168 return 0;
169 }
170
171 int article_view_log_merge_inc(ARTICLE_VIEW_LOG *p_view_log)
172 {
173 int32_t *aid_new;
174 int aid_new_cnt;
175 int i, j, k;
176
177 if (p_view_log == NULL)
178 {
179 log_error("article_view_log_merge_inc() error: NULL pointer\n");
180 return -1;
181 }
182
183 if (p_view_log->aid_inc_cnt == 0) // Nothing to be merged
184 {
185 return 0;
186 }
187
188 aid_new_cnt = p_view_log->aid_base_cnt + p_view_log->aid_inc_cnt;
189
190 aid_new = malloc(sizeof(int32_t) * (size_t)aid_new_cnt);
191 if (aid_new == NULL)
192 {
193 log_error("malloc(INT32 * %d) error: OOM\n", aid_new_cnt);
194 return -2;
195 }
196
197 for (i = 0, j = 0, k = 0; i < p_view_log->aid_base_cnt && j < p_view_log->aid_inc_cnt;)
198 {
199 if (p_view_log->aid_base[i] <= p_view_log->aid_inc[j])
200 {
201 if (p_view_log->aid_base[i] == p_view_log->aid_inc[j])
202 {
203 log_error("Duplicate aid = %d found in both Base (offset = %d) and Inc (offset = %d)\n",
204 p_view_log->aid_base[i], i, j);
205 j++; // Skip duplicate one in Inc
206 }
207
208 aid_new[k++] = p_view_log->aid_base[i++];
209 }
210 else if (p_view_log->aid_base[i] > p_view_log->aid_inc[j])
211 {
212 aid_new[k++] = p_view_log->aid_inc[j++];
213 }
214 }
215
216 memcpy(aid_new + k, p_view_log->aid_base + i, sizeof(int32_t) * (size_t)(p_view_log->aid_base_cnt - i));
217 k += (p_view_log->aid_base_cnt - i);
218 memcpy(aid_new + k, p_view_log->aid_inc + j, sizeof(int32_t) * (size_t)(p_view_log->aid_inc_cnt - j));
219 k += (p_view_log->aid_inc_cnt - j);
220
221 free(p_view_log->aid_base);
222 p_view_log->aid_base = aid_new;
223 p_view_log->aid_base_cnt = k;
224
225 p_view_log->aid_inc_cnt = 0;
226
227 return 0;
228 }
229
230 int article_view_log_is_viewed(int32_t aid, const ARTICLE_VIEW_LOG *p_view_log)
231 {
232 int left;
233 int right;
234 int mid;
235 int i;
236
237 if (p_view_log == NULL)
238 {
239 log_error("article_view_log_is_viewed() error: NULL pointer\n");
240 return -1;
241 }
242
243 for (i = 0; i < 2; i++)
244 {
245 left = 0;
246 right = (i == 0 ? p_view_log->aid_base_cnt : p_view_log->aid_inc_cnt) - 1;
247
248 if (right < 0)
249 {
250 continue;
251 }
252
253 while (left < right)
254 {
255 mid = (left + right) / 2;
256 if (aid < (i == 0 ? p_view_log->aid_base[mid] : p_view_log->aid_inc[mid]))
257 {
258 right = mid;
259 }
260 else if (aid > (i == 0 ? p_view_log->aid_base[mid] : p_view_log->aid_inc[mid]))
261 {
262 left = mid + 1;
263 }
264 else // if (aid == p_view_log->aid_base[mid])
265 {
266 return 1;
267 }
268 }
269
270 if (aid == (i == 0 ? p_view_log->aid_base[left] : p_view_log->aid_inc[left])) // Found
271 {
272 return 1;
273 }
274 }
275
276 return 0;
277 }
278
279 int article_view_log_set_viewed(int32_t aid, ARTICLE_VIEW_LOG *p_view_log)
280 {
281 int left;
282 int right;
283 int mid;
284 int i;
285
286 if (p_view_log == NULL)
287 {
288 log_error("article_view_log_set_viewed() error: NULL pointer\n");
289 return -1;
290 }
291
292 for (i = 0; i < 2; i++)
293 {
294 left = 0;
295 right = (i == 0 ? p_view_log->aid_base_cnt : p_view_log->aid_inc_cnt) - 1;
296
297 if (right < 0)
298 {
299 continue;
300 }
301
302 while (left < right)
303 {
304 mid = (left + right) / 2;
305 if (aid < (i == 0 ? p_view_log->aid_base[mid] : p_view_log->aid_inc[mid]))
306 {
307 right = mid;
308 }
309 else if (aid > (i == 0 ? p_view_log->aid_base[mid] : p_view_log->aid_inc[mid]))
310 {
311 left = mid + 1;
312 }
313 else // if (aid == p_view_log->aid_base[mid])
314 {
315 return 0; // Already set
316 }
317 }
318
319 if (aid == (i == 0 ? p_view_log->aid_base[left] : p_view_log->aid_inc[left])) // Found
320 {
321 return 0; // Already set
322 }
323 }
324
325 // Merge if Inc is full
326 if (p_view_log->aid_inc_cnt >= MAX_AID_INC_CNT)
327 {
328 article_view_log_merge_inc(p_view_log);
329
330 p_view_log->aid_inc[(p_view_log->aid_inc_cnt)++] = aid;
331
332 return 1; // Set complete
333 }
334
335 if (right < 0)
336 {
337 right = 0;
338 }
339 else if (aid > p_view_log->aid_inc[left])
340 {
341 right = left + 1;
342 }
343
344 for (i = p_view_log->aid_inc_cnt - 1; i >= right; i--)
345 {
346 p_view_log->aid_inc[i + 1] = p_view_log->aid_inc[i];
347 }
348
349 p_view_log->aid_inc[right] = aid;
350 (p_view_log->aid_inc_cnt)++;
351
352 return 1; // Set complete
353 }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1