1#include <map>
2#include <string>
3#include <vector>
4
5#include <boost/shared_ptr.hpp>
6
7#include "../Mutex.h"
8
9using std::string;
10
11class CustomerData : boost::noncopyable
12{
13 public:
14  CustomerData()
15    : data_(new Map)
16  { }
17
18  int query(const string& customer, const string& stock) const;
19
20 private:
21  typedef std::pair<string, int> Entry;
22  typedef std::vector<Entry> EntryList;
23  typedef std::map<string, EntryList> Map;
24  typedef boost::shared_ptr<Map> MapPtr;
25  void update(const string& customer, const EntryList& entries);
26  void update(const string& message);
27
28  static int findEntry(const EntryList& entries, const string& stock);
29  static MapPtr parseData(const string& message);
30
31  MapPtr getData() const
32  {
33    muduo::MutexLockGuard lock(mutex_);
34    return data_;
35  }
36
37  mutable muduo::MutexLock mutex_;
38  MapPtr data_;
39};
40
41int CustomerData::query(const string& customer, const string& stock) const
42{
43  MapPtr data = getData();
44
45  Map::const_iterator entries = data->find(customer);
46  if (entries != data->end())
47    return findEntry(entries->second, stock);
48  else
49    return -1;
50}
51
52void CustomerData::update(const string& customer, const EntryList& entries)
53{
54  muduo::MutexLockGuard lock(mutex_);
55  if (!data_.unique())
56  {
57    MapPtr newData(new Map(*data_));
58    data_.swap(newData);
59  }
60  assert(data_.unique());
61  (*data_)[customer] = entries;
62}
63
64void CustomerData::update(const string& message)
65{
66  MapPtr newData = parseData(message);
67  if (newData)
68  {
69    muduo::MutexLockGuard lock(mutex_);
70    data_.swap(newData);
71  }
72}
73
74int main()
75{
76  CustomerData data;
77}
78