1 #ifndef NETCACHE__SYNC_LOG__HPP 2 #define NETCACHE__SYNC_LOG__HPP 3 4 /* $Id: sync_log.hpp 466300 2015-04-30 18:14:53Z gouriano $ 5 * =========================================================================== 6 * 7 * PUBLIC DOMAIN NOTICE 8 * National Center for Biotechnology Information 9 * 10 * This software/database is a "United States Government Work" under the 11 * terms of the United States Copyright Act. It was written as part of 12 * the author's official duties as a United States Government employee and 13 * thus cannot be copyrighted. This software/database is freely available 14 * to the public for use. The National Library of Medicine and the U.S. 15 * Government have not placed any restriction on its use or reproduction. 16 * 17 * Although all reasonable efforts have been taken to ensure the accuracy 18 * and reliability of the software and data, the NLM and the U.S. 19 * Government do not and cannot warrant the performance or results that 20 * may be obtained by using this software or data. The NLM and the U.S. 21 * Government disclaim all warranties, express or implied, including 22 * warranties of performance, merchantability or fitness for any particular 23 * purpose. 24 * 25 * Please cite the author in any work or product based on this material. 26 * 27 * =========================================================================== 28 * 29 * Authors: Denis Vakatov, Pavel Ivanov, Sergey Satskiy 30 * 31 * File Description: Data structures and API to support blobs replication. 32 * 33 */ 34 35 36 37 38 BEGIN_NCBI_SCOPE 39 40 41 /// Event types to log 42 enum ENCSyncEvent 43 { 44 eSyncWrite, //< Blob write event 45 eSyncProlong, //< Blob life time prolongation event 46 eSyncUpdate, //< blob changed notification 47 eSyncRemove, //< blob removal request 48 }; 49 50 /// Single event record 51 struct SNCSyncEvent 52 { 53 Uint8 rec_no; //< Local event sequential number. 54 Uint8 blob_size; //< blob size 55 CNCBlobKeyLight key; //< Blob key. 56 ENCSyncEvent event_type;//< Event type (write, remove, prolong). 57 Uint8 orig_time; //< Timestamp of the event when 58 //< it originated by client. 59 Uint8 orig_server; //< The server where event has 60 //< been originated. 61 Uint8 orig_rec_no; //< Record number on the host where the 62 //< event was originated. 63 Uint8 local_time; //< Timestamp when the record was 64 //< recorded locally. 65 SNCSyncEventSNCSyncEvent66 SNCSyncEvent(void) 67 : rec_no(0), blob_size(0), event_type(eSyncWrite), orig_time(0), orig_server(0), orig_rec_no(0), local_time(0) 68 { 69 } isOlderSNCSyncEvent70 bool isOlder(const SNCSyncEvent& other) const 71 { 72 if (orig_time != other.orig_time) 73 return orig_time < other.orig_time; 74 75 // Timestamp matched, is that were on the same host? 76 if (orig_server == other.orig_server) 77 return orig_rec_no < other.orig_rec_no; 78 79 if (event_type == eSyncWrite && other.event_type != eSyncWrite) 80 return false; 81 if (other.event_type == eSyncWrite && event_type != eSyncWrite) 82 return true; 83 84 // No way to detect, return true 85 return orig_server < other.orig_server; 86 } 87 }; 88 89 90 // Events container - local time ordered 91 typedef list<SNCSyncEvent*> TSyncEvents; 92 93 // Reduced events container for fast search 94 struct SBlobEvent 95 { 96 // One of the fields is always filled 97 SNCSyncEvent* wr_or_rm_event; 98 SNCSyncEvent* prolong_event; 99 SBlobEventSBlobEvent100 SBlobEvent() : 101 wr_or_rm_event(NULL), prolong_event(NULL) 102 {} 103 getMaxRecNoWithinTimeLimitSBlobEvent104 Uint8 getMaxRecNoWithinTimeLimit(Uint8 limit) const 105 { 106 if (prolong_event != NULL && prolong_event->local_time < limit) 107 return prolong_event->rec_no; 108 if (wr_or_rm_event != NULL && wr_or_rm_event->local_time < limit) 109 return wr_or_rm_event->rec_no; 110 return 0; 111 } 112 }; 113 typedef map<string, SBlobEvent> TReducedSyncEvents; 114 115 116 class CNCSyncLog 117 { 118 public: 119 static void Initialize(bool need_read_saved, Uint8 start_log_rec_no); 120 121 // Save the log records to the file_name 122 // Return: true if written successfully 123 // It does not free the memory occupied by records 124 // because it is called when the process exits. 125 static bool Finalize(void); 126 127 // The memory ownership is transferred to CNCSyncLog. 128 // CNCSynclog fills id and the local_time fields. 129 // The id field value is returned. 130 // Must be thread safe. 131 static Uint8 AddEvent(Uint2 slot, SNCSyncEvent* event); 132 133 // Provides the last successful synchronized record numbers 134 // for the given server. 135 // If the server is unknown 0s are provided. 136 // local_synced_rec_id is filled with the last record number till 137 // which the remote server is synchronized 138 // remote_synced_rec_id is filled with the last record number till 139 // which the local server is synchronized 140 static void GetLastSyncedRecNo(Uint8 server, 141 Uint2 slot, 142 Uint8* local_synced_rec_no, 143 Uint8* remote_synced_rec_no); 144 145 // Saves the last synchronized record ids for the given server. 146 static void SetLastSyncRecNo(Uint8 server, 147 Uint2 slot, 148 Uint8 local_synced_rec_no, 149 Uint8 remote_synced_rec_no); 150 151 // Provides the local last created sync log 152 static Uint8 GetCurrentRecNo(Uint2 slot); 153 static Uint8 GetLastRecNo(void); 154 155 // Provides the list of events which occurred for 156 // the given slot starting from local_start_rec_id - kSyncInterval. 157 // If the values of local_start_rec_id and remote_start_rec_id 158 // arguments do not match what is saved for the given server, 159 // then they are updated as the max value of the given and the 160 // stored before building the list of events. (The saved values are 161 // updated correspondingly). 162 // Fills the events container with matched events and 163 // returns false if the start_record_id is not available any more. 164 // The consequent writes and removes must be compressed. 165 // Must be thread safe. 166 static bool GetEventsList(Uint8 server, 167 Uint2 slot, 168 Uint8* local_start_rec_no, 169 Uint8* remote_start_rec_no, 170 TReducedSyncEvents* events ); 171 172 // Calculates the lists of operations for synchronization. 173 // The given start record ids are stored and basing on them 174 // the intervals for analysis are identified in the local log and 175 // in the given remote events log. 176 // The local interval is compressed because a compressed one is 177 // received from the remote host. 178 // Then the local events range to analyze is defined as: 179 // [local_start_rec_id, now - kSyncInterval]. If the interval is 180 // negative then there are no sync operations. 181 // The remote interval for analysis is defined as: 182 // [remote_start_rec_id, now - kSyncInterval]. 183 // The local_synced_rec_id and remote_synced_rec_id are filled with 184 // the end of the corresponding analysis intervals. 185 // The return value is false if the given local_start_rec_id is not 186 // available any more. (there are no operations in this case) 187 static bool GetSyncOperations(Uint8 server, 188 Uint2 slot, 189 Uint8 local_start_rec_no, 190 Uint8 remote_start_rec_no, 191 const TReducedSyncEvents& remote_events, 192 TSyncEvents* events_to_get, 193 TSyncEvents* events_to_send, 194 Uint8* local_synced_rec_no, 195 Uint8* remote_synced_rec_no ); 196 197 static Uint8 Clean(Uint2 slot); 198 199 // Provides the total number of records in the log 200 static Uint8 GetLogSize(void); 201 static Uint8 GetLogSize(Uint2 slot); 202 203 static bool IsOverLimit(Uint2 slot); 204 }; 205 206 END_NCBI_SCOPE 207 208 209 #endif /* NETCACHE__SYNC_LOG__HPP */ 210 211