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

Diff of /lbbs/src/user_list.c

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

Revision 1.14 by sysadm, Wed Oct 22 16:12:50 2025 UTC Revision 1.20 by sysadm, Thu Oct 23 09:54:54 2025 UTC
# Line 19  Line 19 
19  #include "log.h"  #include "log.h"
20  #include "trie_dict.h"  #include "trie_dict.h"
21  #include "user_list.h"  #include "user_list.h"
22    #include "user_stat.h"
23  #include <errno.h>  #include <errno.h>
24  #include <stdlib.h>  #include <stdlib.h>
25  #include <string.h>  #include <string.h>
# Line 53  struct user_list_pool_t Line 54  struct user_list_pool_t
54          USER_ONLINE_LIST user_online_list[2];          USER_ONLINE_LIST user_online_list[2];
55          USER_ONLINE_LIST *p_online_current;          USER_ONLINE_LIST *p_online_current;
56          USER_ONLINE_LIST *p_online_new;          USER_ONLINE_LIST *p_online_new;
57            USER_STAT_MAP user_stat_map;
58  };  };
59  typedef struct user_list_pool_t USER_LIST_POOL;  typedef struct user_list_pool_t USER_LIST_POOL;
60    
# Line 119  static int user_info_index_uid_comp(cons Line 121  static int user_info_index_uid_comp(cons
121    
122  int user_list_load(MYSQL *db, USER_LIST *p_list)  int user_list_load(MYSQL *db, USER_LIST *p_list)
123  {  {
         USER_INFO_INDEX_UID index_uid[BBS_max_user_count];  
124          MYSQL_RES *rs = NULL;          MYSQL_RES *rs = NULL;
125          MYSQL_ROW row;          MYSQL_ROW row;
126          char sql[SQL_BUFFER_LEN];          char sql[SQL_BUFFER_LEN];
127          int ret = 0;          int ret = 0;
128          int i = 0;          int i;
129          int32_t last_uid = -1;          int j;
130          size_t intro_buf_offset = 0L;          int32_t last_uid;
131            size_t intro_buf_offset;
132          size_t intro_len;          size_t intro_len;
133    
134          if (db == NULL || p_list == NULL)          if (db == NULL || p_list == NULL)
# Line 139  int user_list_load(MYSQL *db, USER_LIST Line 141  int user_list_load(MYSQL *db, USER_LIST
141          {          {
142                  last_uid = p_list->users[p_list->user_count - 1].uid;                  last_uid = p_list->users[p_list->user_count - 1].uid;
143          }          }
144            else
145            {
146                    last_uid = -1;
147            }
148    
149          snprintf(sql, sizeof(sql),          snprintf(sql, sizeof(sql),
150                           "SELECT user_list.UID AS UID, username, nickname, gender, gender_pub, life, exp, visit_count, "                           "SELECT user_list.UID AS UID, username, nickname, gender, gender_pub, life, exp, visit_count, "
# Line 192  int user_list_load(MYSQL *db, USER_LIST Line 198  int user_list_load(MYSQL *db, USER_LIST
198                  p_list->users[i].intro = p_list->user_intro_buf + intro_buf_offset;                  p_list->users[i].intro = p_list->user_intro_buf + intro_buf_offset;
199                  intro_buf_offset += (intro_len + 1);                  intro_buf_offset += (intro_len + 1);
200    
                 // index  
                 index_uid[i].uid = p_list->users[i].uid;  
                 index_uid[i].id = i;  
   
201                  i++;                  i++;
202                  if (i >= BBS_max_user_count)                  if (i >= BBS_max_user_count)
203                  {                  {
# Line 206  int user_list_load(MYSQL *db, USER_LIST Line 208  int user_list_load(MYSQL *db, USER_LIST
208          mysql_free_result(rs);          mysql_free_result(rs);
209          rs = NULL;          rs = NULL;
210    
         // Sort index  
211          if (i != p_list->user_count || p_list->users[i - 1].uid != last_uid) // Count of users changed          if (i != p_list->user_count || p_list->users[i - 1].uid != last_uid) // Count of users changed
212          {          {
213                  qsort(index_uid, (size_t)i, sizeof(USER_INFO_INDEX_UID), user_info_index_uid_comp);                  // Rebuild index
214                  memcpy(p_list->index_uid, index_uid, sizeof(USER_INFO_INDEX_UID) * (size_t)i);                  for (j = 0; j < i; j++)
215                    {
216                            p_list->index_uid[j].uid = p_list->users[j].uid;
217                            p_list->index_uid[j].id = j;
218                    }
219    
220                    qsort(p_list->index_uid, (size_t)i, sizeof(USER_INFO_INDEX_UID), user_info_index_uid_comp);
221    
222  #ifdef _DEBUG  #ifdef _DEBUG
223                  log_error("Rebuild index of %d users, last_uid=%d\n", i, p_list->users[i - 1].uid);                  log_error("Rebuild index of %d users, last_uid=%d\n", i, p_list->users[i - 1].uid);
# Line 236  int user_online_list_load(MYSQL *db, USE Line 243  int user_online_list_load(MYSQL *db, USE
243          char sql[SQL_BUFFER_LEN];          char sql[SQL_BUFFER_LEN];
244          int ret = 0;          int ret = 0;
245          int i;          int i;
246            int j;
247    
248          if (db == NULL || p_list == NULL)          if (db == NULL || p_list == NULL)
249          {          {
# Line 297  int user_online_list_load(MYSQL *db, USE Line 305  int user_online_list_load(MYSQL *db, USE
305                  p_list->users[i].login_tm = (row[4] == NULL ? 0 : atol(row[4]));                  p_list->users[i].login_tm = (row[4] == NULL ? 0 : atol(row[4]));
306                  p_list->users[i].last_tm = (row[5] == NULL ? 0 : atol(row[5]));                  p_list->users[i].last_tm = (row[5] == NULL ? 0 : atol(row[5]));
307    
                 // index  
                 p_list->index_uid[i].uid = p_list->users[i].user_info.uid;  
                 p_list->index_uid[i].id = i;  
   
308                  i++;                  i++;
309                  if (i >= BBS_max_user_online_count)                  if (i >= BBS_max_user_online_count)
310                  {                  {
# Line 311  int user_online_list_load(MYSQL *db, USE Line 315  int user_online_list_load(MYSQL *db, USE
315          mysql_free_result(rs);          mysql_free_result(rs);
316          rs = NULL;          rs = NULL;
317    
         // Sort index  
318          if (i > 0)          if (i > 0)
319          {          {
320                    // Rebuild index
321                    for (j = 0; j < i; j++)
322                    {
323                            p_list->index_uid[j].uid = p_list->users[j].user_info.uid;
324                            p_list->index_uid[j].id = j;
325                    }
326    
327                  qsort(p_list->index_uid, (size_t)i, sizeof(USER_INFO_INDEX_UID), user_info_index_uid_comp);                  qsort(p_list->index_uid, (size_t)i, sizeof(USER_INFO_INDEX_UID), user_info_index_uid_comp);
328    
329  #ifdef _DEBUG  #ifdef _DEBUG
330                  log_error("Rebuild index of %d online users\n", i);                  log_error("Rebuild index of %d online users\n", i);
331  #endif  #endif
# Line 422  int user_list_pool_init(void) Line 433  int user_list_pool_init(void)
433          p_user_list_pool->p_online_current = &(p_user_list_pool->user_online_list[0]);          p_user_list_pool->p_online_current = &(p_user_list_pool->user_online_list[0]);
434          p_user_list_pool->p_online_new = &(p_user_list_pool->user_online_list[1]);          p_user_list_pool->p_online_new = &(p_user_list_pool->user_online_list[1]);
435    
436            user_stat_map_init(&(p_user_list_pool->user_stat_map));
437    
438          return 0;          return 0;
439  }  }
440    
# Line 974  int query_user_online_info_by_uid(int32_ Line 987  int query_user_online_info_by_uid(int32_
987          int32_t id;          int32_t id;
988          int ret = 0;          int ret = 0;
989          int i;          int i;
990            int user_cnt;
991    
992          if (p_users == NULL || p_user_cnt == NULL)          if (p_users == NULL || p_user_cnt == NULL)
993          {          {
# Line 981  int query_user_online_info_by_uid(int32_ Line 995  int query_user_online_info_by_uid(int32_
995                  return -1;                  return -1;
996          }          }
997    
998            user_cnt = *p_user_cnt;
999            *p_user_cnt = 0;
1000    
1001          // acquire lock of user list          // acquire lock of user list
1002          if (user_list_rd_lock(p_user_list_pool->semid) < 0)          if (user_list_rd_lock(p_user_list_pool->semid) < 0)
1003          {          {
# Line 1028  int query_user_online_info_by_uid(int32_ Line 1045  int query_user_online_info_by_uid(int32_
1045                  }                  }
1046    
1047                  for (i = 0;                  for (i = 0;
1048                           left < p_user_list_pool->p_online_current->user_count && i < *p_user_cnt &&                           left < p_user_list_pool->p_online_current->user_count && i < user_cnt &&
1049                           uid == p_user_list_pool->p_online_current->index_uid[left].uid;                           uid == p_user_list_pool->p_online_current->index_uid[left].uid;
1050                           left++, i++)                           left++, i++)
1051                  {                  {
# Line 1052  int query_user_online_info_by_uid(int32_ Line 1069  int query_user_online_info_by_uid(int32_
1069    
1070          return ret;          return ret;
1071  }  }
1072    
1073    int get_user_id_list(int32_t *p_uid_list, int *p_user_cnt, int start_uid)
1074    {
1075            int left;
1076            int right;
1077            int mid;
1078            int ret = 0;
1079            int i;
1080    
1081            if (p_uid_list == NULL || p_user_cnt == NULL)
1082            {
1083                    log_error("NULL pointer error\n");
1084                    return -1;
1085            }
1086    
1087            // acquire lock of user list
1088            if (user_list_rd_lock(p_user_list_pool->semid) < 0)
1089            {
1090                    log_error("user_list_rd_lock() error\n");
1091                    return -2;
1092            }
1093    
1094            left = 0;
1095            right = p_user_list_pool->p_current->user_count - 1;
1096    
1097            while (left < right)
1098            {
1099                    mid = (left + right) / 2;
1100                    if (start_uid < p_user_list_pool->p_current->index_uid[mid].uid)
1101                    {
1102                            right = mid;
1103                    }
1104                    else if (start_uid > p_user_list_pool->p_current->index_uid[mid].uid)
1105                    {
1106                            left = mid + 1;
1107                    }
1108                    else // if (start_uid == p_user_list_pool->p_current->index_uid[mid].uid)
1109                    {
1110                            left = mid;
1111                            break;
1112                    }
1113            }
1114    
1115            for (i = 0; i < *p_user_cnt && left + i < p_user_list_pool->p_current->user_count; i++)
1116            {
1117                    p_uid_list[i] = p_user_list_pool->p_current->index_uid[left + i].uid;
1118            }
1119            *p_user_cnt = i;
1120    
1121            // release lock of user list
1122            if (user_list_rd_unlock(p_user_list_pool->semid) < 0)
1123            {
1124                    log_error("user_list_rd_unlock() error\n");
1125                    ret = -1;
1126            }
1127    
1128            return ret;
1129    }
1130    
1131    int user_stat_update(void)
1132    {
1133            return user_stat_map_update(&(p_user_list_pool->user_stat_map));
1134    }
1135    
1136    int user_article_cnt_inc(int32_t uid, int n)
1137    {
1138            return user_stat_article_cnt_inc(&(p_user_list_pool->user_stat_map), uid, n);
1139    }
1140    
1141    int get_user_article_cnt(int32_t uid)
1142    {
1143            const USER_STAT *p_stat;
1144            int ret;
1145    
1146            ret = user_stat_get(&(p_user_list_pool->user_stat_map), uid, &p_stat);
1147            if (ret < 0)
1148            {
1149                    log_error("user_stat_get(uid=%d) error: %d\n", uid, ret);
1150                    return -1;
1151            }
1152            else if (ret == 0) // user not found
1153            {
1154                    return -1;
1155            }
1156    
1157            return p_stat->article_count;
1158    }


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

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