1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
|
// **********************************************************************
//
// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
//
// This copy of Ice is licensed to you under the terms described in the
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************
#ifndef FREEZE_EVICTOR_I_H
#define FREEZE_EVICTOR_I_H
#include <IceUtil/IceUtil.h>
#include <Ice/Ice.h>
#include <Freeze/Freeze.h>
#include <Freeze/ObjectStore.h>
#include <Freeze/EvictorIteratorI.h>
#include <Freeze/SharedDbEnv.h>
#include <Freeze/Index.h>
#include <Freeze/DB.h>
#include <list>
#include <vector>
#include <deque>
class DbTxn;
namespace Freeze
{
class EvictorIBase;
//
// Helper class to prevent deactivation while the Evictor is in use
//
class DeactivateController : private IceUtil::Monitor<IceUtil::Mutex>
{
public:
//
// Prevents deactivation; the constructor raises
// EvictorDeactivatedException if _deactivated or _deactivating is true.
//
class Guard
{
public:
Guard(const DeactivateController&);
~Guard();
private:
DeactivateController& _controller;
};
DeactivateController(EvictorIBase*);
//
// Used mostly in asserts
//
bool deactivated() const;
//
// Returns true if this thread is supposed to do the deactivation and
// call deactivationComplete() once done.
//
bool deactivate();
void deactivationComplete();
private:
friend class Guard;
EvictorIBase* _evictor;
bool _deactivating;
bool _deactivated;
int _guardCount;
};
class EvictorIBase : public virtual Evictor, public IceUtil::Monitor<IceUtil::Mutex>
{
public:
virtual TransactionIPtr beforeQuery() = 0;
virtual void setSize(Ice::Int);
virtual Ice::Int getSize();
virtual Ice::ObjectPrx add(const Ice::ObjectPtr&, const Ice::Identity&);
virtual Ice::ObjectPtr remove(const Ice::Identity&);
virtual bool hasObject(const Ice::Identity&);
virtual Ice::ObjectPtr locate(const Ice::Current&, Ice::LocalObjectPtr&);
DeactivateController& deactivateController();
const Ice::CommunicatorPtr& communicator() const;
const Ice::EncodingVersion& encoding() const;
const SharedDbEnvPtr& dbEnv() const;
const std::string& filename() const;
bool deadlockWarning() const;
Ice::Int trace() const;
Ice::Int txTrace() const;
void initialize(const Ice::Identity&, const std::string&, const Ice::ObjectPtr&);
static void updateStats(Statistics&, IceUtil::Int64);
static std::string defaultDb;
static std::string indexPrefix;
protected:
EvictorIBase(const Ice::ObjectAdapterPtr&, const std::string&, DbEnv*, const std::string&,
const FacetTypeMap&, const ServantInitializerPtr&, bool);
virtual bool hasAnotherFacet(const Ice::Identity&, const std::string&) = 0;
virtual Ice::ObjectPtr locateImpl(const Ice::Current&, Ice::LocalObjectPtr&) = 0;
virtual void evict() = 0;
std::vector<std::string> allDbs() const;
size_t _evictorSize;
FacetTypeMap _facetTypes;
DeactivateController _deactivateController;
Ice::ObjectAdapterPtr _adapter;
Ice::CommunicatorPtr _communicator;
Ice::EncodingVersion _encoding;
ServantInitializerPtr _initializer;
SharedDbEnvPtr _dbEnv;
std::string _filename;
bool _createDb;
Ice::Int _trace;
Ice::Int _txTrace;
bool _deadlockWarning;
private:
Ice::ObjectPtr _pingObject;
};
typedef IceUtil::Handle<EvictorIBase> EvictorIBasePtr;
template<class T>
class EvictorI : public EvictorIBase
{
public:
virtual EvictorIteratorPtr
getIterator(const std::string& facet, Ice::Int batchSize)
{
DeactivateController::Guard deactivateGuard(_deactivateController);
TransactionIPtr tx = beforeQuery();
return new EvictorIteratorI(findStore(facet, false), tx, batchSize);
}
protected:
EvictorI(const Ice::ObjectAdapterPtr& adapter, const std::string& envName, DbEnv* dbEnv,
const std::string& filename, const FacetTypeMap& facetTypes,
const ServantInitializerPtr& initializer, const std::vector<IndexPtr>& indices, bool createDb) :
EvictorIBase(adapter, envName, dbEnv, filename, facetTypes, initializer, createDb)
{
std::string propertyPrefix = std::string("Freeze.Evictor.") + envName + '.' + filename;
bool populateEmptyIndices =
(_communicator->getProperties()->
getPropertyAsIntWithDefault(propertyPrefix + ".PopulateEmptyIndices", 0) != 0);
//
// Instantiate all Dbs in 2 steps:
// (1) iterate over the indices and create ObjectStore with indices
// (2) open ObjectStores without indices
//
std::vector<std::string> dbs = allDbs();
//
// Add default db in case it's not there
//
dbs.push_back(defaultDb);
for(std::vector<IndexPtr>::const_iterator i = indices.begin(); i != indices.end(); ++i)
{
std::string facet = (*i)->facet();
typename StoreMap::iterator q = _storeMap.find(facet);
if(q == _storeMap.end())
{
//
// New db
//
std::vector<IndexPtr> storeIndices;
for(std::vector<IndexPtr>::const_iterator r = i; r != indices.end(); ++r)
{
if((*r)->facet() == facet)
{
storeIndices.push_back(*r);
}
}
std::string facetType;
FacetTypeMap::const_iterator ft = facetTypes.find(facet);
if(ft != facetTypes.end())
{
facetType = ft->second;
}
ObjectStore<T>* store = new ObjectStore<T>(facet, facetType,_createDb, this, storeIndices, populateEmptyIndices);
_storeMap.insert(typename StoreMap::value_type(facet, store));
}
}
for(std::vector<std::string>::iterator p = dbs.begin(); p != dbs.end(); ++p)
{
std::string facet = *p;
if(facet == defaultDb)
{
facet = "";
}
#if (defined(_MSC_VER) && (_MSC_VER >= 1600))
std::pair<typename StoreMap::iterator, bool> ir =
_storeMap.insert(typename StoreMap::value_type(facet, static_cast<ObjectStore<T>*>(nullptr)));
#else
std::pair<typename StoreMap::iterator, bool> ir =
_storeMap.insert(typename StoreMap::value_type(facet, 0));
#endif
if(ir.second)
{
std::string facetType;
FacetTypeMap::const_iterator ft = facetTypes.find(facet);
if(ft != facetTypes.end())
{
facetType = ft->second;
}
ir.first->second = new ObjectStore<T>(facet, facetType, _createDb, this);
}
}
}
ObjectStore<T>*
findStore(const std::string& facet, bool createIt)
{
Lock sync(*this);
ObjectStore<T>* os = 0;
typename StoreMap::const_iterator p = _storeMap.find(facet);
if(p != _storeMap.end())
{
os = (*p).second;
}
else if(createIt)
{
std::string facetType;
typename FacetTypeMap::const_iterator q = _facetTypes.find(facet);
if(q != _facetTypes.end())
{
facetType = q->second;
}
os = new ObjectStore<T>(facet, facetType, true, this);
_storeMap.insert(typename StoreMap::value_type(facet, os));
}
return os;
}
void
closeDbEnv()
{
for(typename StoreMap::iterator p = _storeMap.begin(); p != _storeMap.end(); ++p)
{
delete (*p).second;
}
_dbEnv = 0;
_initializer = 0;
}
typedef std::map<std::string, ObjectStore<T>*> StoreMap;
StoreMap _storeMap;
};
inline DeactivateController&
EvictorIBase::deactivateController()
{
return _deactivateController;
}
inline const Ice::CommunicatorPtr&
EvictorIBase::communicator() const
{
return _communicator;
}
inline const Ice::EncodingVersion&
EvictorIBase::encoding() const
{
return _encoding;
}
inline const SharedDbEnvPtr&
EvictorIBase::dbEnv() const
{
return _dbEnv;
}
inline bool
EvictorIBase::deadlockWarning() const
{
return _deadlockWarning;
}
inline Ice::Int
EvictorIBase::trace() const
{
return _trace;
}
//
// Helper function
//
inline void
checkIdentity(const Ice::Identity& ident)
{
if(ident.name.size() == 0)
{
throw Ice::IllegalIdentityException(__FILE__, __LINE__, ident);
}
}
inline void
checkServant(const Ice::ObjectPtr& servant)
{
if(servant == 0)
{
throw Ice::IllegalServantException(__FILE__, __LINE__, "cannot add null servant to Freeze Evictor");
}
}
}
#endif
|