1 /*
2 * Copyright (C) 2021 Jakub Kruszona-Zawadzki, Core Technology Sp. z o.o.
3 *
4 * This file is part of MooseFS.
5 *
6 * MooseFS is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, version 2 (only).
9 *
10 * MooseFS is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with MooseFS; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA
18 * or visit http://www.gnu.org/licenses/gpl-2.0.html
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <stdlib.h>
26 #include <pthread.h>
27 #include <inttypes.h>
28
29 #define CSDB_HASHSIZE 256
30 #define CSDB_HASH(ip,port) (((ip)*0x7b348943+(port))%(CSDB_HASHSIZE))
31
32 typedef struct _csdbentry {
33 uint32_t ip;
34 uint16_t port;
35 uint32_t readopcnt;
36 uint32_t writeopcnt;
37 struct _csdbentry *next;
38 } csdbentry;
39
40 static csdbentry *csdbhtab[CSDB_HASHSIZE];
41 static pthread_mutex_t *csdblock;
42
csdb_init(void)43 void csdb_init(void) {
44 uint32_t i;
45 for (i=0 ; i<CSDB_HASHSIZE ; i++) {
46 csdbhtab[i]=NULL;
47 }
48 csdblock = malloc(sizeof(pthread_mutex_t));
49 pthread_mutex_init(csdblock,NULL);
50 }
51
csdb_term(void)52 void csdb_term(void) {
53 uint32_t i;
54 csdbentry *cs,*csn;
55
56 pthread_mutex_destroy(csdblock);
57 free(csdblock);
58 for (i=0 ; i<CSDB_HASHSIZE ; i++) {
59 for (cs = csdbhtab[i] ; cs ; cs = csn) {
60 csn = cs->next;
61 free(cs);
62 }
63 }
64 }
65
csdb_getreadcnt(uint32_t ip,uint16_t port)66 uint32_t csdb_getreadcnt(uint32_t ip,uint16_t port) {
67 uint32_t hash = CSDB_HASH(ip,port);
68 uint32_t result = 0;
69 csdbentry *e;
70 pthread_mutex_lock(csdblock);
71 for (e=csdbhtab[hash] ; e ; e=e->next) {
72 if (e->ip == ip && e->port == port) {
73 result = e->readopcnt;
74 break;
75 }
76 }
77 pthread_mutex_unlock(csdblock);
78 return result;
79 }
80
csdb_getwritecnt(uint32_t ip,uint16_t port)81 uint32_t csdb_getwritecnt(uint32_t ip,uint16_t port) {
82 uint32_t hash = CSDB_HASH(ip,port);
83 uint32_t result = 0;
84 csdbentry *e;
85 pthread_mutex_lock(csdblock);
86 for (e=csdbhtab[hash] ; e ; e=e->next) {
87 if (e->ip == ip && e->port == port) {
88 result = e->writeopcnt;
89 break;
90 }
91 }
92 pthread_mutex_unlock(csdblock);
93 return result;
94 }
95
csdb_getopcnt(uint32_t ip,uint16_t port)96 uint32_t csdb_getopcnt(uint32_t ip,uint16_t port) {
97 uint32_t hash = CSDB_HASH(ip,port);
98 uint32_t result = 0;
99 csdbentry *e;
100 pthread_mutex_lock(csdblock);
101 for (e=csdbhtab[hash] ; e ; e=e->next) {
102 if (e->ip == ip && e->port == port) {
103 result = e->readopcnt + e->writeopcnt;
104 break;
105 }
106 }
107 pthread_mutex_unlock(csdblock);
108 return result;
109 }
110
csdb_readinc(uint32_t ip,uint16_t port)111 void csdb_readinc(uint32_t ip,uint16_t port) {
112 uint32_t hash = CSDB_HASH(ip,port);
113 csdbentry *e;
114 pthread_mutex_lock(csdblock);
115 for (e=csdbhtab[hash] ; e ; e=e->next) {
116 if (e->ip == ip && e->port == port) {
117 e->readopcnt++;
118 pthread_mutex_unlock(csdblock);
119 return;
120 }
121 }
122 e = malloc(sizeof(csdbentry));
123 e->ip = ip;
124 e->port = port;
125 e->readopcnt = 1;
126 e->writeopcnt = 0;
127 e->next = csdbhtab[hash];
128 csdbhtab[hash] = e;
129 pthread_mutex_unlock(csdblock);
130 }
131
csdb_readdec(uint32_t ip,uint16_t port)132 void csdb_readdec(uint32_t ip,uint16_t port) {
133 uint32_t hash = CSDB_HASH(ip,port);
134 csdbentry *e;
135 pthread_mutex_lock(csdblock);
136 for (e=csdbhtab[hash] ; e ; e=e->next) {
137 if (e->ip == ip && e->port == port) {
138 e->readopcnt--;
139 pthread_mutex_unlock(csdblock);
140 return;
141 }
142 }
143 pthread_mutex_unlock(csdblock);
144 }
145
csdb_writeinc(uint32_t ip,uint16_t port)146 void csdb_writeinc(uint32_t ip,uint16_t port) {
147 uint32_t hash = CSDB_HASH(ip,port);
148 csdbentry *e;
149 pthread_mutex_lock(csdblock);
150 for (e=csdbhtab[hash] ; e ; e=e->next) {
151 if (e->ip == ip && e->port == port) {
152 e->writeopcnt++;
153 pthread_mutex_unlock(csdblock);
154 return;
155 }
156 }
157 e = malloc(sizeof(csdbentry));
158 e->ip = ip;
159 e->port = port;
160 e->readopcnt = 0;
161 e->writeopcnt = 1;
162 e->next = csdbhtab[hash];
163 csdbhtab[hash] = e;
164 pthread_mutex_unlock(csdblock);
165 }
166
csdb_writedec(uint32_t ip,uint16_t port)167 void csdb_writedec(uint32_t ip,uint16_t port) {
168 uint32_t hash = CSDB_HASH(ip,port);
169 csdbentry *e;
170 pthread_mutex_lock(csdblock);
171 for (e=csdbhtab[hash] ; e ; e=e->next) {
172 if (e->ip == ip && e->port == port) {
173 e->writeopcnt--;
174 pthread_mutex_unlock(csdblock);
175 return;
176 }
177 }
178 pthread_mutex_unlock(csdblock);
179 }
180