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

Diff of /lbbs/src/article_favor.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.1 by sysadm, Wed Oct 15 00:45:52 2025 UTC Revision 1.8 by sysadm, Tue Nov 4 14:58:56 2025 UTC
# Line 1  Line 1 
1  /***************************************************************************  /* SPDX-License-Identifier: GPL-3.0-or-later */
2                                           article_favor.c  -  description  /*
3                                                           -------------------   * article_favor
4          Copyright            : (C) 2004-2025 by Leaflet   *   - data model and basic operations of user favorite articles
5          Email                : leaflet@leafok.com   *
6   ***************************************************************************/   * Copyright (C) 2004-2025  Leaflet <leaflet@leafok.com>
7     */
 /***************************************************************************  
  *                                                                         *  
  *   This program is free software; you can redistribute it and/or modify  *  
  *   it under the terms of the GNU General Public License as published by  *  
  *   the Free Software Foundation; either version 3 of the License, or     *  
  *   (at your option) any later version.                                   *  
  *                                                                         *  
  ***************************************************************************/  
8    
9  #include "article_favor.h"  #include "article_favor.h"
10  #include "common.h"  #include "common.h"
# Line 20  Line 12 
12  #include "log.h"  #include "log.h"
13  #include <stdlib.h>  #include <stdlib.h>
14  #include <string.h>  #include <string.h>
15    #include <sys/param.h>
16    
17  ARTICLE_FAVOR BBS_article_favor;  ARTICLE_FAVOR BBS_article_favor;
18    
# Line 41  int article_favor_load(int uid, ARTICLE_ Line 34  int article_favor_load(int uid, ARTICLE_
34          if (uid == 0)          if (uid == 0)
35          {          {
36                  p_favor->aid_base_cnt = 0;                  p_favor->aid_base_cnt = 0;
                 p_favor->aid_base = NULL;  
37    
38                  if (!keep_inc)                  if (!keep_inc)
39                  {                  {
# Line 66  int article_favor_load(int uid, ARTICLE_ Line 58  int article_favor_load(int uid, ARTICLE_
58                  log_error("Query article_favorite error: %s\n", mysql_error(db));                  log_error("Query article_favorite error: %s\n", mysql_error(db));
59                  return -3;                  return -3;
60          }          }
61          if ((rs = mysql_store_result(db)) == NULL)          if ((rs = mysql_use_result(db)) == NULL)
62          {          {
63                  log_error("Get article_favorite data failed\n");                  log_error("Get article_favorite data failed\n");
64                  return -3;                  return -3;
65          }          }
66    
67          p_favor->aid_base_cnt = 0;          p_favor->aid_base_cnt = 0;
         p_favor->aid_base = malloc(sizeof(int32_t) * mysql_num_rows(rs));  
         if (p_favor->aid_base == NULL)  
         {  
                 log_error("malloc(INT32 * %d) error: OOM\n", mysql_num_rows(rs));  
                 mysql_free_result(rs);  
                 mysql_close(db);  
                 return -4;  
         }  
68    
69          while ((row = mysql_fetch_row(rs)))          while ((row = mysql_fetch_row(rs)))
70          {          {
71                  p_favor->aid_base[(p_favor->aid_base_cnt)++] = atoi(row[0]);                  p_favor->aid_base[p_favor->aid_base_cnt] = atoi(row[0]);
72                    (p_favor->aid_base_cnt)++;
73                    if (p_favor->aid_base_cnt >= MAX_FAVOR_AID_BASE_CNT)
74                    {
75                            log_error("Too many article_favorite records for uid=%d\n",
76                                              uid);
77                            break;
78                    }
79          }          }
80          mysql_free_result(rs);          mysql_free_result(rs);
81    
# Line 108  int article_favor_unload(ARTICLE_FAVOR * Line 99  int article_favor_unload(ARTICLE_FAVOR *
99                  return -1;                  return -1;
100          }          }
101    
102          if (p_favor->aid_base != NULL)          p_favor->aid_base_cnt = 0;
         {  
                 free(p_favor->aid_base);  
                 p_favor->aid_base = NULL;  
                 p_favor->aid_base_cnt = 0;  
         }  
103    
104          return 0;          return 0;
105  }  }
# Line 154  int article_favor_save_inc(const ARTICLE Line 140  int article_favor_save_inc(const ARTICLE
140                           "DELETE FROM article_favorite WHERE UID = %d AND AID IN (",                           "DELETE FROM article_favorite WHERE UID = %d AND AID IN (",
141                           p_favor->uid);                           p_favor->uid);
142    
143          for (i = 0, j = 0; i < p_favor->aid_base_cnt && j < p_favor->aid_inc_cnt;)          for (i = 0, j = 0; j < p_favor->aid_inc_cnt;)
144          {          {
145                  if (p_favor->aid_base[i] == p_favor->aid_inc[j]) // XOR - delete record                  if (i < p_favor->aid_base_cnt && p_favor->aid_base[i] == p_favor->aid_inc[j]) // XOR - delete record
146                  {                  {
147                          snprintf(tuple_tmp, sizeof(tuple_tmp), "%d, ", p_favor->aid_inc[j]);                          snprintf(tuple_tmp, sizeof(tuple_tmp), "%d, ", p_favor->aid_inc[j]);
148                          strncat(sql_del, tuple_tmp, sizeof(sql_del) - 1 - strnlen(sql_del, sizeof(sql_del)));                          strncat(sql_del, tuple_tmp, sizeof(sql_del) - 1 - strnlen(sql_del, sizeof(sql_del)));
# Line 165  int article_favor_save_inc(const ARTICLE Line 151  int article_favor_save_inc(const ARTICLE
151                          i++;                          i++;
152                          j++;                          j++;
153                  }                  }
154                  else if (p_favor->aid_base[i] < p_favor->aid_inc[j]) // skip existing record                  else if (i < p_favor->aid_base_cnt && p_favor->aid_base[i] < p_favor->aid_inc[j]) // skip existing record
155                  {                  {
156                          i++;                          i++;
157                  }                  }
158                  else // if (p_favor->aid_base[i] > p_favor->aid_inc[j])                  else // if (i >= p_favor->aid_base_cnt || p_favor->aid_base[i] > p_favor->aid_inc[j])
159                  {                  {
160                          snprintf(tuple_tmp, sizeof(tuple_tmp),                          snprintf(tuple_tmp, sizeof(tuple_tmp),
161                                           "(%d, %d), ",                                           "(%d, %d), ",
# Line 232  int article_favor_save_inc(const ARTICLE Line 218  int article_favor_save_inc(const ARTICLE
218    
219  int article_favor_merge_inc(ARTICLE_FAVOR *p_favor)  int article_favor_merge_inc(ARTICLE_FAVOR *p_favor)
220  {  {
221          int32_t *aid_new;          int32_t aid_new[MAX_FAVOR_AID_BASE_CNT];
         int aid_new_cnt;  
222          int i, j, k;          int i, j, k;
223            int len;
224    
225          if (p_favor == NULL)          if (p_favor == NULL)
226          {          {
# Line 247  int article_favor_merge_inc(ARTICLE_FAVO Line 233  int article_favor_merge_inc(ARTICLE_FAVO
233                  return 0;                  return 0;
234          }          }
235    
236          aid_new_cnt = p_favor->aid_base_cnt + p_favor->aid_inc_cnt;          for (i = 0, j = 0, k = 0; i < p_favor->aid_base_cnt && j < p_favor->aid_inc_cnt && k < MAX_FAVOR_AID_BASE_CNT;)
   
         aid_new = malloc(sizeof(int32_t) * (size_t)aid_new_cnt);  
         if (aid_new == NULL)  
         {  
                 log_error("malloc(INT32 * %d) error: OOM\n", aid_new_cnt);  
                 return -2;  
         }  
   
         for (i = 0, j = 0, k = 0; i < p_favor->aid_base_cnt && j < p_favor->aid_inc_cnt;)  
237          {          {
238                  if (p_favor->aid_base[i] == p_favor->aid_inc[j]) // XOR - discard duplicate pair                  if (p_favor->aid_base[i] == p_favor->aid_inc[j]) // XOR - discard duplicate pair
239                  {                  {
# Line 273  int article_favor_merge_inc(ARTICLE_FAVO Line 250  int article_favor_merge_inc(ARTICLE_FAVO
250                  }                  }
251          }          }
252    
253          memcpy(aid_new + k, p_favor->aid_base + i, sizeof(int32_t) * (size_t)(p_favor->aid_base_cnt - i));          len = MIN(p_favor->aid_base_cnt - i, MAX_FAVOR_AID_BASE_CNT - k);
254          k += (p_favor->aid_base_cnt - i);          if (len > 0)
255          memcpy(aid_new + k, p_favor->aid_inc + j, sizeof(int32_t) * (size_t)(p_favor->aid_inc_cnt - j));          {
256          k += (p_favor->aid_inc_cnt - j);                  memcpy(aid_new + k, p_favor->aid_base + i,
257                               sizeof(int32_t) * (size_t)len);
258                    i += len;
259                    k += len;
260            }
261            if (i < p_favor->aid_base_cnt)
262            {
263                    log_error("Too many base aids, %d will be discarded\n", p_favor->aid_base_cnt - i);
264            }
265    
266          free(p_favor->aid_base);          len = MIN(p_favor->aid_inc_cnt - j, MAX_FAVOR_AID_BASE_CNT - k);
267          p_favor->aid_base = aid_new;          if (len > 0)
268          p_favor->aid_base_cnt = k;          {
269                    memcpy(aid_new + k, p_favor->aid_inc + j,
270                               sizeof(int32_t) * (size_t)len);
271                    j += len;
272                    k += len;
273            }
274            if (j < p_favor->aid_inc_cnt)
275            {
276                    log_error("Too many inc aids, %d will be discarded\n", p_favor->aid_inc_cnt - j);
277            }
278    
279            memcpy(p_favor->aid_base, aid_new, sizeof(int32_t) * (size_t)k);
280    
281            p_favor->aid_base_cnt = k;
282          p_favor->aid_inc_cnt = 0;          p_favor->aid_inc_cnt = 0;
283    
284          return 0;          return 0;
# Line 316  int article_favor_check(int32_t aid, con Line 313  int article_favor_check(int32_t aid, con
313                          mid = (left + right) / 2;                          mid = (left + right) / 2;
314                          if (aid < (i == 0 ? p_favor->aid_base[mid] : p_favor->aid_inc[mid]))                          if (aid < (i == 0 ? p_favor->aid_base[mid] : p_favor->aid_inc[mid]))
315                          {                          {
316                                  right = mid;                                  right = mid - 1;
317                          }                          }
318                          else if (aid > (i == 0 ? p_favor->aid_base[mid] : p_favor->aid_inc[mid]))                          else if (aid > (i == 0 ? p_favor->aid_base[mid] : p_favor->aid_inc[mid]))
319                          {                          {
# Line 367  int article_favor_set(int32_t aid, ARTIC Line 364  int article_favor_set(int32_t aid, ARTIC
364                          mid = (left + right) / 2;                          mid = (left + right) / 2;
365                          if (aid < (i == 0 ? p_favor->aid_base[mid] : p_favor->aid_inc[mid]))                          if (aid < (i == 0 ? p_favor->aid_base[mid] : p_favor->aid_inc[mid]))
366                          {                          {
367                                  right = mid;                                  right = mid - 1;
368                          }                          }
369                          else if (aid > (i == 0 ? p_favor->aid_base[mid] : p_favor->aid_inc[mid]))                          else if (aid > (i == 0 ? p_favor->aid_base[mid] : p_favor->aid_inc[mid]))
370                          {                          {
# Line 393  int article_favor_set(int32_t aid, ARTIC Line 390  int article_favor_set(int32_t aid, ARTIC
390    
391          if (aid == p_favor->aid_inc[left] && p_favor->aid_inc_cnt > 0) // Unset          if (aid == p_favor->aid_inc[left] && p_favor->aid_inc_cnt > 0) // Unset
392          {          {
393                  for (i = left; i < p_favor->aid_inc_cnt - 1; i++)                  if (p_favor->aid_inc_cnt > left + 1)
394                  {                  {
395                          p_favor->aid_inc[i] = p_favor->aid_inc[i + 1];                          memmove(p_favor->aid_inc + left,
396                                            p_favor->aid_inc + left + 1,
397                                            sizeof(int32_t) * (size_t)(p_favor->aid_inc_cnt - left - 1));
398                  }                  }
399    
400                  (p_favor->aid_inc_cnt)--;                  (p_favor->aid_inc_cnt)--;
# Line 429  int article_favor_set(int32_t aid, ARTIC Line 428  int article_favor_set(int32_t aid, ARTIC
428                  right = left + 1;                  right = left + 1;
429          }          }
430    
431          for (i = p_favor->aid_inc_cnt - 1; i >= right; i--)          if (p_favor->aid_inc_cnt > right)
432          {          {
433                  p_favor->aid_inc[i + 1] = p_favor->aid_inc[i];                  memmove(p_favor->aid_inc + right + 1,
434                                    p_favor->aid_inc + right,
435                                    sizeof(int32_t) * (size_t)(p_favor->aid_inc_cnt - right));
436          }          }
437    
438          p_favor->aid_inc[right] = aid;          p_favor->aid_inc[right] = aid;
# Line 499  int query_favor_articles(ARTICLE_FAVOR * Line 500  int query_favor_articles(ARTICLE_FAVOR *
500                          return -3;                          return -3;
501                  }                  }
502    
503                  // acquire lock of section                  if (get_section_info(p_section, p_snames[i], NULL, NULL) < 0)
                 if (section_list_rd_lock(p_section) < 0)  
                 {  
                         log_error("section_list_rd_lock(sid = %d) error\n", p_section->sid);  
                         return -4;  
                 }  
   
                 memcpy(p_snames[i], p_section->sname, sizeof(p_snames[i]));  
   
                 // release lock of section  
                 if (section_list_rd_unlock(p_section) < 0)  
504                  {                  {
505                          log_error("section_list_rd_unlock(sid = %d) error\n", p_section->sid);                          log_error("get_section_info(sid=%d) error\n", p_section->sid);
506                          return -4;                          return -4;
507                  }                  }
508          }          }


Legend:
Removed lines/characters  
Changed lines/characters
  Added lines/characters

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