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