source: colin/trunk/src/ResponseCache_Local.cpp @ 5700

Revision 5700, 9.0 KB checked in by jdsiiro, 5 years ago (diff)

Merging the COLIN colin-appresponse-dev branch (r5454 - r5699) back into
COLIN trunk. This brings the colin trunk up-to-date with the current
COLIN 3.0 development API.

NOTE: This *will* break all COLIN solvers (including Coliny & Interfaces).

Line 
1/*  _________________________________________________________________________
2 *
3 *  COLIN: A Common Optimization Library INterface
4 *  Copyright (c) 2003, Sandia National Laboratories.
5 *  This software is distributed under the GNU Lesser General Public License.
6 *  For more information, see the README.html file in the top COLIN directory.
7 *  _________________________________________________________________________
8 */
9
10/**
11 * \file ResponseCache_Local.cpp
12 *
13 * Implements the colin::ResponseCache_Local class.
14 */
15
16#include <colin/ResponseCache_Local.h>
17#include <colin/AppRequest.h>
18#include <colin/ResponseCacheFactory.h>
19
20using std::cerr;
21using std::endl;
22
23using std::set;
24using std::map;
25using std::pair;
26using std::string;
27using std::make_pair;
28
29using utilib::Any;
30using utilib::seed_t;
31
32namespace colin {
33
34namespace StaticInitializers {
35
36namespace {
37
38/// Function to create a new ResponseCache_Local
39ResponseCache* create_local_cache()
40{
41   return new ResponseCache_Local();
42}
43
44bool RegisterLocalCache()
45{
46   CacheFactory().declare_cache_type("Local", create_local_cache);
47   return true;
48}
49
50} // namespace colin::StaticInitializers::(local)
51
52extern const volatile bool local_cache = RegisterLocalCache();
53
54} // namespace colin::StaticInitializers
55
56
57
58//================================================================
59// ResponseCache_Local::Data Member Definitions
60//================================================================
61
62struct ResponseCache_Local::Data {
63   typedef map<string, Any> annotation_map_t;
64
65   struct Record {
66      Record()
67         : data(), annotations()
68      {}
69
70      CachedResponseData  data;
71      annotation_map_t    annotations;
72   };
73
74   typedef map<Key, Record>  cache_map_t;
75
76   typedef map<const OptApplication_Base*,  cache_map_t>  multicache_map_t;
77
78   multicache_map_t caches;
79};
80
81
82
83//================================================================
84// ResponseCache_Local Public Member Definitions
85//================================================================
86
87ResponseCache_Local::ResponseCache_Local()
88   : data(new Data())
89{}
90
91
92ResponseCache_Local::~ResponseCache_Local()
93{
94   delete data;
95}
96
97
98size_t ResponseCache_Local::size( const OptApplication_Base* app ) const
99{
100   Data::multicache_map_t::iterator c_it = data->caches.find(app);
101   if ( c_it == data->caches.end() )
102      return 0;
103   else
104      return c_it->second.size();
105}
106
107
108void ResponseCache_Local::clear( const OptApplication_Base* app )
109{
110   if ( app == NULL )
111      data->caches.clear();
112   else
113   {
114      Data::multicache_map_t::iterator c_it = data->caches.find(app);
115      if ( c_it == data->caches.end() )
116         EXCEPTION_MNGR(std::runtime_error, "ResponseCache_Local::clear(): "
117                        "unknown application");
118      else
119         data->caches.erase(c_it);
120   }
121}
122
123
124size_t
125ResponseCache_Local::erase( const OptApplication_Base* app, Key key )
126{
127   Data::multicache_map_t::iterator c_it = data->caches.find(app);
128   if ( c_it == data->caches.end() )
129      return 0;
130   else
131      return c_it->second.erase(key);
132}
133
134
135
136CachedResponseData
137ResponseCache_Local::find( const OptApplication_Base* app, Key key ) const
138{
139   Data::multicache_map_t::iterator c_it = data->caches.find(app);
140   if ( c_it == data->caches.end() )
141      return CachedResponseData();
142
143   Data::cache_map_t::iterator it = c_it->second.find(key);
144   if ( it == c_it->second.end() )
145      return CachedResponseData();
146   else
147      return it->second.data;
148}
149
150
151void
152ResponseCache_Local::
153insert_info( const OptApplication_Base* app,
154             const Key key,
155             const utilib::seed_t seed,
156             const utilib::Any domain,
157             const std::map<response_info_t, const utilib::Any> &info )
158{
159   if ( app == NULL )
160      EXCEPTION_MNGR(std::runtime_error, "ResponseCache_Local::insert_info(): "
161                     "cannot insert into a cache with a NULL application");
162   if ( key.empty() )
163      EXCEPTION_MNGR(std::runtime_error, "ResponseCache_Local::insert_info(): "
164                     "cannot insert into a cache with an empty key");
165
166   Data::Record &cache_record = data->caches[app][key];
167   if ( cache_record.data.empty() )
168      cache_record.data = CachedResponseData(domain);
169   insert_impl(cache_record.data, seed, info);
170}
171
172
173size_t
174ResponseCache_Local::getResponses( AppRequest& request,
175                                   std::list<AppResponse> &ans,
176                                   size_t maxReturnCount ) const
177{
178   ans.clear();
179
180   // At this point, no more changes to the request will be honored
181   AppRequest tmp_r = request.replicate(request.seed());
182   request.finalize_request();
183   CoreRequestInfo cqi = get_core_request(request);
184
185   Data::multicache_map_t::iterator c_it = data->caches.find(cqi.app);
186   if ( c_it == data->caches.end() )
187      return 0;  // throw an exception???
188
189
190   Data::cache_map_t::iterator it;
191   Data::cache_map_t::iterator itEnd;
192   if ( cqi.domain.empty() )
193   {
194      // Check all stored domain points
195      it = c_it->second.begin();
196      itEnd = c_it->second.end();
197   }
198   else
199   {
200      // look for a specific domain point
201      itEnd = it = c_it->second.find(generate_key(cqi.domain));
202      if ( it == c_it->second.end() )
203         return 0;
204      ++itEnd;
205   }
206
207   size_t count = 0;
208   for( ; it != itEnd; ++it )
209   {
210      // Needed for all responses after the first (and silently ignored
211      // by the first)
212      request.finalize_request();
213
214      set<seed_t> seeds;
215      if ( ! it->second.data.get_seeds(cqi.requests, seeds) )
216         continue;
217     
218      CoreResponseInfo cri;
219      if (( cqi.seed != 0 ) || ( it->second.data.has_seed(0) ))
220      {
221         if ( seeds.count(cqi.seed) == 0 )
222            continue;
223         cri.seed = cqi.seed;
224      }
225      else
226         cri.seed = *seeds.begin();
227      it->second.data.get(cri.seed, cri.responses);
228      cri.domain = it->second.data.domain();
229
230      ans.push_back(form_response(request, cri));
231      ++count;
232
233      if ( count == maxReturnCount )
234         break;
235
236      request = tmp_r;
237      tmp_r = request.replicate(request.seed());
238   }
239   return count;
240}
241
242
243std::map<ResponseCache::Key, CachedResponseData>
244ResponseCache_Local::getRawData( const OptApplication_Base *app,
245                                 FilterFunctor& filter ) const
246{
247   map<Key, CachedResponseData> ans;
248
249   Data::multicache_map_t::iterator c_it = data->caches.find(app);
250   if ( c_it == data->caches.end() )
251      return ans;
252
253   Data::cache_map_t::iterator it = c_it->second.begin();
254   Data::cache_map_t::iterator itEnd = c_it->second.end();
255   for( ; it != itEnd; ++it )
256   {
257      if ( filter(it->first, it->second.data) )
258         ans.insert(ans.end(), *it);
259   }
260   return ans;
261}
262
263
264
265void
266ResponseCache_Local::annotate( const OptApplication_Base* app,
267                               Key key,
268                               std::string attribute,
269                               utilib::Any value )
270{
271   Data::multicache_map_t::iterator c_it = data->caches.find(app);
272   if ( c_it == data->caches.end() )
273      EXCEPTION_MNGR(std::runtime_error, "ResponseCache_Local::annotate(): "
274                     "unknown application");
275
276   Data::cache_map_t::iterator it = c_it->second.find(key);
277   if ( it == c_it->second.end() )
278      EXCEPTION_MNGR(std::runtime_error, "ResponseCache_Local::annotate(): "
279                     "key not present in cache");
280   
281   if ( ! it->second.annotations.insert( make_pair(attribute, value) ).second )
282      EXCEPTION_MNGR(std::runtime_error, "ResponseCache_Local::annotate(): "
283                     "duplicate annotation (" << attribute << ", "
284                     << value << ")");
285}
286
287
288utilib::Any
289ResponseCache_Local::get_annotation( const OptApplication_Base* app,
290                                     Key key,
291                                     std::string attribute ) const
292{
293   Data::multicache_map_t::iterator c_it = data->caches.find(app);
294   if ( c_it == data->caches.end() )
295      EXCEPTION_MNGR(std::runtime_error, "ResponseCache_Local::"
296                     "get_annotation(): unknown application");
297
298   Data::cache_map_t::iterator it = c_it->second.find(key);
299   if ( it == c_it->second.end() )
300      EXCEPTION_MNGR(std::runtime_error, "ResponseCache_Local::"
301                     "get_annotation(): key not present in cache");
302   
303   Data::annotation_map_t::iterator a_it
304      = it->second.annotations.find(attribute);
305   if ( a_it == it->second.annotations.end() )
306      return Any();
307   else
308      return a_it->second;
309}
310
311
312std::map<std::string, utilib::Any>
313ResponseCache_Local::
314get_annotations( const OptApplication_Base* app, Key key ) const
315{
316   Data::multicache_map_t::iterator c_it = data->caches.find(app);
317   if ( c_it == data->caches.end() )
318      EXCEPTION_MNGR(std::runtime_error, "ResponseCache_Local::"
319                     "get_annotations(): unknown application");
320
321   Data::cache_map_t::iterator it = c_it->second.find(key);
322   if ( it == c_it->second.end() )
323      EXCEPTION_MNGR(std::runtime_error, "ResponseCache_Local::"
324                     "get_annotations(): key not present in cache");
325   
326   return it->second.annotations;
327}
328
329
330
331} // namespace colin
Note: See TracBrowser for help on using the repository browser.