Add support for a numeric table id in DataLogs.
Useful when logging in modules which have multiple instances and the logs should be separated into different tables. Review URL: http://webrtc-codereview.appspot.com/132003 git-svn-id: http://webrtc.googlecode.com/svn/trunk@555 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
dd07d5932a
commit
3bbe41aad6
@ -53,26 +53,29 @@ class DataLog {
|
||||
// CreateLog or memory leak will occur.
|
||||
static void ReturnLog();
|
||||
|
||||
// Adds a new table, with the name table_name, and creates the file, with
|
||||
// the name file_name, to which the table will be written.
|
||||
// table_name is case sensitive.
|
||||
static int AddTable(const std::string& table_name,
|
||||
const std::string& file_name);
|
||||
// Combines the string table_name and the integer table_id into a new string
|
||||
// table_name + _ + table_id. The new string will be lower-case.
|
||||
static std::string Combine(const std::string& table_name, int table_id);
|
||||
|
||||
// Adds a new table, with the name table_name, and creates the file, with the
|
||||
// name table_name + ".txt", to which the table will be written.
|
||||
// table_name is treated in a case sensitive way.
|
||||
static int AddTable(const std::string& table_name);
|
||||
|
||||
// Adds a new column to a table. The column will be a multi-value-column
|
||||
// if multi_value_length is greater than 1.
|
||||
// Both table_name and column_name are case sensitive.
|
||||
// table_name and column_name are treated in a case sensitive way.
|
||||
static int AddColumn(const std::string& table_name,
|
||||
const std::string& column_name,
|
||||
int multi_value_length);
|
||||
|
||||
// Inserts a single value into a table with name table_name at the column
|
||||
// with name column_name.
|
||||
// Inserts a single value into a table with name table_name at the column with
|
||||
// name column_name.
|
||||
// Note that the ValueContainer makes use of the copy constructor,
|
||||
// operator= and operator<< of the type T, and that the template type must
|
||||
// implement a deep copy copy constructor and operator=.
|
||||
// Copy constructor and operator= must not be disabled for the type T.
|
||||
// Both table_name and column_name are case sensitive.
|
||||
// table_name and column_name are treated in a case sensitive way.
|
||||
template<class T>
|
||||
static int InsertCell(const std::string& table_name,
|
||||
const std::string& column_name,
|
||||
@ -92,7 +95,7 @@ class DataLog {
|
||||
// operator= and operator<< of the type T, and that the template type
|
||||
// must implement a deep copy copy constructor and operator=.
|
||||
// Copy constructor and operator= must not be disabled for the type T.
|
||||
// Both table_name and column_name are case sensitive.
|
||||
// table_name and column_name are treated in a case sensitive way.
|
||||
template<class T>
|
||||
static int InsertCell(const std::string& table_name,
|
||||
const std::string& column_name,
|
||||
@ -107,9 +110,9 @@ class DataLog {
|
||||
new MultiValueContainer<T>(array, length));
|
||||
}
|
||||
|
||||
// For the table table_name: Writes the current row to file. Starts a new
|
||||
// empty row.
|
||||
// table_name is case sensitive.
|
||||
// For the table with name table_name: Writes the current row to file.
|
||||
// Starts a new empty row.
|
||||
// table_name is treated in a case-sensitive way.
|
||||
static int NextRow(const std::string& table_name);
|
||||
};
|
||||
|
||||
|
@ -83,47 +83,37 @@ class DataLogImpl {
|
||||
public:
|
||||
~DataLogImpl();
|
||||
|
||||
// Creates a log which uses a separate thread (referred to as the file
|
||||
// writer thread) for writing log rows to file.
|
||||
//
|
||||
// Calls to this function after the log object has been created will only
|
||||
// increment the reference counter.
|
||||
// The implementation of the CreateLog() method declared in data_log.h.
|
||||
// See data_log.h for a description.
|
||||
static int CreateLog();
|
||||
|
||||
// Returns a pointer to the instance of DataLogImpl which was created by
|
||||
// CreateLog(), or NULL if no instance has been created, or if the
|
||||
// previous instance has been deleted.
|
||||
// The implementation of the StaticInstance() method declared in data_log.h.
|
||||
// See data_log.h for a description.
|
||||
static DataLogImpl* StaticInstance();
|
||||
|
||||
// Decrements the reference counter keeping track of the number of times
|
||||
// CreateLog() has been called. When the reference counter reaches 0
|
||||
// the DataLogImpl instance created by CreateLog() will be deleted.
|
||||
// Should be called equal number of times as successful calls to
|
||||
// CreateLog or memory leak will occur.
|
||||
// The implementation of the ReturnLog() method declared in data_log.h. See
|
||||
// data_log.h for a description.
|
||||
static void ReturnLog();
|
||||
|
||||
// Adds a new table, with the name table_name, and creates the file, with
|
||||
// the name file_name, to which the table will be written.
|
||||
// table_name is case sensitive.
|
||||
int AddTable(const std::string& table_name, const std::string& file_name);
|
||||
// The implementation of the AddTable() method declared in data_log.h. See
|
||||
// data_log.h for a description.
|
||||
int AddTable(const std::string& table_name);
|
||||
|
||||
// Adds a new column to a table. The column will be a multi-value-column
|
||||
// if multi_value_length is greater than 1.
|
||||
// Both table_name and column_name are case sensitive.
|
||||
// The implementation of the AddColumn() method declared in data_log.h. See
|
||||
// data_log.h for a description.
|
||||
int AddColumn(const std::string& table_name,
|
||||
const std::string& column_name,
|
||||
int multi_value_length);
|
||||
|
||||
// Inserts a Container into a table with name table_name at the column
|
||||
// with name column_name.
|
||||
// Both table_name and column_name are case sensitive.
|
||||
// column_name is treated in a case sensitive way.
|
||||
int InsertCell(const std::string& table_name,
|
||||
const std::string& column_name,
|
||||
const Container* value_container);
|
||||
|
||||
// For the table table_name: Writes the current row to file. Starts a new
|
||||
// empty row.
|
||||
// table_name is case sensitive.
|
||||
// The implementation of the NextRow() method declared in data_log.h. See
|
||||
// data_log.h for a description.
|
||||
int NextRow(const std::string& table_name);
|
||||
|
||||
private:
|
||||
@ -149,7 +139,7 @@ class DataLogImpl {
|
||||
// Stops the continuous calling of Process().
|
||||
void StopThread();
|
||||
|
||||
// Collection of tables indexed by table name as std::string
|
||||
// Collection of tables indexed by the table name as std::string.
|
||||
typedef std::map<std::string, LogTable*> TableMap;
|
||||
typedef webrtc::scoped_ptr<CriticalSectionWrapper> CritSectScopedPtr;
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <list>
|
||||
|
||||
#include "critical_section_wrapper.h"
|
||||
@ -28,7 +29,7 @@ DataLogImpl::CritSectScopedPtr DataLogImpl::crit_sect_(
|
||||
DataLogImpl* DataLogImpl::instance_ = NULL;
|
||||
|
||||
// A Row contains cells, which are indexed by the column names as std::string.
|
||||
// The string index is case sensitive.
|
||||
// The string index is treated in a case sensitive way.
|
||||
class Row {
|
||||
public:
|
||||
Row();
|
||||
@ -36,13 +37,13 @@ class Row {
|
||||
|
||||
// Inserts a Container into the cell of the column specified with
|
||||
// column_name.
|
||||
// column_name is case sensitive.
|
||||
// column_name is treated in a case sensitive way.
|
||||
int InsertCell(const std::string& column_name,
|
||||
const Container* value_container);
|
||||
|
||||
// Converts the value at the column specified by column_name to a string
|
||||
// stored in value_string.
|
||||
// column_name is case sensitive.
|
||||
// column_name is treated in a case sensitive way.
|
||||
void ToString(const std::string& column_name, std::string* value_string);
|
||||
|
||||
private:
|
||||
@ -64,7 +65,7 @@ class LogTable {
|
||||
|
||||
// Adds the column with name column_name to the table. The column will be a
|
||||
// multi-value-column if multi_value_length is greater than 1.
|
||||
// column_name is case sensitive.
|
||||
// column_name is treated in a case sensitive way.
|
||||
int AddColumn(const std::string& column_name, int multi_value_length);
|
||||
|
||||
// Buffers the current row while it is waiting to be written to file,
|
||||
@ -74,7 +75,7 @@ class LogTable {
|
||||
|
||||
// Inserts a Container into the cell of the column specified with
|
||||
// column_name.
|
||||
// column_name is case sensitive.
|
||||
// column_name is treated in a case sensitive way.
|
||||
int InsertCell(const std::string& column_name,
|
||||
const Container* value_container);
|
||||
|
||||
@ -280,12 +281,21 @@ void DataLog::ReturnLog() {
|
||||
return DataLogImpl::ReturnLog();
|
||||
}
|
||||
|
||||
int DataLog::AddTable(const std::string& table_name,
|
||||
const std::string& file_name) {
|
||||
std::string DataLog::Combine(const std::string& table_name, int table_id) {
|
||||
std::stringstream ss;
|
||||
std::string combined_id;
|
||||
ss << table_name << "_" << table_id;
|
||||
ss >> combined_id;
|
||||
std::transform(combined_id.begin(), combined_id.end(), combined_id.begin(),
|
||||
::tolower);
|
||||
return combined_id;
|
||||
}
|
||||
|
||||
int DataLog::AddTable(const std::string& table_name) {
|
||||
DataLogImpl* data_log = DataLogImpl::StaticInstance();
|
||||
if (data_log == NULL)
|
||||
return -1;
|
||||
return data_log->AddTable(table_name, file_name);
|
||||
return data_log->AddTable(table_name);
|
||||
}
|
||||
|
||||
int DataLog::AddColumn(const std::string& table_name,
|
||||
@ -367,14 +377,13 @@ void DataLogImpl::ReturnLog() {
|
||||
instance_ = NULL;
|
||||
}
|
||||
|
||||
int DataLogImpl::AddTable(const std::string& table_name,
|
||||
const std::string& file_name) {
|
||||
int DataLogImpl::AddTable(const std::string& table_name) {
|
||||
WriteLockScoped synchronize(*tables_lock_);
|
||||
// Make sure we don't add a table which already exists
|
||||
if (tables_.count(table_name) > 0)
|
||||
return -1;
|
||||
tables_[table_name] = new LogTable();
|
||||
if (tables_[table_name]->CreateLogFile(file_name) == -1)
|
||||
if (tables_[table_name]->CreateLogFile(table_name + ".txt") == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -19,8 +19,7 @@ int DataLog::CreateLog() {
|
||||
void DataLog::ReturnLog() {
|
||||
}
|
||||
|
||||
int DataLog::AddTable(const std::string& /*table_name*/,
|
||||
const std::string& /*file_name*/) {
|
||||
int DataLog::AddTable(const std::string& /*table_name*/) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -47,8 +46,7 @@ DataLogImpl* DataLogImpl::StaticInstance() {
|
||||
void DataLogImpl::ReturnLog() {
|
||||
}
|
||||
|
||||
int DataLogImpl::AddTable(const std::string& /*table_name*/,
|
||||
const std::string& /*file_name*/) {
|
||||
int DataLogImpl::AddTable(const std::string& /*table_name*/) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -113,29 +113,30 @@ class DataLogParser {
|
||||
TEST(TestDataLog, CreateReturnTest) {
|
||||
for (int i = 0; i < 10; ++i)
|
||||
ASSERT_EQ(DataLog::CreateLog(), 0);
|
||||
ASSERT_EQ(DataLog::AddTable("a proper table", "table.txt"), 0);
|
||||
ASSERT_EQ(DataLog::AddTable(DataLog::Combine("a proper table", 1)), 0);
|
||||
for (int i = 0; i < 10; ++i)
|
||||
DataLog::ReturnLog();
|
||||
ASSERT_LT(DataLog::AddTable("table failure", "table.txt"), 0);
|
||||
ASSERT_LT(DataLog::AddTable(DataLog::Combine("table failure", 1)), 0);
|
||||
}
|
||||
|
||||
TEST(TestDataLog, VerifySingleTable) {
|
||||
DataLog::CreateLog();
|
||||
DataLog::AddTable("table1", "table1.txt");
|
||||
DataLog::AddColumn("table1", "arrival", 1);
|
||||
DataLog::AddColumn("table1", "timestamp", 1);
|
||||
DataLog::AddColumn("table1", "size", 5);
|
||||
DataLog::AddTable(DataLog::Combine("table", 1));
|
||||
DataLog::AddColumn(DataLog::Combine("table", 1), "arrival", 1);
|
||||
DataLog::AddColumn(DataLog::Combine("table", 1), "timestamp", 1);
|
||||
DataLog::AddColumn(DataLog::Combine("table", 1), "size", 5);
|
||||
WebRtc_UWord32 sizes[5] = {1400, 1500, 1600, 1700, 1800};
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
DataLog::InsertCell("table1", "arrival", static_cast<double>(i));
|
||||
DataLog::InsertCell("table1", "timestamp",
|
||||
DataLog::InsertCell(DataLog::Combine("table", 1), "arrival",
|
||||
static_cast<double>(i));
|
||||
DataLog::InsertCell(DataLog::Combine("table", 1), "timestamp",
|
||||
static_cast<WebRtc_Word64>(4354 + i));
|
||||
DataLog::InsertCell("table1", "size", sizes, 5);
|
||||
DataLog::NextRow("table1");
|
||||
DataLog::InsertCell(DataLog::Combine("table", 1), "size", sizes, 5);
|
||||
DataLog::NextRow(DataLog::Combine("table", 1));
|
||||
}
|
||||
DataLog::ReturnLog();
|
||||
// Verify file
|
||||
FILE* table = fopen("table1.txt", "r");
|
||||
FILE* table = fopen("table_1.txt", "r");
|
||||
ASSERT_FALSE(table == NULL);
|
||||
// Read the column names and verify with the expected columns.
|
||||
// Note that the columns are written to file in alphabetical order.
|
||||
@ -170,31 +171,31 @@ TEST(TestDataLog, VerifySingleTable) {
|
||||
|
||||
TEST(TestDataLog, VerifyMultipleTables) {
|
||||
DataLog::CreateLog();
|
||||
DataLog::AddTable("table2", "table2.txt");
|
||||
DataLog::AddTable("table3", "table3.txt");
|
||||
DataLog::AddColumn("table2", "arrival", 1);
|
||||
DataLog::AddColumn("table2", "timestamp", 1);
|
||||
DataLog::AddColumn("table2", "size", 1);
|
||||
DataLog::AddTable("table4", "table4.txt");
|
||||
DataLog::AddColumn("table3", "timestamp", 1);
|
||||
DataLog::AddColumn("table3", "arrival", 1);
|
||||
DataLog::AddColumn("table4", "size", 1);
|
||||
DataLog::AddTable(DataLog::Combine("table", 2));
|
||||
DataLog::AddTable(DataLog::Combine("table", 3));
|
||||
DataLog::AddColumn(DataLog::Combine("table", 2), "arrival", 1);
|
||||
DataLog::AddColumn(DataLog::Combine("table", 2), "timestamp", 1);
|
||||
DataLog::AddColumn(DataLog::Combine("table", 2), "size", 1);
|
||||
DataLog::AddTable(DataLog::Combine("table", 4));
|
||||
DataLog::AddColumn(DataLog::Combine("table", 3), "timestamp", 1);
|
||||
DataLog::AddColumn(DataLog::Combine("table", 3), "arrival", 1);
|
||||
DataLog::AddColumn(DataLog::Combine("table", 4), "size", 1);
|
||||
for (WebRtc_Word32 i = 0; i < 10; ++i) {
|
||||
DataLog::InsertCell("table2", "arrival",
|
||||
DataLog::InsertCell(DataLog::Combine("table", 2), "arrival",
|
||||
static_cast<WebRtc_Word32>(i));
|
||||
DataLog::InsertCell("table2", "timestamp",
|
||||
DataLog::InsertCell(DataLog::Combine("table", 2), "timestamp",
|
||||
static_cast<WebRtc_Word32>(4354 + i));
|
||||
DataLog::InsertCell("table2", "size",
|
||||
DataLog::InsertCell(DataLog::Combine("table", 2), "size",
|
||||
static_cast<WebRtc_Word32>(1200 + 10 * i));
|
||||
DataLog::InsertCell("table3", "timestamp",
|
||||
DataLog::InsertCell(DataLog::Combine("table", 3), "timestamp",
|
||||
static_cast<WebRtc_Word32>(4354 + i));
|
||||
DataLog::InsertCell("table3", "arrival",
|
||||
DataLog::InsertCell(DataLog::Combine("table", 3), "arrival",
|
||||
static_cast<WebRtc_Word32>(i));
|
||||
DataLog::InsertCell("table4", "size",
|
||||
DataLog::InsertCell(DataLog::Combine("table", 4), "size",
|
||||
static_cast<WebRtc_Word32>(1200 + 10 * i));
|
||||
DataLog::NextRow("table4");
|
||||
DataLog::NextRow("table2");
|
||||
DataLog::NextRow("table3");
|
||||
DataLog::NextRow(DataLog::Combine("table", 4));
|
||||
DataLog::NextRow(DataLog::Combine("table", 2));
|
||||
DataLog::NextRow(DataLog::Combine("table", 3));
|
||||
}
|
||||
DataLog::ReturnLog();
|
||||
|
||||
@ -217,7 +218,7 @@ TEST(TestDataLog, VerifyMultipleTables) {
|
||||
|
||||
// Verify table 2
|
||||
{
|
||||
FILE* table = fopen("table2.txt", "r");
|
||||
FILE* table = fopen("table_2.txt", "r");
|
||||
ASSERT_FALSE(table == NULL);
|
||||
ExpectedValuesMap expected;
|
||||
expected["arrival,"] = ExpectedValues(
|
||||
@ -240,20 +241,18 @@ TEST(TestDataLog, VerifyMultipleTables) {
|
||||
|
||||
// Verify table 3
|
||||
{
|
||||
FILE* table = fopen("table3.txt", "r");
|
||||
FILE* table = fopen("table_3.txt", "r");
|
||||
ASSERT_FALSE(table == NULL);
|
||||
ExpectedValuesMap expected;
|
||||
expected["arrival,"] = ExpectedValues(
|
||||
std::vector<std::string>(string_arrival,
|
||||
string_arrival +
|
||||
sizeof(string_arrival)
|
||||
/ sizeof(std::string)),
|
||||
kNumberOfRows),
|
||||
1);
|
||||
expected["timestamp,"] = ExpectedValues(
|
||||
std::vector<std::string>(string_timestamp,
|
||||
string_timestamp +
|
||||
sizeof(string_timestamp) /
|
||||
sizeof(std::string)),
|
||||
kNumberOfRows),
|
||||
1);
|
||||
ASSERT_EQ(DataLogParser::VerifyTable(table, expected), 0);
|
||||
fclose(table);
|
||||
@ -261,14 +260,13 @@ TEST(TestDataLog, VerifyMultipleTables) {
|
||||
|
||||
// Verify table 4
|
||||
{
|
||||
FILE* table = fopen("table4.txt", "r");
|
||||
FILE* table = fopen("table_4.txt", "r");
|
||||
ASSERT_FALSE(table == NULL);
|
||||
ExpectedValuesMap expected;
|
||||
expected["size,"] = ExpectedValues(
|
||||
std::vector<std::string>(string_size,
|
||||
string_size +
|
||||
sizeof(string_size)
|
||||
/ sizeof(std::string)),
|
||||
kNumberOfRows),
|
||||
1);
|
||||
ASSERT_EQ(DataLogParser::VerifyTable(table, expected), 0);
|
||||
fclose(table);
|
||||
|
Loading…
Reference in New Issue
Block a user