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