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