Fixed issue #507: Help Spell error and push wrongly link to sync
[TortoiseGit.git] / src / TortoiseProc / GitLogCache.cpp
blob0ba88b94a745b9a7428bc53ea52813ef091d1caa
1 #include "stdafx.h"
2 #include "GitLogCache.h"
4 CLogCache::CLogCache()
9 CLogCache::~CLogCache()
11 //this->m_IndexFile.Close();
12 //this->m_DataFile.Close();
14 int CLogCache::AddCacheEntry(GitRev &Rev)
16 this->m_HashMap[Rev.m_CommitHash] = Rev;
17 return 0;
20 GitRev * CLogCache::GetCacheData(CGitHash &hash)
22 if(this->m_HashMapIndex.find(hash)==m_HashMapIndex.end())
24 if(this->m_HashMap.IsExist(hash))
26 return &m_HashMap[hash];
28 m_HashMap[hash].m_CommitHash=hash;
29 return &m_HashMap[hash];
31 else
33 GitRev rev;
34 if(!LoadOneItem(rev,m_HashMapIndex[hash]))
36 m_HashMap[hash].CopyFrom(rev);
37 m_HashMap[hash].m_IsFull=true;
39 return &m_HashMap[hash];
42 m_HashMap[hash].m_CommitHash=hash;
43 return &m_HashMap[hash];
45 int CLogCache::FetchCacheIndex(CString GitDir)
48 if(this->m_IndexFile.m_hFile == CFile::hFileNull)
50 BOOL b=m_IndexFile.Open(GitDir+_T("\\.git\\")+INDEX_FILE_NAME,
51 CFile::modeRead|CFile::shareDenyNone|
52 CFile::modeNoTruncate|CFile::modeCreate);
53 if(!b)
54 return -1;
56 //Cache has been fetched.
57 //if(m_GitDir == GitDir)
58 // return 0;
60 m_GitDir=GitDir;
61 m_IndexFile.SeekToBegin();
63 SLogCacheIndexHeader header;
64 UINT count=m_IndexFile.Read(&header,sizeof(SLogCacheIndexHeader));
65 if(count != sizeof(SLogCacheIndexHeader))
66 return -2;
68 if( header.m_Magic != LOG_INDEX_MAGIC )
69 return -3;
71 if( header.m_Version != LOG_INDEX_VERSION )
72 return -4;
75 SLogCacheItem Item;
77 //for(int i=0;i<header.m_ItemCount;i++)
78 this->m_HashMapIndex.clear();
80 while(1)
82 count=m_IndexFile.Read(&Item,sizeof(SLogCacheItem));
83 if( count != sizeof(SLogCacheItem) )
84 break;
86 this->m_HashMapIndex[Item.m_Hash]=Item.m_Offset;
89 return 0;
92 int CLogCache::SaveOneItem(GitRev &Rev,ULONGLONG offset)
95 SLogCacheRevItemHeader header;
96 m_DataFile.Seek(offset,CFile::begin);
98 if(this->m_DataFile.m_hFile == CFile::hFileNull)
100 BOOL b=m_DataFile.Open(m_GitDir+_T("\\.git\\")+INDEX_FILE_NAME,
101 CFile::modeRead|CFile::shareDenyNone|
102 CFile::modeNoTruncate|CFile::modeCreate);
103 if(!b)
104 return -1;
107 header.m_Magic=LOG_DATA_ITEM_MAGIC;
108 header.m_Version=LOG_INDEX_VERSION;
109 header.m_FileCount=Rev.m_Files.GetCount();
111 m_DataFile.Write(&header,sizeof(SLogCacheRevItemHeader));
113 CArchive ar(&m_DataFile, CArchive::store);
115 ar<<Rev.m_AuthorName;
116 ar<<Rev.m_AuthorEmail;
117 ar<<Rev.m_AuthorDate;
118 ar<<Rev.m_CommitterName;
119 ar<<Rev.m_CommitterEmail;
120 ar<<Rev.m_CommitterDate;
121 ar<<Rev.m_Subject;
122 ar<<Rev.m_Body;
123 ar<<Rev.m_CommitHash;
124 ar<<Rev.m_Action;
126 for(int i=0;i<Rev.m_Files.GetCount();i++)
128 SLogCacheRevFileHeader header;
129 header.m_Magic=LOG_DATA_FILE_MAGIC;
130 header.m_Version=LOG_INDEX_VERSION;
132 ar<<header.m_Magic;
133 ar<<header.m_Version;
134 ar<<Rev.m_Files[i].GetGitPathString();
135 ar<<Rev.m_Files[i].GetGitOldPathString();
136 ar<<Rev.m_Files[i].m_Action;
137 ar<<Rev.m_Files[i].m_Stage;
138 ar<<Rev.m_Files[i].m_StatAdd;
139 ar<<Rev.m_Files[i].m_StatDel;
142 return 0;
145 int CLogCache::LoadOneItem(GitRev &Rev,ULONGLONG offset)
147 SLogCacheRevItemHeader header;
149 if(this->m_DataFile.m_hFile == CFile::hFileNull)
151 BOOL b=m_DataFile.Open(m_GitDir+_T("\\.git\\")+DATA_FILE_NAME,
152 CFile::modeRead|CFile::shareDenyNone|
153 CFile::modeNoTruncate|CFile::modeCreate);
154 if(!b)
155 return -1;
157 m_DataFile.Seek(offset,CFile::begin);
159 UINT count=m_DataFile.Read(&header,sizeof(SLogCacheRevItemHeader));
160 if( count != sizeof(SLogCacheRevItemHeader))
161 return -1;
162 if( !CheckHeader(header))
163 return -2;
166 CArchive ar(&m_DataFile, CArchive::load);
168 ar>>Rev.m_AuthorName;
169 ar>>Rev.m_AuthorEmail;
170 ar>>Rev.m_AuthorDate;
171 ar>>Rev.m_CommitterName;
172 ar>>Rev.m_CommitterEmail;
173 ar>>Rev.m_CommitterDate;
174 ar>>Rev.m_Subject;
175 ar>>Rev.m_Body;
176 ar>>Rev.m_CommitHash;
177 ar>>Rev.m_Action;
179 Rev.m_Files.Clear();
181 for(int i=0;i<header.m_FileCount;i++)
183 CTGitPath path;
184 CString file,oldfile;
185 path.Reset();
186 SLogCacheRevFileHeader header;
188 ar>>header.m_Magic;
189 ar>>header.m_Version;
191 if( this->CheckHeader(header) )
192 return -1;
193 ar>>file;
194 ar>>oldfile;
195 path.SetFromGit(file,&oldfile);
197 ar>>path.m_Action;
198 ar>>path.m_Stage;
199 ar>>path.m_StatAdd;
200 ar>>path.m_StatDel;
203 Rev.m_Files.AddPath(path);
205 return 0;
207 int CLogCache::RebuildCacheFile()
209 m_IndexFile.SetLength(0);
210 m_DataFile.SetLength(0);
212 SLogCacheIndexHeader header;
213 header.m_Magic=LOG_INDEX_MAGIC;
214 header.m_Version=LOG_INDEX_VERSION;
215 m_IndexFile.SeekToBegin();
216 m_IndexFile.Write(&header,sizeof(SLogCacheIndexHeader));
220 SLogCacheRevFileHeader header;
221 header.m_Magic=LOG_DATA_MAGIC;
222 header.m_Version=LOG_INDEX_VERSION;
224 m_DataFile.SeekToBegin();
225 m_DataFile.Write(&header,sizeof(SLogCacheRevFileHeader));
227 return 0;
229 int CLogCache::SaveCache()
231 if( this->m_HashMap.size() == 0 )
232 return 0;
234 if( this->m_GitDir.IsEmpty())
235 return 0;
237 bool bIsRebuild=false;
238 if(this->m_DataFile.m_hFile != CFile::hFileNull)
239 m_DataFile.Close();
240 if(this->m_IndexFile.m_hFile!=CFile::hFileNull)
241 m_IndexFile.Close();
243 if(this->m_IndexFile.m_hFile == CFile::hFileNull)
245 BOOL b=m_IndexFile.Open(m_GitDir+_T("\\.git\\")+INDEX_FILE_NAME,
246 CFile::modeReadWrite|CFile::shareDenyWrite|
247 CFile::modeNoTruncate|CFile::modeCreate);
248 if(!b)
249 return -1;
252 if(this->m_DataFile.m_hFile == CFile::hFileNull)
254 BOOL b=m_DataFile.Open(m_GitDir+_T("\\.git\\")+DATA_FILE_NAME,
255 CFile::modeReadWrite|CFile::shareDenyWrite|
256 CFile::modeNoTruncate|CFile::modeCreate);
259 if(!b)
261 m_IndexFile.Close();
262 return -1;
267 SLogCacheIndexHeader header;
268 memset(&header,0,sizeof(SLogCacheIndexHeader));
269 UINT count=m_IndexFile.Read(&header,sizeof(SLogCacheIndexHeader));
270 if(count != sizeof(SLogCacheIndexHeader) || !this->CheckHeader(header))
271 {// new file
272 RebuildCacheFile();
273 bIsRebuild=true;
279 SLogCacheRevFileHeader header;
281 UINT count=m_DataFile.Read(&header,sizeof(SLogCacheRevFileHeader));
282 if( count != sizeof(SLogCacheRevFileHeader) || !CheckHeader(header))
284 RebuildCacheFile();
285 bIsRebuild=true;
290 m_DataFile.SeekToEnd();
291 m_IndexFile.SeekToEnd();
292 CGitHashMap::iterator i;
293 for(i=m_HashMap.begin();i!=m_HashMap.end();i++)
295 if(this->m_HashMapIndex.find((*i).second.m_CommitHash) == m_HashMapIndex.end() || bIsRebuild)
297 if((*i).second.m_IsFull && !(*i).second.m_CommitHash.IsEmpty())
299 ULONGLONG offset = m_DataFile.GetPosition();
300 this->SaveOneItem((*i).second,offset);
302 SLogCacheItem item;
303 item.m_Hash = (*i).second.m_CommitHash;
304 item.m_Offset=offset;
306 m_IndexFile.Write(&item,sizeof(SLogCacheItem));
310 m_IndexFile.Close();
311 m_DataFile.Close();
312 return 0;
315 int CLogCache::ClearAllParent()
317 CGitHashMap::iterator i;
318 for(i=m_HashMap.begin();i!=m_HashMap.end();i++)
320 (*i).second.m_ParentHash.clear();
321 (*i).second.m_Lanes.clear();
323 return 0;