xref: /haiku/src/add-ons/kernel/file_systems/netfs/server/StatisticsManager.cpp (revision 5a1d355fdf2747f80f8c46e2539f844a0b813346)
1 // StatisticsManager.cpp
2 
3 #include "StatisticsManager.h"
4 
5 #include <AutoLocker.h>
6 #include <HashMap.h>
7 #include <Message.h>
8 
9 #include "DebugSupport.h"
10 #include "SecurityContext.h"
11 
12 typedef HashMap<HashString, int32>	UserCountMap;
13 
14 // ShareStatistics
15 class StatisticsManager::ShareStatistics {
16 public:
ShareStatistics(const char * share)17 	ShareStatistics(const char* share)
18 		: fShare(share),
19 		  fUsers()
20 	{
21 	}
22 
~ShareStatistics()23 	~ShareStatistics()
24 	{
25 	}
26 
Init()27 	status_t Init()
28 	{
29 		return fUsers.InitCheck();
30 	}
31 
GetShare() const32 	const char* GetShare() const
33 	{
34 		return fShare.GetString();
35 	}
36 
AddUser(const char * user)37 	void AddUser(const char* user)
38 	{
39 		int32 count = 0;
40 		if (fUsers.ContainsKey(user))
41 			count = fUsers.Get(user);
42 		count++;
43 		fUsers.Put(user, count);
44 	}
45 
RemoveUser(const char * user)46 	void RemoveUser(const char* user)
47 	{
48 		if (!fUsers.ContainsKey(user))
49 			return;
50 
51 		int32 count = fUsers.Get(user);
52 		count--;
53 		if (count > 0)
54 			fUsers.Put(user, count);
55 		else
56 			fUsers.Remove(user);
57 	}
58 
GetStatistics(BMessage * statistics)59 	status_t GetStatistics(BMessage* statistics)
60 	{
61 		// add "mounted by"
62 		for (UserCountMap::Iterator it = fUsers.GetIterator(); it.HasNext();) {
63 			HashString user(it.Next().key);
64 			status_t error = statistics->AddString("mounted by",
65 				user.GetString());
66 			if (error != B_OK)
67 				return error;
68 		}
69 		return B_OK;
70 	}
71 
72 private:
73 	HashString		fShare;
74 	UserCountMap	fUsers;
75 };
76 
77 // ShareStatisticsMap
78 struct StatisticsManager::ShareStatisticsMap
79 	: HashMap<HashString, StatisticsManager::ShareStatistics*> {
80 };
81 
82 
83 // constructor
StatisticsManager()84 StatisticsManager::StatisticsManager()
85 	: fLock("statistics manager"),
86 	  fShareStatistics(NULL)
87 {
88 }
89 
90 // destructor
~StatisticsManager()91 StatisticsManager::~StatisticsManager()
92 {
93 	// delete the share statistics
94 	for (ShareStatisticsMap::Iterator it = fShareStatistics->GetIterator();
95 		 it.HasNext();) {
96 		ShareStatistics* statistics = it.Next().value;
97 		delete statistics;
98 	}
99 
100 	delete fShareStatistics;
101 }
102 
103 // Init
104 status_t
Init()105 StatisticsManager::Init()
106 {
107 	// check lock
108 	if (fLock.Sem() < 0)
109 		return fLock.Sem();
110 
111 	// create share info map
112 	fShareStatistics = new(std::nothrow) ShareStatisticsMap;
113 	if (!fShareStatistics)
114 		return B_NO_MEMORY;
115 	status_t error = fShareStatistics->InitCheck();
116 	if (error != B_OK)
117 		return error;
118 
119 	return B_OK;
120 }
121 
122 // CreateDefault
123 status_t
CreateDefault()124 StatisticsManager::CreateDefault()
125 {
126 	if (fManager)
127 		return B_OK;
128 
129 	fManager = new(std::nothrow) StatisticsManager;
130 	if (!fManager)
131 		return B_NO_MEMORY;
132 	status_t error = fManager->Init();
133 	if (error != B_OK) {
134 		DeleteDefault();
135 		return error;
136 	}
137 
138 	return B_OK;
139 }
140 
141 // DeleteDefault
142 void
DeleteDefault()143 StatisticsManager::DeleteDefault()
144 {
145 	if (fManager) {
146 		delete fManager;
147 		fManager = NULL;
148 	}
149 }
150 
151 // GetDefault
152 StatisticsManager*
GetDefault()153 StatisticsManager::GetDefault()
154 {
155 	return fManager;
156 }
157 
158 // UserRemoved
159 void
UserRemoved(User * user)160 StatisticsManager::UserRemoved(User* user)
161 {
162 	// the shares the user mounted should already have been unmounted
163 }
164 
165 // ShareRemoved
166 void
ShareRemoved(Share * share)167 StatisticsManager::ShareRemoved(Share* share)
168 {
169 	if (!share)
170 		return;
171 
172 	AutoLocker<Locker> locker(fLock);
173 
174 	ShareStatistics* statistics = fShareStatistics->Remove(share->GetName());
175 	delete statistics;
176 }
177 
178 // ShareMounted
179 void
ShareMounted(Share * share,User * user)180 StatisticsManager::ShareMounted(Share* share, User* user)
181 {
182 	if (!share || !user)
183 		return;
184 
185 	AutoLocker<Locker> locker(fLock);
186 
187 	// get the statistics
188 	ShareStatistics* statistics = fShareStatistics->Get(share->GetName());
189 	if (!statistics) {
190 		// no statistics for this share yet: create
191 		statistics = new(std::nothrow) ShareStatistics(share->GetName());
192 		if (!statistics)
193 			return;
194 
195 		// add to the map
196 		if (fShareStatistics->Put(share->GetName(), statistics) != B_OK) {
197 			delete statistics;
198 			return;
199 		}
200 	}
201 
202 	// add the user
203 	statistics->AddUser(user->GetName());
204 }
205 
206 // ShareUnmounted
207 void
ShareUnmounted(Share * share,User * user)208 StatisticsManager::ShareUnmounted(Share* share, User* user)
209 {
210 	if (!share || !user)
211 		return;
212 
213 	AutoLocker<Locker> locker(fLock);
214 
215 	// get the statistics
216 	ShareStatistics* statistics = fShareStatistics->Get(share->GetName());
217 	if (!statistics)
218 		return;
219 
220 	// remove the user
221 	statistics->RemoveUser(user->GetName());
222 }
223 
224 // GetUserStatistics
225 status_t
GetUserStatistics(User * user,BMessage * statistics)226 StatisticsManager::GetUserStatistics(User* user, BMessage* statistics)
227 {
228 	if (!user)
229 		return B_BAD_VALUE;
230 
231 	return GetUserStatistics(user->GetName(), statistics);
232 }
233 
234 // GetUserStatistics
235 status_t
GetUserStatistics(const char * user,BMessage * _statistics)236 StatisticsManager::GetUserStatistics(const char* user, BMessage* _statistics)
237 {
238 	if (!user || !_statistics)
239 		return B_BAD_VALUE;
240 
241 	// nothing for now
242 
243 	return B_OK;
244 }
245 
246 // GetShareStatistics
247 status_t
GetShareStatistics(Share * share,BMessage * statistics)248 StatisticsManager::GetShareStatistics(Share* share, BMessage* statistics)
249 {
250 	if (!share)
251 		return B_BAD_VALUE;
252 
253 	return GetShareStatistics(share->GetName(), statistics);
254 }
255 
256 // GetShareStatistics
257 status_t
GetShareStatistics(const char * share,BMessage * _statistics)258 StatisticsManager::GetShareStatistics(const char* share, BMessage* _statistics)
259 {
260 	if (!share || !_statistics)
261 		return B_BAD_VALUE;
262 
263 	AutoLocker<Locker> locker(fLock);
264 
265 	// get the statistics
266 	ShareStatistics* statistics = fShareStatistics->Get(share);
267 	if (!statistics)
268 		return B_OK;
269 
270 	// get the users
271 	return statistics->GetStatistics(_statistics);
272 }
273 
274 
275 // fManager
276 StatisticsManager*	StatisticsManager::fManager = NULL;
277