From 6872ace90110799f87402cbc594c4cbf1bc474c7 Mon Sep 17 00:00:00 2001 From: "gabor@google.com" Date: Tue, 19 Jul 2011 23:36:47 +0000 Subject: [PATCH] Sun Studio support, and fix for test related memory fixes. - LevelDB patch for Sun Studio Based on a patch submitted by Theo Schlossnagle - thanks! This fixes Issue 17. - Fix a couple of test related memory leaks. git-svn-id: https://leveldb.googlecode.com/svn/trunk@38 62dab493-f737-651d-591e-8d6aee1b9529 --- db/db_test.cc | 1 + db/dbformat.h | 2 +- db/filename.h | 2 +- db/log_format.h | 2 +- db/repair.cc | 5 +++++ db/skiplist_test.cc | 4 ++-- db/version_edit.cc | 2 +- db/version_set.cc | 11 ++++++++--- include/leveldb/options.h | 2 +- include/leveldb/status.h | 2 +- port/atomic_pointer.h | 5 +++-- table/table_test.cc | 9 +++++++-- util/comparator.cc | 1 + 13 files changed, 33 insertions(+), 15 deletions(-) diff --git a/db/db_test.cc b/db/db_test.cc index 0ac29e6..22fa70c 100644 --- a/db/db_test.cc +++ b/db/db_test.cc @@ -42,6 +42,7 @@ class SpecialEnv : public EnvWrapper { : env_(env), base_(base) { } + ~SSTableFile() { delete base_; } Status Append(const Slice& data) { return base_->Append(data); } Status Close() { return base_->Close(); } Status Flush() { return base_->Flush(); } diff --git a/db/dbformat.h b/db/dbformat.h index ec1d193..7344cbf 100644 --- a/db/dbformat.h +++ b/db/dbformat.h @@ -46,7 +46,7 @@ class InternalKey; // data structures. enum ValueType { kTypeDeletion = 0x0, - kTypeValue = 0x1, + kTypeValue = 0x1 }; // kValueTypeForSeek defines the ValueType that should be passed when // constructing a ParsedInternalKey object for seeking to a particular diff --git a/db/filename.h b/db/filename.h index 6a99744..e9ec8a7 100644 --- a/db/filename.h +++ b/db/filename.h @@ -24,7 +24,7 @@ enum FileType { kDescriptorFile, kCurrentFile, kTempFile, - kInfoLogFile, // Either the current one, or an old one + kInfoLogFile // Either the current one, or an old one }; // Return the name of the log file with the specified number diff --git a/db/log_format.h b/db/log_format.h index 137cd4a..353eff8 100644 --- a/db/log_format.h +++ b/db/log_format.h @@ -20,7 +20,7 @@ enum RecordType { // For fragments kFirstType = 2, kMiddleType = 3, - kLastType = 4, + kLastType = 4 }; static const int kMaxRecordType = kLastType; diff --git a/db/repair.cc b/db/repair.cc index ae1b136..2e3f506 100644 --- a/db/repair.cc +++ b/db/repair.cc @@ -50,6 +50,7 @@ class Repairer { icmp_(options.comparator), options_(SanitizeOptions(dbname, &icmp_, options)), owns_info_log_(options_.info_log != options.info_log), + owns_cache_(options_.block_cache != options.block_cache), next_file_number_(1) { // TableCache can be small since we expect each table to be opened once. table_cache_ = new TableCache(dbname_, &options_, 10); @@ -60,6 +61,9 @@ class Repairer { if (owns_info_log_) { delete options_.info_log; } + if (owns_cache_) { + delete options_.block_cache; + } } Status Run() { @@ -97,6 +101,7 @@ class Repairer { InternalKeyComparator const icmp_; Options const options_; bool owns_info_log_; + bool owns_cache_; TableCache* table_cache_; VersionEdit edit_; diff --git a/db/skiplist_test.cc b/db/skiplist_test.cc index 5f9ec0d..2bd8d22 100644 --- a/db/skiplist_test.cc +++ b/db/skiplist_test.cc @@ -238,14 +238,14 @@ class ConcurrentTest { current = MakeKey(K, 0); } else { current = iter.key(); - ASSERT_TRUE(IsValidKey(current)) << std::hex << current; + ASSERT_TRUE(IsValidKey(current)) << current; } ASSERT_LE(pos, current) << "should not go backwards"; // Verify that everything in [pos,current) was not present in // initial_state. while (pos < current) { - ASSERT_LT(key(pos), K) << std::hex << pos; + ASSERT_LT(key(pos), K) << pos; // Note that generation 0 is never inserted, so it is ok if // <*,0,*> is missing. diff --git a/db/version_edit.cc b/db/version_edit.cc index 3941271..f6b9e9c 100644 --- a/db/version_edit.cc +++ b/db/version_edit.cc @@ -20,7 +20,7 @@ enum Tag { kDeletedFile = 6, kNewFile = 7, // 8 was used for large value refs - kPrevLogNumber = 9, + kPrevLogNumber = 9 }; void VersionEdit::Clear() { diff --git a/db/version_set.cc b/db/version_set.cc index 816f189..62bd6dd 100644 --- a/db/version_set.cc +++ b/db/version_set.cc @@ -434,9 +434,14 @@ class VersionSet::Builder { ~Builder() { for (int level = 0; level < config::kNumLevels; level++) { - std::vector to_unref(levels_[level].added_files->begin(), - levels_[level].added_files->end()); - delete levels_[level].added_files; + const FileSet* added = levels_[level].added_files; + std::vector to_unref; + to_unref.reserve(added->size()); + for (FileSet::const_iterator it = added->begin(); + it != added->end(); ++it) { + to_unref.push_back(*it); + } + delete added; for (int i = 0; i < to_unref.size(); i++) { FileMetaData* f = to_unref[i]; f->refs--; diff --git a/include/leveldb/options.h b/include/leveldb/options.h index a0afbf2..0d4f6cd 100644 --- a/include/leveldb/options.h +++ b/include/leveldb/options.h @@ -23,7 +23,7 @@ enum CompressionType { // NOTE: do not change the values of existing entries, as these are // part of the persistent format on disk. kNoCompression = 0x0, - kSnappyCompression = 0x1, + kSnappyCompression = 0x1 }; // Options to control the behavior of a database (passed to DB::Open) diff --git a/include/leveldb/status.h b/include/leveldb/status.h index 6796fdd..8fe4442 100644 --- a/include/leveldb/status.h +++ b/include/leveldb/status.h @@ -72,7 +72,7 @@ class Status { kCorruption = 2, kNotSupported = 3, kInvalidArgument = 4, - kIOError = 5, + kIOError = 5 }; Code code() const { diff --git a/port/atomic_pointer.h b/port/atomic_pointer.h index 7659840..c618778 100644 --- a/port/atomic_pointer.h +++ b/port/atomic_pointer.h @@ -48,8 +48,9 @@ namespace port { // http://msdn.microsoft.com/en-us/library/ms684208(v=vs.85).aspx #define LEVELDB_HAVE_MEMORY_BARRIER -// Gcc on x86 -#elif defined(__GNUC__) && defined(ARCH_CPU_X86_FAMILY) +// Gcc and Sun Studio on x86 +#elif defined(ARCH_CPU_X86_FAMILY) && \ + (defined(__GNUC__) || defined(__SUNPRO_CC)) inline void MemoryBarrier() { // See http://gcc.gnu.org/ml/gcc/2003-04/msg01180.html for a discussion on // this idiom. Also see http://en.wikipedia.org/wiki/Memory_ordering. diff --git a/table/table_test.cc b/table/table_test.cc index 10d08fc..c69a386 100644 --- a/table/table_test.cc +++ b/table/table_test.cc @@ -5,6 +5,7 @@ #include "leveldb/table.h" #include +#include #include "db/dbformat.h" #include "db/memtable.h" #include "db/write_batch_internal.h" @@ -25,7 +26,11 @@ namespace leveldb { // Used to test non-lexicographic comparators. static std::string Reverse(const Slice& key) { std::string str(key.ToString()); - std::string rev(str.rbegin(), str.rend()); + std::string rev(""); + for (std::string::reverse_iterator rit = str.rbegin(); + rit != str.rend(); ++rit) { + rev.push_back(*rit); + } return rev; } @@ -411,7 +416,7 @@ enum TestType { TABLE_TEST, BLOCK_TEST, MEMTABLE_TEST, - DB_TEST, + DB_TEST }; struct TestArgs { diff --git a/util/comparator.cc b/util/comparator.cc index cc2b263..2d7544d 100644 --- a/util/comparator.cc +++ b/util/comparator.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. See the AUTHORS file for names of contributors. +#include #include #include "leveldb/comparator.h" #include "leveldb/slice.h"