36a5f8ed7f
- Replace raw slice comparison with a call to user comparator. Added test for custom comparators. - Fix end of namespace comments. - Fixed bug in picking inputs for a level-0 compaction. When finding overlapping files, the covered range may expand as files are added to the input set. We now correctly expand the range when this happens instead of continuing to use the old range. For example, suppose L0 contains files with the following ranges: F1: a .. d F2: c .. g F3: f .. j and the initial compaction target is F3. We used to search for range f..j which yielded {F2,F3}. However we now expand the range as soon as another file is added. In this case, when F2 is added, we expand the range to c..j and restart the search. That picks up file F1 as well. This change fixes a bug related to deleted keys showing up incorrectly after a compaction as described in Issue 44. (Sync with upstream @25072954)
157 lines
3.6 KiB
C++
157 lines
3.6 KiB
C++
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
|
|
// 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.
|
|
//
|
|
// See port_example.h for documentation for the following types/functions.
|
|
|
|
#ifndef STORAGE_LEVELDB_PORT_PORT_ANDROID_H_
|
|
#define STORAGE_LEVELDB_PORT_PORT_ANDROID_H_
|
|
|
|
#include <endian.h>
|
|
#include <pthread.h>
|
|
#include <stdint.h>
|
|
#include <cstdatomic>
|
|
#include <string>
|
|
#include <cctype>
|
|
|
|
// Collapse the plethora of ARM flavors available to an easier to manage set
|
|
// Defs reference is at https://wiki.edubuntu.org/ARM/Thumb2PortingHowto
|
|
#if defined(__ARM_ARCH_6__) || \
|
|
defined(__ARM_ARCH_6J__) || \
|
|
defined(__ARM_ARCH_6K__) || \
|
|
defined(__ARM_ARCH_6Z__) || \
|
|
defined(__ARM_ARCH_6T2__) || \
|
|
defined(__ARM_ARCH_6ZK__) || \
|
|
defined(__ARM_ARCH_7__) || \
|
|
defined(__ARM_ARCH_7R__) || \
|
|
defined(__ARM_ARCH_7A__)
|
|
#define ARMV6_OR_7 1
|
|
#endif
|
|
|
|
extern "C" {
|
|
size_t fread_unlocked(void *a, size_t b, size_t c, FILE *d);
|
|
size_t fwrite_unlocked(const void *a, size_t b, size_t c, FILE *d);
|
|
int fflush_unlocked(FILE *f);
|
|
int fdatasync (int fd);
|
|
}
|
|
|
|
namespace leveldb {
|
|
namespace port {
|
|
|
|
static const bool kLittleEndian = __BYTE_ORDER == __LITTLE_ENDIAN;
|
|
|
|
class CondVar;
|
|
|
|
class Mutex {
|
|
public:
|
|
Mutex();
|
|
~Mutex();
|
|
|
|
void Lock();
|
|
void Unlock();
|
|
void AssertHeld() {
|
|
//TODO(gabor): How can I implement this?
|
|
}
|
|
|
|
private:
|
|
friend class CondVar;
|
|
pthread_mutex_t mu_;
|
|
|
|
// No copying
|
|
Mutex(const Mutex&);
|
|
void operator=(const Mutex&);
|
|
};
|
|
|
|
class CondVar {
|
|
public:
|
|
explicit CondVar(Mutex* mu);
|
|
~CondVar();
|
|
void Wait();
|
|
void Signal();
|
|
void SignalAll();
|
|
private:
|
|
Mutex* mu_;
|
|
pthread_cond_t cv_;
|
|
};
|
|
|
|
#ifndef ARMV6_OR_7
|
|
// On ARM chipsets <V6, 0xffff0fa0 is the hard coded address of a
|
|
// memory barrier function provided by the kernel.
|
|
typedef void (*LinuxKernelMemoryBarrierFunc)(void);
|
|
LinuxKernelMemoryBarrierFunc pLinuxKernelMemoryBarrier ATTRIBUTE_WEAK =
|
|
(LinuxKernelMemoryBarrierFunc) 0xffff0fa0;
|
|
#endif
|
|
|
|
// Storage for a lock-free pointer
|
|
class AtomicPointer {
|
|
private:
|
|
void* rep_;
|
|
|
|
inline void MemoryBarrier() const {
|
|
// TODO(gabor): This only works on Android instruction sets >= V6
|
|
#ifdef ARMV6_OR_7
|
|
__asm__ __volatile__("dmb" : : : "memory");
|
|
#else
|
|
pLinuxKernelMemoryBarrier();
|
|
#endif
|
|
}
|
|
|
|
public:
|
|
AtomicPointer() { }
|
|
explicit AtomicPointer(void* v) : rep_(v) { }
|
|
inline void* Acquire_Load() const {
|
|
void* r = rep_;
|
|
MemoryBarrier();
|
|
return r;
|
|
}
|
|
inline void Release_Store(void* v) {
|
|
MemoryBarrier();
|
|
rep_ = v;
|
|
}
|
|
inline void* NoBarrier_Load() const {
|
|
void* r = rep_;
|
|
return r;
|
|
}
|
|
inline void NoBarrier_Store(void* v) {
|
|
rep_ = v;
|
|
}
|
|
};
|
|
|
|
// TODO(gabor): Implement compress
|
|
inline bool Snappy_Compress(
|
|
const char* input,
|
|
size_t input_length,
|
|
std::string* output) {
|
|
return false;
|
|
}
|
|
|
|
// TODO(gabor): Implement uncompress
|
|
inline bool Snappy_GetUncompressedLength(const char* input, size_t length,
|
|
size_t* result) {
|
|
return false;
|
|
}
|
|
|
|
// TODO(gabor): Implement uncompress
|
|
inline bool Snappy_Uncompress(
|
|
const char* input_data,
|
|
size_t input_length,
|
|
char* output) {
|
|
return false;
|
|
}
|
|
|
|
inline uint64_t ThreadIdentifier() {
|
|
pthread_t tid = pthread_self();
|
|
uint64_t r = 0;
|
|
memcpy(&r, &tid, sizeof(r) < sizeof(tid) ? sizeof(r) : sizeof(tid));
|
|
return r;
|
|
}
|
|
|
|
inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) {
|
|
return false;
|
|
}
|
|
|
|
} // namespace port
|
|
} // namespace leveldb
|
|
|
|
#endif // STORAGE_LEVELDB_PORT_PORT_ANDROID_H_
|