/[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.15 - (hide annotations)
Fri Oct 24 02:07:01 2025 UTC (4 months, 3 weeks ago) by sysadm
Branch: MAIN
Changes since 1.14: +2 -2 lines
Content type: text/x-csrc
Refine search algorithm

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 sysadm 1.14 int len;
189 sysadm 1.1
190     if (p_view_log == NULL)
191     {
192 sysadm 1.9 log_error("NULL pointer error\n");
193 sysadm 1.1 return -1;
194     }
195    
196     if (p_view_log->aid_inc_cnt == 0) // Nothing to be merged
197     {
198     return 0;
199     }
200    
201     aid_new_cnt = p_view_log->aid_base_cnt + p_view_log->aid_inc_cnt;
202    
203     aid_new = malloc(sizeof(int32_t) * (size_t)aid_new_cnt);
204     if (aid_new == NULL)
205     {
206     log_error("malloc(INT32 * %d) error: OOM\n", aid_new_cnt);
207     return -2;
208     }
209    
210     for (i = 0, j = 0, k = 0; i < p_view_log->aid_base_cnt && j < p_view_log->aid_inc_cnt;)
211     {
212     if (p_view_log->aid_base[i] <= p_view_log->aid_inc[j])
213     {
214     if (p_view_log->aid_base[i] == p_view_log->aid_inc[j])
215     {
216     log_error("Duplicate aid = %d found in both Base (offset = %d) and Inc (offset = %d)\n",
217     p_view_log->aid_base[i], i, j);
218     j++; // Skip duplicate one in Inc
219     }
220    
221     aid_new[k++] = p_view_log->aid_base[i++];
222     }
223     else if (p_view_log->aid_base[i] > p_view_log->aid_inc[j])
224     {
225     aid_new[k++] = p_view_log->aid_inc[j++];
226     }
227     }
228    
229 sysadm 1.14 len = p_view_log->aid_base_cnt - i;
230     if (len > 0)
231     {
232     memcpy(aid_new + k, p_view_log->aid_base + i,
233     sizeof(int32_t) * (size_t)len);
234     k += len;
235     }
236     len = p_view_log->aid_inc_cnt - j;
237     if (len > 0)
238     {
239     memcpy(aid_new + k, p_view_log->aid_inc + j,
240     sizeof(int32_t) * (size_t)len);
241     k += len;
242     }
243 sysadm 1.1
244     free(p_view_log->aid_base);
245     p_view_log->aid_base = aid_new;
246     p_view_log->aid_base_cnt = k;
247    
248     p_view_log->aid_inc_cnt = 0;
249    
250     return 0;
251     }
252    
253     int article_view_log_is_viewed(int32_t aid, const ARTICLE_VIEW_LOG *p_view_log)
254     {
255     int left;
256     int right;
257     int mid;
258     int i;
259    
260     if (p_view_log == NULL)
261     {
262 sysadm 1.9 log_error("NULL pointer error\n");
263 sysadm 1.1 return -1;
264     }
265    
266     for (i = 0; i < 2; i++)
267     {
268     left = 0;
269     right = (i == 0 ? p_view_log->aid_base_cnt : p_view_log->aid_inc_cnt) - 1;
270    
271     if (right < 0)
272     {
273     continue;
274     }
275    
276     while (left < right)
277     {
278     mid = (left + right) / 2;
279     if (aid < (i == 0 ? p_view_log->aid_base[mid] : p_view_log->aid_inc[mid]))
280     {
281 sysadm 1.15 right = mid - 1;
282 sysadm 1.1 }
283     else if (aid > (i == 0 ? p_view_log->aid_base[mid] : p_view_log->aid_inc[mid]))
284     {
285     left = mid + 1;
286     }
287     else // if (aid == p_view_log->aid_base[mid])
288     {
289     return 1;
290     }
291     }
292    
293     if (aid == (i == 0 ? p_view_log->aid_base[left] : p_view_log->aid_inc[left])) // Found
294     {
295     return 1;
296     }
297     }
298    
299     return 0;
300     }
301    
302     int article_view_log_set_viewed(int32_t aid, ARTICLE_VIEW_LOG *p_view_log)
303     {
304     int left;
305     int right;
306     int mid;
307     int i;
308    
309     if (p_view_log == NULL)
310     {
311 sysadm 1.9 log_error("NULL pointer error\n");
312 sysadm 1.1 return -1;
313     }
314    
315     for (i = 0; i < 2; i++)
316     {
317     left = 0;
318     right = (i == 0 ? p_view_log->aid_base_cnt : p_view_log->aid_inc_cnt) - 1;
319    
320     if (right < 0)
321     {
322     continue;
323     }
324    
325     while (left < right)
326     {
327     mid = (left + right) / 2;
328     if (aid < (i == 0 ? p_view_log->aid_base[mid] : p_view_log->aid_inc[mid]))
329     {
330 sysadm 1.15 right = mid - 1;
331 sysadm 1.1 }
332     else if (aid > (i == 0 ? p_view_log->aid_base[mid] : p_view_log->aid_inc[mid]))
333     {
334     left = mid + 1;
335     }
336     else // if (aid == p_view_log->aid_base[mid])
337     {
338     return 0; // Already set
339     }
340     }
341    
342     if (aid == (i == 0 ? p_view_log->aid_base[left] : p_view_log->aid_inc[left])) // Found
343     {
344     return 0; // Already set
345     }
346     }
347    
348     // Merge if Inc is full
349 sysadm 1.8 if (p_view_log->aid_inc_cnt >= MAX_VIEWED_AID_INC_CNT)
350 sysadm 1.1 {
351 sysadm 1.3 // Save incremental article view log
352     if (article_view_log_save_inc(p_view_log) < 0)
353     {
354     log_error("article_view_log_save_inc() error\n");
355     return -2;
356     }
357    
358 sysadm 1.1 article_view_log_merge_inc(p_view_log);
359    
360     p_view_log->aid_inc[(p_view_log->aid_inc_cnt)++] = aid;
361    
362     return 1; // Set complete
363     }
364    
365     if (right < 0)
366     {
367     right = 0;
368     }
369     else if (aid > p_view_log->aid_inc[left])
370     {
371     right = left + 1;
372     }
373    
374 sysadm 1.13 if (p_view_log->aid_inc_cnt > right)
375 sysadm 1.12 {
376 sysadm 1.13 memmove(p_view_log->aid_inc + right + 1,
377     p_view_log->aid_inc + right,
378     sizeof(int32_t) * (size_t)(p_view_log->aid_inc_cnt - right));
379 sysadm 1.12 }
380 sysadm 1.1
381     p_view_log->aid_inc[right] = aid;
382     (p_view_log->aid_inc_cnt)++;
383    
384     return 1; // Set complete
385     }

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