195456d52SShuo Chen#include <map>
295456d52SShuo Chen#include <string>
395456d52SShuo Chen#include <vector>
495456d52SShuo Chen
595456d52SShuo Chen#include <boost/shared_ptr.hpp>
695456d52SShuo Chen
795456d52SShuo Chen#include "../Mutex.h"
895456d52SShuo Chen
995456d52SShuo Chenusing std::string;
1095456d52SShuo Chen
1195456d52SShuo Chenclass CustomerData : boost::noncopyable
1295456d52SShuo Chen{
1395456d52SShuo Chen public:
1495456d52SShuo Chen  CustomerData()
1595456d52SShuo Chen    : data_(new Map)
1695456d52SShuo Chen  { }
1795456d52SShuo Chen
1895456d52SShuo Chen  int query(const string& customer, const string& stock) const;
1995456d52SShuo Chen
2095456d52SShuo Chen private:
2195456d52SShuo Chen  typedef std::pair<string, int> Entry;
2295456d52SShuo Chen  typedef std::vector<Entry> EntryList;
2395456d52SShuo Chen  typedef std::map<string, EntryList> Map;
2495456d52SShuo Chen  typedef boost::shared_ptr<Map> MapPtr;
2595456d52SShuo Chen  void update(const string& customer, const EntryList& entries);
2695456d52SShuo Chen  void update(const string& message);
2795456d52SShuo Chen
2895456d52SShuo Chen  static int findEntry(const EntryList& entries, const string& stock);
2995456d52SShuo Chen  static MapPtr parseData(const string& message);
3095456d52SShuo Chen
3195456d52SShuo Chen  MapPtr getData() const
3295456d52SShuo Chen  {
3395456d52SShuo Chen    muduo::MutexLockGuard lock(mutex_);
3495456d52SShuo Chen    return data_;
3595456d52SShuo Chen  }
3695456d52SShuo Chen
3795456d52SShuo Chen  mutable muduo::MutexLock mutex_;
3895456d52SShuo Chen  MapPtr data_;
3995456d52SShuo Chen};
4095456d52SShuo Chen
4195456d52SShuo Chenint CustomerData::query(const string& customer, const string& stock) const
4295456d52SShuo Chen{
4395456d52SShuo Chen  MapPtr data = getData();
4495456d52SShuo Chen
4595456d52SShuo Chen  Map::const_iterator entries = data->find(customer);
4695456d52SShuo Chen  if (entries != data->end())
4795456d52SShuo Chen    return findEntry(entries->second, stock);
4895456d52SShuo Chen  else
4995456d52SShuo Chen    return -1;
5095456d52SShuo Chen}
5195456d52SShuo Chen
5295456d52SShuo Chenvoid CustomerData::update(const string& customer, const EntryList& entries)
5395456d52SShuo Chen{
5495456d52SShuo Chen  muduo::MutexLockGuard lock(mutex_);
5595456d52SShuo Chen  if (!data_.unique())
5695456d52SShuo Chen  {
5795456d52SShuo Chen    MapPtr newData(new Map(*data_));
5895456d52SShuo Chen    data_.swap(newData);
5995456d52SShuo Chen  }
6095456d52SShuo Chen  assert(data_.unique());
6195456d52SShuo Chen  (*data_)[customer] = entries;
6295456d52SShuo Chen}
6395456d52SShuo Chen
6495456d52SShuo Chenvoid CustomerData::update(const string& message)
6595456d52SShuo Chen{
6695456d52SShuo Chen  MapPtr newData = parseData(message);
6795456d52SShuo Chen  if (newData)
6895456d52SShuo Chen  {
6995456d52SShuo Chen    muduo::MutexLockGuard lock(mutex_);
7095456d52SShuo Chen    data_.swap(newData);
7195456d52SShuo Chen  }
7295456d52SShuo Chen}
7395456d52SShuo Chen
7495456d52SShuo Chenint main()
7595456d52SShuo Chen{
7695456d52SShuo Chen  CustomerData data;
7795456d52SShuo Chen}
78