WorkingMemorySnapshot.cpp
Go to the documentation of this file.
1/*
2* This file is part of ArmarX.
3*
4* ArmarX is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License version 2 as
6* published by the Free Software Foundation.
7*
8* ArmarX is distributed in the hope that it will be useful, but
9* WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program. If not, see <http://www.gnu.org/licenses/>.
15*
16* @package MemoryX::LongtermMemory
17* @author Alexey Kozlov ( kozlov at kit dot edu)
18* @date 2012
19* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20* GNU General Public License
21*/
22
24
25#include <Ice/ObjectAdapter.h>
26#include <IceUtil/UUID.h>
27
31
33#include <MemoryX/interface/workingmemory/WorkingMemoryListenerInterface.h>
34
35namespace memoryx
36{
39 const DatabaseInterfacePrx& databasePrx) :
40 name(name), ic(ic), databasePrx(databasePrx)
41 {
42 iceId.name = IceUtil::generateUUID();
43 }
44
45 PersistentEntitySegmentBasePrx
46 WorkingMemorySnapshot::addSegment(const std::string& segName, const ::Ice::Current& c)
47 {
48 addSegmentToMap(segName);
49 return getSegment(segName, c);
50 }
51
53 WorkingMemorySnapshot::addSegmentPtr(const std::string& segName)
54 {
55 addSegmentToMap(segName);
56 return getSegmentPtr(segName);
57 }
58
59 void
60 WorkingMemorySnapshot::addSegmentToMap(const std::string& segName)
61 {
62 segmentNames[segName] = getSegmentCollectionName(segName);
63 }
64
65 PersistentEntitySegmentBasePrx
66 WorkingMemorySnapshot::getSegment(const ::std::string& segName, const ::Ice::Current& c)
67 {
68 PersistentEntitySegmentPtr segment = getSegmentPtr(segName);
69
70 if (segment)
71 {
72 Ice::Identity segId = segment->getIceId();
73 segId.name += "_" + IceUtil::generateUUID();
74
75 openedSegments[segId] = segment;
77 Ice::ObjectPrx node = c.adapter->add(segment, segId);
78 return PersistentEntitySegmentBasePrx::uncheckedCast(node);
79 }
80 else
81 {
82 return PersistentEntitySegmentBasePrx();
83 }
84 }
85
87 WorkingMemorySnapshot::getSegmentPtr(const ::std::string& segName)
88 {
89 SegmentMap::const_iterator itSeg = segmentNames.find(segName);
90
91 if (itSeg != segmentNames.end())
92 {
93 ARMARX_CHECK_EXPRESSION(databasePrx);
94 CollectionInterfacePrx segmentColl = databasePrx->requestCollection(itSeg->second);
95
96 if (segmentColl)
97 {
98 PersistentEntitySegmentBasePtr segment =
99 new PersistentEntitySegment(segmentColl, ic, false);
100 segment->setSegmentName(segName);
101 return PersistentEntitySegmentPtr::dynamicCast(segment);
102 }
103 else
104 {
106 }
107 }
108 else
109 {
111 }
112 }
113
114 bool
115 WorkingMemorySnapshot::hasSegment(const ::std::string& segName, const ::Ice::Current&)
116 {
117 return segmentNames.count(segName);
118 }
119
120 NameList
122 {
123 NameList result;
124
125 for (SegmentMap::const_iterator it = segmentNames.begin(); it != segmentNames.end(); ++it)
126 {
127 result.push_back(it->first);
128 }
129
130 return result;
131 }
132
133 void
134 WorkingMemorySnapshot::clear(const ::Ice::Current&)
135 {
136 for (SegmentMap::const_iterator it = segmentNames.begin(); it != segmentNames.end(); ++it)
137 {
138 databasePrx->dropCollection(it->second);
139 }
140
141 segmentNames.clear();
142 }
143
146 {
147 return segmentNames;
148 }
149
150 void
151 WorkingMemorySnapshot::saveWorkingMemory(const AbstractWorkingMemoryInterfacePrx& workingMemory,
152 const ::Ice::Current&)
153 {
154 NameList wmSegNames = workingMemory->getSegmentNames();
155
156 for (NameList::const_iterator itSeg = wmSegNames.begin(); itSeg != wmSegNames.end();
157 ++itSeg)
158 {
159 WorkingMemoryEntitySegmentBasePrx wmSegment =
160 WorkingMemoryEntitySegmentBasePrx::uncheckedCast(workingMemory->getSegment(*itSeg));
161
162 if (wmSegment)
163 {
164 PersistentEntitySegmentBasePtr snapSegment = addSegmentPtr(*itSeg);
165 EntityIdList ids = wmSegment->getAllEntityIds();
166
167 for (EntityIdList::const_iterator itEntity = ids.begin(); itEntity != ids.end();
168 ++itEntity)
169 {
170 snapSegment->addEntity(wmSegment->getEntityById(*itEntity));
171 }
172 }
173 }
174 }
175
176 void
178 const AbstractWorkingMemoryInterfacePrx& workingMemory,
179 const Ice::StringSeq& entityIdList,
180 const Ice::Current&)
181 {
182 NameList wmSegNames = workingMemory->getSegmentNames();
183 auto sortedEntities = entityIdList;
184 std::sort(sortedEntities.begin(), sortedEntities.end());
185 auto newEnd = std::unique(sortedEntities.begin(), sortedEntities.end());
186 sortedEntities.erase(newEnd, sortedEntities.end());
187
188 for (const auto& segName : wmSegNames)
189 {
190 WorkingMemoryEntitySegmentBasePrx wmSegment =
191 WorkingMemoryEntitySegmentBasePrx::uncheckedCast(
192 workingMemory->getSegment(segName));
193
194 if (wmSegment)
195 {
196 PersistentEntitySegmentBasePtr snapSegment = addSegmentPtr(segName);
197 EntityIdList ids = wmSegment->getAllEntityIds();
198 std::sort(ids.begin(), ids.end());
199 Ice::StringSeq intersectionList(ids.size());
200 auto intersectionEnd = std::set_intersection(ids.begin(),
201 ids.end(),
202 sortedEntities.begin(),
203 sortedEntities.end(),
204 intersectionList.begin());
205 intersectionList.resize(intersectionEnd - intersectionList.begin());
206 auto newEnd = std::unique(intersectionList.begin(), intersectionList.end());
207 intersectionList.erase(newEnd, intersectionList.end());
208
209 for (EntityIdList::const_iterator itEntity = intersectionList.begin();
210 itEntity != intersectionList.end();
211 ++itEntity)
212 {
213 snapSegment->addEntity(wmSegment->getEntityById(*itEntity));
214 }
215 }
216 }
217 }
218
219 void
221 const AbstractWorkingMemoryInterfacePrx& workingMemory,
222 const ::Ice::Current&)
223 {
224 std::set<WorkingMemoryListenerInterfacePrx> listeners;
225 for (SegmentMap::const_iterator itSeg = segmentNames.begin(); itSeg != segmentNames.end();
226 ++itSeg)
227 {
228 PersistentEntitySegmentBasePtr snapSegment = getSegmentPtr(itSeg->first);
229 WorkingMemoryEntitySegmentBasePrx wmSegment =
230 WorkingMemoryEntitySegmentBasePrx::uncheckedCast(
231 workingMemory->getSegment(itSeg->first));
232
233 if (wmSegment)
234 {
235 // wmSegment->clear();
236 EntityIdList ids = snapSegment->getAllEntityIds();
237
238 for (EntityIdList::const_iterator itEntity = ids.begin(); itEntity != ids.end();
239 ++itEntity)
240 {
241 // std::cout << "Restoring entity, id = " << *itEntity << std::endl;
242 wmSegment->addEntity(snapSegment->getEntityById(*itEntity));
243 }
244
245 ARMARX_INFO << "Loaded " << wmSegment->size() << " elements into segment "
246 << itSeg->first;
247
248 WorkingMemoryListenerInterfacePrx l = wmSegment->getListenerProxy();
249 if (l)
250 {
251 listeners.insert(l);
252 l->reportSnapshotLoaded(itSeg->first);
253 }
254 }
255 else
257 << "Unable to load segment " << itSeg->first
258 << " from snapshot: Corresponding WM segment not exists or has invalid type";
259 }
260 for (auto& l : listeners)
261 {
262 l->reportSnapshotCompletelyLoaded();
263 }
264 }
265
266 Ice::Identity
268 {
269 return iceId;
270 }
271
272 std::string
273 WorkingMemorySnapshot::getSegmentCollectionName(const std::string& segName)
274 {
275 return name + "_" + segName;
276 }
277
278 // serialization
279 void
280 WorkingMemorySnapshot::serialize(const armarx::ObjectSerializerBasePtr& serializer,
281 const ::Ice::Current& c) const
282 {
284 armarx::AbstractObjectSerializerPtr::dynamicCast(serializer);
285
286 obj->setString("name", name);
287
288 armarx::AbstractObjectSerializerPtr objSegments = obj->createElement();
289
290 for (SegmentMap::const_iterator it = segmentNames.begin(); it != segmentNames.end(); ++it)
291 {
292 objSegments->setString(it->first, it->second);
293 }
294
295 obj->setElement("segments", objSegments);
296 }
297
298 void
299 WorkingMemorySnapshot::deserialize(const armarx::ObjectSerializerBasePtr& serializer,
300 const ::Ice::Current& c)
301 {
303 armarx::AbstractObjectSerializerPtr::dynamicCast(serializer);
304
305 name = obj->getString("name");
306
307 const armarx::AbstractObjectSerializerPtr objSegments = obj->getElement("segments");
308 const std::vector<std::string> segNames = objSegments->getElementNames();
309 segmentNames.clear();
310
311 for (std::vector<std::string>::const_iterator it = segNames.begin(); it != segNames.end();
312 ++it)
313 {
314 segmentNames[*it] = objSegments->getString(*it);
315 }
316 }
317} // namespace memoryx
constexpr T c
The PersistentEntitySegment class is the base class for all memory segments containing memoryx::Entit...
NameList getSegmentNames(const ::Ice::Current &=Ice::emptyCurrent) override
void clear(const ::Ice::Current &=Ice::emptyCurrent) override
PersistentEntitySegmentBasePrx getSegment(const ::std::string &segName, const ::Ice::Current &=Ice::emptyCurrent) override
void deserialize(const armarx::ObjectSerializerBasePtr &serializer, const ::Ice::Current &=Ice::emptyCurrent) override
void saveWorkingMemory(const AbstractWorkingMemoryInterfacePrx &workingMemory, const ::Ice::Current &=Ice::emptyCurrent) override
Save all segments with all entities of the WorkingMemory to this snapshot.
WorkingMemorySnapshot(const std::string &name, Ice::CommunicatorPtr ic, const DatabaseInterfacePrx &databasePrx)
void saveWorkingMemorySubset(const AbstractWorkingMemoryInterfacePrx &workingMemory, const Ice::StringSeq &entityIdList, const ::Ice::Current &=Ice::emptyCurrent) override
void serialize(const armarx::ObjectSerializerBasePtr &serializer, const ::Ice::Current &=Ice::emptyCurrent) const override
PersistentEntitySegmentBasePrx addSegment(const ::std::string &segName, const ::Ice::Current &=Ice::emptyCurrent) override
bool hasSegment(const ::std::string &segName, const ::Ice::Current &=Ice::emptyCurrent) override
void restoreWorkingMemory(const AbstractWorkingMemoryInterfacePrx &workingMemory, const ::Ice::Current &=Ice::emptyCurrent) override
Restore all segments with all entities of this snapshot to the WorkingMemory.
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
::IceInternal::Handle<::Ice::Communicator > CommunicatorPtr
Definition IceManager.h:49
IceInternal::Handle< AbstractObjectSerializer > AbstractObjectSerializerPtr
VirtualRobot headers.
IceUtil::Handle< PersistentEntitySegment > PersistentEntitySegmentPtr
std::map< std::string, std::string > SegmentMap