00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __FILE_H__
00012 #define __FILE_H__
00013
00014 #include "sync.h"
00015
00016 #if defined(REPLICATION_SUPPORT)
00017 const int dbModMapBlockBits = 12;
00018 const int dbModMapBlockSize = 1 << dbModMapBlockBits;
00019 #elif defined(NO_MMAP)
00020 const int dbModMapBlockBits = 12;
00021 const int dbModMapBlockSize = 1 << dbModMapBlockBits;
00022 #endif
00023
00024 #ifdef REPLICATION_SUPPORT
00025
00026 class dbFile;
00027 class dbReplicatedDatabase;
00028 class socket_t;
00029
00030 struct ReplicationRequest {
00031 enum {
00032 RR_CONNECT,
00033 RR_RECOVERY,
00034 RR_GET_STATUS,
00035 RR_STATUS,
00036 RR_UPDATE_PAGE,
00037 RR_NEW_ACTIVE_NODE,
00038 RR_CLOSE,
00039 RR_READY
00040 };
00041 byte op;
00042 byte nodeId;
00043 byte status;
00044 int size;
00045 struct {
00046 int updateCount;
00047 int offs;
00048 } page;
00049 };
00050
00051 struct RecoveryRequest {
00052 dbFile* file;
00053 int nodeId;
00054 int nPages;
00055 int* updateCounters;
00056 };
00057 #endif
00058
00059
00060 class dbFile {
00061 protected:
00062 #ifdef _WIN32
00063 HANDLE fh;
00064 HANDLE mh;
00065 #else
00066 #ifdef USE_SYSV_SHARED_MEMORY
00067 dbSharedMemory shmem;
00068 #endif
00069 int fd;
00070 #endif
00071 char* sharedName;
00072 char* mmapAddr;
00073 size_t mmapSize;
00074
00075 public:
00076 enum {
00077 ok = 0
00078 };
00079
00080
00081
00082 int create(char const* name, bool noBuffering = true);
00083
00084
00085
00086 int open(char const* fileName, char const* sharedName,
00087 bool readonly, size_t initSize, bool replicationSupport);
00088
00089 void* getAddr() const { return mmapAddr; }
00090 size_t getSize() const { return mmapSize; }
00091 int setSize(size_t size, char const* sharedName, bool initialize = true);
00092 int flush(bool physical = false);
00093 int close();
00094 int erase();
00095 int write(void const* ptr, size_t& writtenBytes, size_t size);
00096 int read(void* ptr, size_t& readBytes, size_t size);
00097 bool write(void const* ptr, size_t size);
00098
00099 static char* errorText(int code, char* buf, size_t bufSize);
00100
00101 #if defined(NO_MMAP) || defined(REPLICATION_SUPPORT)
00102 void markAsDirty(size_t pos, size_t size) {
00103 size_t page = pos >> dbModMapBlockBits;
00104 size_t last = (pos + size + dbModMapBlockSize - 1) >> dbModMapBlockBits;
00105 assert(int(last >> 5) <= pageMapSize);
00106 while (page < last) {
00107 pageMap[page >> 5] |= 1 << (page & 31);
00108 page += 1;
00109 }
00110 }
00111
00112 private:
00113 int* pageMap;
00114 int pageMapSize;
00115 int pageSize;
00116 public:
00117 int updateCounter;
00118
00119 #ifdef REPLICATION_SUPPORT
00120 int* currUpdateCount;
00121 int* diskUpdateCount;
00122 byte* rootPage;
00123 bool doSync;
00124 bool closing;
00125
00126 dbReplicatedDatabase* db;
00127
00128 int getUpdateCountTableSize();
00129 int getMaxPages();
00130
00131 dbMutex replCS;
00132 dbMutex syncCS;
00133
00134 dbThread syncThread;
00135 dbLocalEvent syncEvent;
00136 dbLocalEvent recoveredEvent;
00137 int nRecovered;
00138
00139 static int dbSyncTimeout;
00140
00141 #ifdef _WIN32
00142 HANDLE cfh;
00143 HANDLE cmh;
00144 #else
00145 int cfd;
00146 #endif
00147
00148 static void thread_proc startSyncToDisk(void* arg);
00149 static void thread_proc startRecovery(void* arg);
00150
00151
00152 void doRecovery(int nodeId, int* updateCounters, int nPages);
00153
00154 void syncToDisk();
00155 void startSync();
00156 void stopSync();
00157
00158 public:
00159 void configure(dbReplicatedDatabase* db) {
00160 this->db = db;
00161 }
00162
00163 bool updatePages(socket_t* s, size_t pos, int updateCount, int size);
00164 bool concurrentUpdatePages(socket_t* s, size_t pos, int updateCount, int size);
00165 void recovery(int nodeId, int* updateCounters, int nPages);
00166 #endif
00167
00168 #else
00169 void markAsDirty(size_t, size_t) {}
00170 #endif
00171
00172 dbFile();
00173 };
00174
00175
00176 #endif
00177