1 #ifndef STOCK_DATABASE_TPP
2 #define STOCK_DATABASE_TPP
4 #include "Stock_Database.h"
7 #include <ace/OS_NS_unistd.h>
12 template <typename CALLBACK>
15 Map_Init (typename Stock_Database<CALLBACK>::Stock_Map &map)
20 void operator () (const typename Stock_Database<CALLBACK>::Init_Map::value_type &item)
22 typename Stock_Database<CALLBACK>::StockInfo stock_info (item.first.c_str ());
24 // If the initial value is nonzero, use that - otherwise, use a number
28 stock_info.high_ = item.second ? item.second : ACE_OS::rand () % 100;
30 map_[item.first] = stock_info;
33 typename Stock_Database<CALLBACK>::Stock_Map &map_;
37 template <typename CALLBACK>
38 Stock_Database<CALLBACK>::Stock_Database (u_int rate)
47 std::for_each (map.begin (),
49 Map_Init<CALLBACK> (this->stock_map_));
52 template <typename CALLBACK>
53 Stock_Database<CALLBACK>::Stock_Database (const char *file, u_int rate)
58 this->handle_signal (0, 0, 0);
61 template <typename CALLBACK>
62 Stock_Database<CALLBACK>::Stock_Database (const Init_Map &stockmap,
67 std::for_each (stockmap.begin (),
69 Map_Init<CALLBACK> (this->stock_map_));
73 template <typename CALLBACK>
74 typename Stock_Database<CALLBACK>::StockInfo
75 Stock_Database<CALLBACK>::get_stock_info(const char *name)
77 ACE_READ_GUARD_RETURN (ACE_RW_Thread_Mutex,
82 // Locate the <stock_name> in the database.
84 "*** message: searching the stock_map_ for the stock_name\n"));
86 typename Stock_Map::iterator iter = this->stock_map_.find (std::string (name));
88 if (iter == this->stock_map_.end ())
89 throw Invalid_Stock ();
91 ACE_DEBUG ((LM_DEBUG, "*** message: returning stock_info to the client\n"));
96 template <typename CALLBACK>
97 typename Stock_Database<CALLBACK>::Cookie
98 Stock_Database<CALLBACK>::register_callback (CALLBACK &obj)
100 ACE_Utils::UUID uuid;
101 ACE_Utils::UUID_GENERATOR::instance ()->generate_UUID (uuid);
103 this->callbacks_[uuid.to_string ()->c_str ()] = &obj;
105 return uuid.to_string ()->c_str ();
108 template <typename CALLBACK>
110 Stock_Database<CALLBACK>::update_rate (u_int rate)
115 template <typename CALLBACK>
117 Stock_Database<CALLBACK>::start (void)
120 { // Double checked locking
121 ACE_WRITE_GUARD (ACE_RW_Thread_Mutex,
126 this->active_ = true;
127 this->activate (THR_NEW_LWP | THR_JOINABLE, 1);
132 template <typename CALLBACK>
134 Stock_Database<CALLBACK>::stop (void)
136 ACE_WRITE_GUARD (ACE_RW_Thread_Mutex,
140 this->active_ = false;
143 template <typename CALLBACK>
145 Stock_Database<CALLBACK>::handle_signal (int,
149 ACE_WRITE_GUARD_RETURN (ACE_RW_Thread_Mutex,
154 std::ifstream input (this->filename_.c_str ());
159 typename Stock_Database<CALLBACK>::Init_Map map;
161 while (input.good ())
170 std::for_each (map.begin (),
172 Map_Init<CALLBACK> (this->stock_map_));
178 template <typename CALLBACK>
181 void operator () (typename Stock_Database<CALLBACK>::Stock_Map::value_type &item)
183 // Determine if the stock has changed.
184 if (ACE_OS::rand () % 2)
185 return; // Nope! On to the next!
187 changed_.push_back (item.first);
189 // Determine the amount of change of the stock. We will
190 // only permit a 5 point change at a time in either direction
191 int delta = ACE_OS::rand () % 10 - 5;
193 // We don't want negative stock values!
194 if (item.second.last_ <= delta)
197 // Calculate the new values for the stock.
198 item.second.last_ += delta;
200 if (item.second.last_ < item.second.low_)
201 item.second.low_ = item.second.last_;
202 else if (item.second.last_ > item.second.high_)
203 item.second.high_ = item.second.last_;
206 void operator () (typename Stock_Database<CALLBACK>::Callback_Map::value_type &item)
208 (*item.second) (changed_);
212 std::vector <std::string> changed_;
215 template <typename CALLBACK>
217 Stock_Database<CALLBACK>::svc (void)
219 ACE_DEBUG ((LM_DEBUG, "tock!\n"));
221 while (this->active_)
225 Stock_Updater<CALLBACK> updater;
227 { // Control the scope of our mutex to avoid deadlock.
228 ACE_WRITE_GUARD_RETURN (ACE_RW_Thread_Mutex,
233 updater = std::for_each (this->stock_map_.begin (),
234 this->stock_map_.end (),
238 // Update stock prices
240 std::for_each (this->callbacks_.begin (),
241 this->callbacks_.end (),
245 // Sleep for one second.
246 ACE_OS::sleep (this->rate_);
252 #endif /* STOCK_DATABASE_TPP */