1c55a96383497a772a307b346368133960b02ad03Eric Laurent/*
2c55a96383497a772a307b346368133960b02ad03Eric Laurent *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3c55a96383497a772a307b346368133960b02ad03Eric Laurent *
4c55a96383497a772a307b346368133960b02ad03Eric Laurent *  Use of this source code is governed by a BSD-style license
5c55a96383497a772a307b346368133960b02ad03Eric Laurent *  that can be found in the LICENSE file in the root of the source
6c55a96383497a772a307b346368133960b02ad03Eric Laurent *  tree. An additional intellectual property rights grant can be found
7c55a96383497a772a307b346368133960b02ad03Eric Laurent *  in the file PATENTS.  All contributing project authors may
8c55a96383497a772a307b346368133960b02ad03Eric Laurent *  be found in the AUTHORS file in the root of the source tree.
9c55a96383497a772a307b346368133960b02ad03Eric Laurent */
10c55a96383497a772a307b346368133960b02ad03Eric Laurent
11c55a96383497a772a307b346368133960b02ad03Eric Laurent/*
12c55a96383497a772a307b346368133960b02ad03Eric Laurent * This file contains the helper classes for the DataLog APIs. See data_log.h
13c55a96383497a772a307b346368133960b02ad03Eric Laurent * for the APIs.
14c55a96383497a772a307b346368133960b02ad03Eric Laurent *
15c55a96383497a772a307b346368133960b02ad03Eric Laurent * These classes are helper classes used for logging data for offline
16c55a96383497a772a307b346368133960b02ad03Eric Laurent * processing. Data logged with these classes can conveniently be parsed and
17c55a96383497a772a307b346368133960b02ad03Eric Laurent * processed with e.g. Matlab.
18c55a96383497a772a307b346368133960b02ad03Eric Laurent */
19c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_IMPL_H_
20c55a96383497a772a307b346368133960b02ad03Eric Laurent#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_IMPL_H_
21c55a96383497a772a307b346368133960b02ad03Eric Laurent
22c55a96383497a772a307b346368133960b02ad03Eric Laurent#include <map>
23c55a96383497a772a307b346368133960b02ad03Eric Laurent#include <sstream>
24c55a96383497a772a307b346368133960b02ad03Eric Laurent#include <string>
25c55a96383497a772a307b346368133960b02ad03Eric Laurent#include <vector>
26c55a96383497a772a307b346368133960b02ad03Eric Laurent
27c55a96383497a772a307b346368133960b02ad03Eric Laurent#include "scoped_ptr.h"
28c55a96383497a772a307b346368133960b02ad03Eric Laurent#include "typedefs.h"
29c55a96383497a772a307b346368133960b02ad03Eric Laurent
30c55a96383497a772a307b346368133960b02ad03Eric Laurentnamespace webrtc {
31c55a96383497a772a307b346368133960b02ad03Eric Laurent
32c55a96383497a772a307b346368133960b02ad03Eric Laurentclass CriticalSectionWrapper;
33c55a96383497a772a307b346368133960b02ad03Eric Laurentclass EventWrapper;
34c55a96383497a772a307b346368133960b02ad03Eric Laurentclass LogTable;
35c55a96383497a772a307b346368133960b02ad03Eric Laurentclass RWLockWrapper;
36c55a96383497a772a307b346368133960b02ad03Eric Laurentclass ThreadWrapper;
37c55a96383497a772a307b346368133960b02ad03Eric Laurent
38c55a96383497a772a307b346368133960b02ad03Eric Laurent// All container classes need to implement a ToString-function to be
39c55a96383497a772a307b346368133960b02ad03Eric Laurent// writable to file. Enforce this via the Container interface.
40c55a96383497a772a307b346368133960b02ad03Eric Laurentclass Container {
41c55a96383497a772a307b346368133960b02ad03Eric Laurent public:
42c55a96383497a772a307b346368133960b02ad03Eric Laurent  virtual ~Container() {}
43c55a96383497a772a307b346368133960b02ad03Eric Laurent
44c55a96383497a772a307b346368133960b02ad03Eric Laurent  virtual void ToString(std::string* container_string) const = 0;
45c55a96383497a772a307b346368133960b02ad03Eric Laurent};
46c55a96383497a772a307b346368133960b02ad03Eric Laurent
47c55a96383497a772a307b346368133960b02ad03Eric Laurenttemplate<class T>
48c55a96383497a772a307b346368133960b02ad03Eric Laurentclass ValueContainer : public Container {
49c55a96383497a772a307b346368133960b02ad03Eric Laurent public:
50c55a96383497a772a307b346368133960b02ad03Eric Laurent  explicit ValueContainer(T data) : data_(data) {}
51c55a96383497a772a307b346368133960b02ad03Eric Laurent
52c55a96383497a772a307b346368133960b02ad03Eric Laurent  virtual void ToString(std::string* container_string) const {
53c55a96383497a772a307b346368133960b02ad03Eric Laurent    *container_string = "";
54c55a96383497a772a307b346368133960b02ad03Eric Laurent    std::stringstream ss;
55c55a96383497a772a307b346368133960b02ad03Eric Laurent    ss << data_ << ",";
56c55a96383497a772a307b346368133960b02ad03Eric Laurent    ss >> *container_string;
57c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
58c55a96383497a772a307b346368133960b02ad03Eric Laurent
59c55a96383497a772a307b346368133960b02ad03Eric Laurent private:
60c55a96383497a772a307b346368133960b02ad03Eric Laurent  T   data_;
61c55a96383497a772a307b346368133960b02ad03Eric Laurent};
62c55a96383497a772a307b346368133960b02ad03Eric Laurent
63c55a96383497a772a307b346368133960b02ad03Eric Laurenttemplate<class T>
64c55a96383497a772a307b346368133960b02ad03Eric Laurentclass MultiValueContainer : public Container {
65c55a96383497a772a307b346368133960b02ad03Eric Laurent public:
66c55a96383497a772a307b346368133960b02ad03Eric Laurent  MultiValueContainer(const T* data, int length)
67c55a96383497a772a307b346368133960b02ad03Eric Laurent    : data_(data, data + length) {
68c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
69c55a96383497a772a307b346368133960b02ad03Eric Laurent
70c55a96383497a772a307b346368133960b02ad03Eric Laurent  virtual void ToString(std::string* container_string) const {
71c55a96383497a772a307b346368133960b02ad03Eric Laurent    *container_string = "";
72c55a96383497a772a307b346368133960b02ad03Eric Laurent    std::stringstream ss;
73c55a96383497a772a307b346368133960b02ad03Eric Laurent    for (size_t i = 0; i < data_.size(); ++i)
74c55a96383497a772a307b346368133960b02ad03Eric Laurent      ss << data_[i] << ",";
75c55a96383497a772a307b346368133960b02ad03Eric Laurent    *container_string += ss.str();
76c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
77c55a96383497a772a307b346368133960b02ad03Eric Laurent
78c55a96383497a772a307b346368133960b02ad03Eric Laurent private:
79c55a96383497a772a307b346368133960b02ad03Eric Laurent  std::vector<T>  data_;
80c55a96383497a772a307b346368133960b02ad03Eric Laurent};
81c55a96383497a772a307b346368133960b02ad03Eric Laurent
82c55a96383497a772a307b346368133960b02ad03Eric Laurentclass DataLogImpl {
83c55a96383497a772a307b346368133960b02ad03Eric Laurent public:
84c55a96383497a772a307b346368133960b02ad03Eric Laurent  ~DataLogImpl();
85c55a96383497a772a307b346368133960b02ad03Eric Laurent
86c55a96383497a772a307b346368133960b02ad03Eric Laurent  // The implementation of the CreateLog() method declared in data_log.h.
87c55a96383497a772a307b346368133960b02ad03Eric Laurent  // See data_log.h for a description.
88c55a96383497a772a307b346368133960b02ad03Eric Laurent  static int CreateLog();
89c55a96383497a772a307b346368133960b02ad03Eric Laurent
90c55a96383497a772a307b346368133960b02ad03Eric Laurent  // The implementation of the StaticInstance() method declared in data_log.h.
91c55a96383497a772a307b346368133960b02ad03Eric Laurent  // See data_log.h for a description.
92c55a96383497a772a307b346368133960b02ad03Eric Laurent  static DataLogImpl* StaticInstance();
93c55a96383497a772a307b346368133960b02ad03Eric Laurent
94c55a96383497a772a307b346368133960b02ad03Eric Laurent  // The implementation of the ReturnLog() method declared in data_log.h. See
95c55a96383497a772a307b346368133960b02ad03Eric Laurent  // data_log.h for a description.
96c55a96383497a772a307b346368133960b02ad03Eric Laurent  static void ReturnLog();
97c55a96383497a772a307b346368133960b02ad03Eric Laurent
98c55a96383497a772a307b346368133960b02ad03Eric Laurent  // The implementation of the AddTable() method declared in data_log.h. See
99c55a96383497a772a307b346368133960b02ad03Eric Laurent  // data_log.h for a description.
100c55a96383497a772a307b346368133960b02ad03Eric Laurent  int AddTable(const std::string& table_name);
101c55a96383497a772a307b346368133960b02ad03Eric Laurent
102c55a96383497a772a307b346368133960b02ad03Eric Laurent  // The implementation of the AddColumn() method declared in data_log.h. See
103c55a96383497a772a307b346368133960b02ad03Eric Laurent  // data_log.h for a description.
104c55a96383497a772a307b346368133960b02ad03Eric Laurent  int AddColumn(const std::string& table_name,
105c55a96383497a772a307b346368133960b02ad03Eric Laurent                const std::string& column_name,
106c55a96383497a772a307b346368133960b02ad03Eric Laurent                int multi_value_length);
107c55a96383497a772a307b346368133960b02ad03Eric Laurent
108c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Inserts a Container into a table with name table_name at the column
109c55a96383497a772a307b346368133960b02ad03Eric Laurent  // with name column_name.
110c55a96383497a772a307b346368133960b02ad03Eric Laurent  // column_name is treated in a case sensitive way.
111c55a96383497a772a307b346368133960b02ad03Eric Laurent  int InsertCell(const std::string& table_name,
112c55a96383497a772a307b346368133960b02ad03Eric Laurent                 const std::string& column_name,
113c55a96383497a772a307b346368133960b02ad03Eric Laurent                 const Container* value_container);
114c55a96383497a772a307b346368133960b02ad03Eric Laurent
115c55a96383497a772a307b346368133960b02ad03Eric Laurent  // The implementation of the NextRow() method declared in data_log.h. See
116c55a96383497a772a307b346368133960b02ad03Eric Laurent  // data_log.h for a description.
117c55a96383497a772a307b346368133960b02ad03Eric Laurent  int NextRow(const std::string& table_name);
118c55a96383497a772a307b346368133960b02ad03Eric Laurent
119c55a96383497a772a307b346368133960b02ad03Eric Laurent private:
120c55a96383497a772a307b346368133960b02ad03Eric Laurent  DataLogImpl();
121c55a96383497a772a307b346368133960b02ad03Eric Laurent
122c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Initializes the DataLogImpl object, allocates and starts the
123c55a96383497a772a307b346368133960b02ad03Eric Laurent  // thread file_writer_thread_.
124c55a96383497a772a307b346368133960b02ad03Eric Laurent  int Init();
125c55a96383497a772a307b346368133960b02ad03Eric Laurent
126c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Write all complete rows in every table to file.
127c55a96383497a772a307b346368133960b02ad03Eric Laurent  // This function should only be called by the file_writer_thread_ if that
128c55a96383497a772a307b346368133960b02ad03Eric Laurent  // thread is running to avoid race conditions.
129c55a96383497a772a307b346368133960b02ad03Eric Laurent  void Flush();
130c55a96383497a772a307b346368133960b02ad03Eric Laurent
131c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Run() is called by the thread file_writer_thread_.
132c55a96383497a772a307b346368133960b02ad03Eric Laurent  static bool Run(void* obj);
133c55a96383497a772a307b346368133960b02ad03Eric Laurent
134c55a96383497a772a307b346368133960b02ad03Eric Laurent  // This function writes data to file. Note, it blocks if there is no data
135c55a96383497a772a307b346368133960b02ad03Eric Laurent  // that should be written to file availble. Flush is the non-blocking
136c55a96383497a772a307b346368133960b02ad03Eric Laurent  // version of this function.
137c55a96383497a772a307b346368133960b02ad03Eric Laurent  void Process();
138c55a96383497a772a307b346368133960b02ad03Eric Laurent
139c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Stops the continuous calling of Process().
140c55a96383497a772a307b346368133960b02ad03Eric Laurent  void StopThread();
141c55a96383497a772a307b346368133960b02ad03Eric Laurent
142c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Collection of tables indexed by the table name as std::string.
143c55a96383497a772a307b346368133960b02ad03Eric Laurent  typedef std::map<std::string, LogTable*> TableMap;
144c55a96383497a772a307b346368133960b02ad03Eric Laurent  typedef webrtc::scoped_ptr<CriticalSectionWrapper> CritSectScopedPtr;
145c55a96383497a772a307b346368133960b02ad03Eric Laurent
146c55a96383497a772a307b346368133960b02ad03Eric Laurent  static CritSectScopedPtr  crit_sect_;
147c55a96383497a772a307b346368133960b02ad03Eric Laurent  static DataLogImpl*       instance_;
148c55a96383497a772a307b346368133960b02ad03Eric Laurent  int                       counter_;
149c55a96383497a772a307b346368133960b02ad03Eric Laurent  TableMap                  tables_;
150c55a96383497a772a307b346368133960b02ad03Eric Laurent  EventWrapper*             flush_event_;
151c55a96383497a772a307b346368133960b02ad03Eric Laurent  ThreadWrapper*            file_writer_thread_;
152c55a96383497a772a307b346368133960b02ad03Eric Laurent  RWLockWrapper*            tables_lock_;
153c55a96383497a772a307b346368133960b02ad03Eric Laurent};
154c55a96383497a772a307b346368133960b02ad03Eric Laurent
155c55a96383497a772a307b346368133960b02ad03Eric Laurent}  // namespace webrtc
156c55a96383497a772a307b346368133960b02ad03Eric Laurent
157c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif  // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_DATA_LOG_IMPL_H_
158