- Removed one copy of an uncompressed block contents changing the signature of Snappy_Uncompress() so it uncompresses into a flat array instead of a std::string. Speeds up readrandom ~10%. - Instead of a combination of Env/WritableFile, we now have a Logger interface that can be easily overridden applications that want to supply their own logging. - Separated out the gcc and Sun Studio parts of atomic_pointer.h so we can use 'asm', 'volatile' keywords for Sun Studio. git-svn-id: https://leveldb.googlecode.com/svn/trunk@39 62dab493-f737-651d-591e-8d6aee1b9529main
parent
6872ace901
commit
60bd8015f2
@ -0,0 +1,97 @@ |
||||
// Copyright 2011 Google Inc. All Rights Reserved.
|
||||
// Author: sanjay@google.com (Sanjay Ghemawat)
|
||||
//
|
||||
// Logger implementation that can be shared by all environments
|
||||
// where enough posix functionality is available.
|
||||
|
||||
#ifndef STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_ |
||||
#define STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_ |
||||
|
||||
#include <algorithm> |
||||
#include <stdio.h> |
||||
#include <sys/time.h> |
||||
#include <time.h> |
||||
#include "leveldb/env.h" |
||||
|
||||
namespace leveldb { |
||||
|
||||
class PosixLogger : public Logger { |
||||
private: |
||||
FILE* file_; |
||||
uint64_t (*gettid_)(); // Return the thread id for the current thread
|
||||
public: |
||||
PosixLogger(FILE* f, uint64_t (*gettid)()) : file_(f), gettid_(gettid) { } |
||||
virtual ~PosixLogger() { |
||||
fclose(file_); |
||||
} |
||||
virtual void Logv(const char* format, va_list ap) { |
||||
const uint64_t thread_id = (*gettid_)(); |
||||
|
||||
// We try twice: the first time with a fixed-size stack allocated buffer,
|
||||
// and the second time with a much larger dynamically allocated buffer.
|
||||
char buffer[500]; |
||||
for (int iter = 0; iter < 2; iter++) { |
||||
char* base; |
||||
int bufsize; |
||||
if (iter == 0) { |
||||
bufsize = sizeof(buffer); |
||||
base = buffer; |
||||
} else { |
||||
bufsize = 30000; |
||||
base = new char[bufsize]; |
||||
} |
||||
char* p = base; |
||||
char* limit = base + bufsize; |
||||
|
||||
struct timeval now_tv; |
||||
gettimeofday(&now_tv, NULL); |
||||
const time_t seconds = now_tv.tv_sec; |
||||
struct tm t; |
||||
localtime_r(&seconds, &t); |
||||
p += snprintf(p, limit - p, |
||||
"%04d/%02d/%02d-%02d:%02d:%02d.%06d %llx ", |
||||
t.tm_year + 1900, |
||||
t.tm_mon + 1, |
||||
t.tm_mday, |
||||
t.tm_hour, |
||||
t.tm_min, |
||||
t.tm_sec, |
||||
static_cast<int>(now_tv.tv_usec), |
||||
static_cast<long long unsigned int>(thread_id)); |
||||
|
||||
// Print the message
|
||||
if (p < limit) { |
||||
va_list backup_ap; |
||||
va_copy(backup_ap, ap); |
||||
p += vsnprintf(p, limit - p, format, backup_ap); |
||||
va_end(backup_ap); |
||||
} |
||||
|
||||
// Truncate to available space if necessary
|
||||
if (p >= limit) { |
||||
if (iter == 0) { |
||||
continue; // Try again with larger buffer
|
||||
} else { |
||||
p = limit - 1; |
||||
} |
||||
} |
||||
|
||||
// Add newline if necessary
|
||||
if (p == base || p[-1] != '\n') { |
||||
*p++ = '\n'; |
||||
} |
||||
|
||||
assert(p <= limit); |
||||
fwrite(base, 1, p - base, file_); |
||||
fflush(file_); |
||||
if (base != buffer) { |
||||
delete[] base; |
||||
} |
||||
break; |
||||
} |
||||
} |
||||
}; |
||||
|
||||
} |
||||
|
||||
#endif // STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_
|
Loading…
Reference in new issue