urbackup_backend/urbackupserver/FileIndex.h
2016-02-01 16:56:03 +01:00

164 lines
4.1 KiB
C++

#pragma once
#include "../Interface/Database.h"
#include "../Interface/Types.h"
#include "../Interface/Mutex.h"
#include "../Interface/Condition.h"
#include "../Interface/Thread.h"
#include <memory.h>
#include "../stringtools.h"
#include <assert.h>
const size_t bytes_in_index = 16;
class FileIndex : public IThread
{
public:
typedef db_results(*get_data_callback_t)(size_t, size_t, void *userdata);
#pragma pack(1)
class SIndexKey
{
public:
SIndexKey(const char thash[bytes_in_index], int64 pfilesize, int pclientid)
: filesize(big_endian(pfilesize)), clientid(big_endian(pclientid))
{
assert(pfilesize>=0);
assert(pclientid>=0);
memcpy(hash, thash, bytes_in_index);
}
SIndexKey(const char thash[bytes_in_index], int64 pfilesize)
: filesize(big_endian(pfilesize)), clientid(0)
{
assert(pfilesize>=0);
memcpy(hash, thash, bytes_in_index);
}
SIndexKey(void)
: filesize(0), clientid(0)
{
memset(hash, 0, bytes_in_index);
}
void operator=(const SIndexKey& other)
{
memcpy(hash, other.hash, bytes_in_index);
filesize=other.filesize;
clientid=other.clientid;
}
bool operator==(const SIndexKey& other) const
{
return memcmp(hash, other.hash, bytes_in_index)==0 && filesize==other.filesize
&& clientid==other.clientid;
}
bool operator!=(const SIndexKey& other) const
{
return !(*this==other);
}
bool operator<(const SIndexKey& other) const
{
int mres=memcmp(this, &other, sizeof(SIndexKey));
return mres<0;
}
bool isEqualWithoutClientid(const SIndexKey& other) const
{
return memcmp(hash, other.hash, bytes_in_index)==0 && filesize==other.filesize;
}
const char* getHash() const
{
return hash;
}
int64 getFilesize() const
{
return big_endian(filesize);
}
int getClientid() const
{
return big_endian(clientid);
}
private:
char hash[bytes_in_index];
int64 filesize;
int clientid;
};
#pragma pack()
virtual ~FileIndex(void) {};
virtual bool has_error(void)=0;
virtual void create(get_data_callback_t get_data_callback, void *userdata)=0;
virtual int64 get(const SIndexKey& key)=0;
virtual int64 get_any_client(const SIndexKey& key) = 0;
virtual int64 get_prefer_client(const SIndexKey& key) = 0;
virtual std::map<int, int64> get_all_clients(const SIndexKey& key) = 0;
virtual void start_transaction(void)=0;
virtual void put(const SIndexKey& key, int64 value)=0;
static void put_delayed(const SIndexKey& key, int64 value);
virtual int64 get_with_cache(const SIndexKey& key);
virtual int64 get_with_cache_exact(const SIndexKey& key);
virtual std::map<int, int64> get_all_clients_with_cache(const SIndexKey& key, bool with_del);
virtual int64 get_with_cache_prefer_client(const SIndexKey& key);
virtual void del(const SIndexKey& key)=0;
static void del_delayed(const SIndexKey& key);
virtual void commit_transaction(void)=0;
virtual void start_iteration()=0;
virtual std::map<int, int64> get_next_entries_iteration(bool& has_next)=0;
virtual void stop_iteration()=0;
void operator()(void);
static void shutdown();
static void flush();
static void stop_accept();
private:
bool get_from_cache( const FileIndex::SIndexKey &key, const std::map<SIndexKey, int64>& cache, int64& res );
bool get_from_cache_prefer_client( const SIndexKey &key, const std::map<SIndexKey, int64>& cache, int64& res);
bool get_from_cache_exact( const SIndexKey& key, const std::map<SIndexKey, int64>& cache, int64& res );
void get_from_cache_all_clients( const SIndexKey &key, const std::map<SIndexKey, int64>& cache, std::map<int, int64> &ret );
static std::map<SIndexKey, int64> cache_buffer_1;
static std::map<SIndexKey, int64> cache_buffer_2;
static std::map<SIndexKey, int64>* active_cache_buffer;
static std::map<SIndexKey, int64>* other_cache_buffer;
static std::map<SIndexKey, bool> del_buffer;
static IMutex *mutex;
static ICondition *cond;
static bool do_shutdown;
static bool do_flush;
static bool do_accept;
};