- 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