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

Annotation of /lbbs/src/article_view_log.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.10 - (hide annotations)
Tue Oct 14 03:24:27 2025 UTC (5 months ago) by sysadm
Branch: MAIN
Changes since 1.9: +1 -1 lines
Content type: text/x-csrc
Skip save view_log if there is no incremental data

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

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