#pragma once #include "../Interface/Database.h" #include "../Interface/Types.h" #include "../Interface/Mutex.h" #include "../Interface/Condition.h" #include "../Interface/Thread.h" #include #include "../stringtools.h" #include 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 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 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 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& cache, int64& res ); bool get_from_cache_prefer_client( const SIndexKey &key, const std::map& cache, int64& res); bool get_from_cache_exact( const SIndexKey& key, const std::map& cache, int64& res ); void get_from_cache_all_clients( const SIndexKey &key, const std::map& cache, std::map &ret ); static std::map cache_buffer_1; static std::map cache_buffer_2; static std::map* active_cache_buffer; static std::map* other_cache_buffer; static std::map del_buffer; static IMutex *mutex; static ICondition *cond; static bool do_shutdown; static bool do_flush; static bool do_accept; };