• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "config.h"
27 #include "LevelDBDatabase.h"
28 
29 #if ENABLE(LEVELDB)
30 
31 #include "LevelDBComparator.h"
32 #include "LevelDBIterator.h"
33 #include "LevelDBSlice.h"
34 #include <leveldb/comparator.h>
35 #include <leveldb/db.h>
36 #include <leveldb/slice.h>
37 #include <string>
38 #include <wtf/PassOwnPtr.h>
39 #include <wtf/text/CString.h>
40 #include <wtf/text/WTFString.h>
41 
42 namespace WebCore {
43 
makeSlice(const Vector<char> & value)44 static leveldb::Slice makeSlice(const Vector<char>& value)
45 {
46     return leveldb::Slice(value.data(), value.size());
47 }
48 
makeSlice(const LevelDBSlice & s)49 static leveldb::Slice makeSlice(const LevelDBSlice& s)
50 {
51     return leveldb::Slice(s.begin(), s.end() - s.begin());
52 }
53 
makeLevelDBSlice(const leveldb::Slice & s)54 static LevelDBSlice makeLevelDBSlice(const leveldb::Slice& s)
55 {
56     return LevelDBSlice(s.data(), s.data() + s.size());
57 }
58 
makeVector(const std::string & s)59 static Vector<char> makeVector(const std::string& s)
60 {
61     Vector<char> res;
62     res.append(s.c_str(), s.length());
63     return res;
64 }
65 
66 namespace {
67 class ComparatorAdapter : public leveldb::Comparator {
68 public:
ComparatorAdapter(const LevelDBComparator * comparator)69     ComparatorAdapter(const LevelDBComparator* comparator)
70         : m_comparator(comparator)
71     {
72     }
73 
Compare(const leveldb::Slice & a,const leveldb::Slice & b) const74     virtual int Compare(const leveldb::Slice& a, const leveldb::Slice& b) const
75     {
76         return m_comparator->compare(makeLevelDBSlice(a), makeLevelDBSlice(b));
77     }
78 
Name() const79     virtual const char* Name() const { return m_comparator->name(); }
80 
81     // FIXME: Support the methods below in the future.
FindShortestSeparator(std::string * start,const leveldb::Slice & limit) const82     virtual void FindShortestSeparator(std::string* start, const leveldb::Slice& limit) const { }
FindShortSuccessor(std::string * key) const83     virtual void FindShortSuccessor(std::string* key) const { }
84 
85 private:
86     const LevelDBComparator* m_comparator;
87 };
88 }
89 
LevelDBDatabase()90 LevelDBDatabase::LevelDBDatabase()
91     : m_db(0)
92 {
93 }
94 
~LevelDBDatabase()95 LevelDBDatabase::~LevelDBDatabase()
96 {
97 }
98 
open(const String & fileName,const LevelDBComparator * comparator)99 LevelDBDatabase* LevelDBDatabase::open(const String& fileName, const LevelDBComparator* comparator)
100 {
101     OwnPtr<ComparatorAdapter> comparatorAdapter(new ComparatorAdapter(comparator));
102 
103     LevelDBDatabase* result = new LevelDBDatabase();
104 
105     leveldb::Options options;
106     options.comparator = comparatorAdapter.get();
107     options.create_if_missing = true;
108     leveldb::DB* db;
109     leveldb::Status s = leveldb::DB::Open(options, fileName.utf8().data(), &db);
110 
111     if (!s.ok()) {
112         delete result;
113         return 0;
114     }
115 
116     result->m_db = WTF::adoptPtr(db);
117     result->m_comparatorAdapter = comparatorAdapter.release();
118 
119     return result;
120 }
121 
122 
put(const LevelDBSlice & key,const Vector<char> & value)123 bool LevelDBDatabase::put(const LevelDBSlice& key, const Vector<char>& value)
124 {
125     leveldb::WriteOptions writeOptions;
126     writeOptions.sync = false;
127 
128     return m_db->Put(writeOptions, makeSlice(key), makeSlice(value)).ok();
129 }
130 
remove(const LevelDBSlice & key)131 bool LevelDBDatabase::remove(const LevelDBSlice& key)
132 {
133     leveldb::WriteOptions writeOptions;
134     writeOptions.sync = false;
135 
136     return m_db->Delete(writeOptions, makeSlice(key)).ok();
137 }
138 
get(const LevelDBSlice & key,Vector<char> & value)139 bool LevelDBDatabase::get(const LevelDBSlice& key, Vector<char>& value)
140 {
141     std::string result;
142     if (!m_db->Get(leveldb::ReadOptions(), makeSlice(key), &result).ok())
143         return false;
144 
145     value = makeVector(result);
146     return true;
147 }
148 
newIterator()149 LevelDBIterator* LevelDBDatabase::newIterator()
150 {
151     leveldb::Iterator* i = m_db->NewIterator(leveldb::ReadOptions());
152     if (!i) // FIXME: Double check if we actually need to check this.
153         return 0;
154     return new LevelDBIterator(i);
155 }
156 
157 } // namespace WebCore
158 
159 #endif // ENABLE(LEVELDB)
160