CARMA C++
FunctorWorkRequest.h
1 #ifndef CARMA_CONTROL_FUNCTOR_WORK_REQUEST_H
2 #define CARMA_CONTROL_FUNCTOR_WORK_REQUEST_H
3 
4 
5 #include <string>
6 #include <map>
7 #include <stdexcept>
8 #include <set>
9 
11 #include "carma/util/WorkRequest.h"
12 
13 
14 namespace carma {
15 namespace control {
16 
17 template < typename F >
18 void
19 queueFunctorWorkRequestGroup(
20  const ::std::string & requestIdCallString,
21  const ::std::map< ::std::string, F > & keyToFunctorMap,
22  util::WorkResultSet & wrs,
23  WorkerPool & workerPool );
24 
25 
26 template < typename F >
27 void
28 queueFunctorWorkRequestGroup(
29  const ::std::string & requestIdCallString,
30  const ::std::map< ::std::string, F > & keyToFunctorMap,
31  util::WorkResultSet & wrs,
32  WorkerPool & workerPool,
33  const bool loggingOverride );
34 
35 
36 template < typename F >
37 class FunctorWorkRequestImpl : public util::WorkRequest::Impl {
38  public:
39  static util::WorkRequest make( const ::std::string & requestId,
40  const util::WorkResult & wr,
41  const F & functor );
42 
43  private:
44  FunctorWorkRequestImpl( const ::std::string & requestId,
45  const util::WorkResult & wr,
46  const F & functor );
47 
48  virtual void serviceImpl( );
49 
50  F functor_;
51 };
52 
53 
54 template < typename F >
55 FunctorWorkRequestImpl< F >::FunctorWorkRequestImpl(
56  const ::std::string & requestId,
57  const util::WorkResult & wr,
58  const F & functor ) :
59 util::WorkRequest::Impl( requestId, wr ),
60 functor_( functor )
61 {
62 }
63 
64 
65 template < typename F >
66 util::WorkRequest
67 FunctorWorkRequestImpl< F >::make( const ::std::string & requestId,
68  const util::WorkResult & wr,
69  const F & functor )
70 {
71  return util::WorkRequest( new FunctorWorkRequestImpl( requestId,
72  wr,
73  functor ) );
74 }
75 
76 
77 template < typename F >
78 void
79 FunctorWorkRequestImpl< F >::serviceImpl( )
80 {
81  functor_( );
82 }
83 
84 
85 template < typename F >
86 void
87 queueFunctorWorkRequestGroupImpl(
88  const ::std::string & requestIdCallString,
89  const ::std::map< ::std::string, F > & keyToFunctorMap,
90  util::WorkResultSet & wrs,
91  WorkerPool & workerPool,
92  const bool * const pLoggingOverride )
93 {
94  ::std::set< ::std::string > keysToRemove;
95 
96  try {
97  typedef typename ::std::map< ::std::string, F >::const_iterator
98  KeyToFunctorMapIter;
99 
100  typedef ::std::map< ::std::string, util::WorkResult > KeyToWrMap;
101 
102  const KeyToFunctorMapIter keyToFunctorMapEnd = keyToFunctorMap.end( );
103 
104  KeyToWrMap keyToWrMap;
105  {
106  ::std::set< ::std::string > keys;
107 
108  KeyToFunctorMapIter i = keyToFunctorMap.begin( );
109 
110  for ( ; i != keyToFunctorMapEnd; ++i )
111  keys.insert( i->first );
112 
113  // add the keys to the wrs to get work results
114  keyToWrMap = wrs.addKeys( keys );
115 
116  keysToRemove.swap( keys );
117  }
118 
119  ::std::set< util::WorkRequest > requestGroup;
120  {
121  KeyToWrMap::const_iterator i = keyToWrMap.begin( );
122  const KeyToWrMap::const_iterator iEnd = keyToWrMap.end( );
123 
124  while ( i != iEnd ) {
125  const ::std::string key = i->first;
126  const util::WorkResult wr = i->second;
127 
128  const KeyToFunctorMapIter j = keyToFunctorMap.find( key );
129 
130  if ( j == keyToFunctorMapEnd )
131  throw ::std::logic_error( "Two maps don't agree" );
132 
133  ::std::string requestId = key;
134 
135  if ( requestIdCallString.empty( ) == false ) {
136  if ( requestIdCallString[ 0 ] != ' ' )
137  requestId.append( 1, ' ' );
138 
139  requestId.append( requestIdCallString );
140  }
141 
142  requestId.append( " request" );
143 
144  const util::WorkRequest request =
145  FunctorWorkRequestImpl< F >::make( requestId,
146  wr,
147  j->second );
148 
149  if ( requestGroup.insert( request ).second == false )
150  throw ::std::logic_error( "request is not unique" );
151 
152  ++i;
153  }
154  }
155 
156  ::std::set< ::std::string > temp;
157 
158  if ( pLoggingOverride != 0 )
159  workerPool.queueRequestGroup( requestGroup, *pLoggingOverride );
160  else
161  workerPool.queueRequestGroup( requestGroup );
162 
163  keysToRemove.swap( temp ); // This will not throw
164  } catch ( ... ) {
165  wrs.removeKeys( keysToRemove );
166 
167  throw;
168  }
169 }
170 
171 
172 template < typename F >
173 void
174 queueFunctorWorkRequestGroup(
175  const ::std::string & requestIdCallString,
176  const ::std::map< ::std::string, F > & keyToFunctorMap,
177  util::WorkResultSet & wrs,
178  WorkerPool & workerPool )
179 {
180  queueFunctorWorkRequestGroupImpl( requestIdCallString,
181  keyToFunctorMap,
182  wrs,
183  workerPool,
184  0 );
185 }
186 
187 
188 template < typename F >
189 void
190 queueFunctorWorkRequestGroup(
191  const ::std::string & requestIdCallString,
192  const ::std::map< ::std::string, F > & keyToFunctorMap,
193  util::WorkResultSet & wrs,
194  WorkerPool & workerPool,
195  const bool loggingOverride )
196 {
197  queueFunctorWorkRequestGroupImpl( requestIdCallString,
198  keyToFunctorMap,
199  wrs,
200  workerPool,
201  &loggingOverride );
202 }
203 
204 
205 } // namespace carma::control
206 } // namespace carma
207 
208 
209 #endif
Interface file for the carma::control::WorkerPool class.
Interface file for the carma::util::WorkRequest class.
::std::set< K > keys(const ::std::map< K, V > &in)
Return the keys of a map as a set.