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