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:
stefan@webrtc.org 2011-09-07 15:31:03 +00:00
parent dd07d5932a
commit 3bbe41aad6
5 changed files with 89 additions and 91 deletions

View File

@ -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);
};

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);