/[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.1 - (hide annotations)
Sat Jun 7 07:59:38 2025 UTC (9 months, 1 week ago) by sysadm
Branch: MAIN
Content type: text/x-csrc
Add article_view_log

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

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