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