Merge branch 'master' of git://github.com/Jopie64/tortoisegit
[TortoiseGit.git] / src / TortoiseProc / GitLogCache.cpp
bloba167e0ac1587a28580c4d2616d9928bffc42f533
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_NewCacheEntry.push_back(Rev);
17 return 0;
20 int CLogCache::GetCacheData(GitRev &Rev)
22 if(this->m_HashMapIndex.find(Rev.m_CommitHash)==m_HashMapIndex.end())
24 for(int i=0;i<this->m_NewCacheEntry.size();i++)
26 if(m_NewCacheEntry[i].m_CommitHash==Rev.m_CommitHash)
28 Rev.CopyFrom(m_NewCacheEntry[i],true);
29 return 0;
32 return -1;
34 else
36 return LoadOneItem(Rev,m_HashMapIndex[Rev.m_CommitHash]);
38 return 0;
40 int CLogCache::FetchCacheIndex(CString GitDir)
43 if(this->m_IndexFile.m_hFile == CFile::hFileNull)
45 BOOL b=m_IndexFile.Open(GitDir+_T("\\.git\\")+INDEX_FILE_NAME,
46 CFile::modeRead|CFile::shareDenyNone|
47 CFile::modeNoTruncate|CFile::modeCreate);
48 if(!b)
49 return -1;
51 //Cache has been fetched.
52 //if(m_GitDir == GitDir)
53 // return 0;
55 m_GitDir=GitDir;
56 m_IndexFile.SeekToBegin();
58 SLogCacheIndexHeader header;
59 UINT count=m_IndexFile.Read(&header,sizeof(SLogCacheIndexHeader));
60 if(count != sizeof(SLogCacheIndexHeader))
61 return -2;
63 if( header.m_Magic != LOG_INDEX_MAGIC )
64 return -3;
66 if( header.m_Version != LOG_INDEX_VERSION )
67 return -4;
70 SLogCacheItem Item;
72 //for(int i=0;i<header.m_ItemCount;i++)
73 this->m_HashMapIndex.clear();
75 while(1)
77 count=m_IndexFile.Read(&Item,sizeof(SLogCacheItem));
78 if( count != sizeof(SLogCacheItem) )
79 break;
81 CString str;
82 g_Git.StringAppend(&str,Item.m_Hash,CP_UTF8,40);
83 this->m_HashMapIndex[str]=Item.m_Offset;
86 return 0;
89 int CLogCache::SaveOneItem(GitRev &Rev,ULONGLONG offset)
92 SLogCacheRevItemHeader header;
93 m_DataFile.Seek(offset,CFile::begin);
95 if(this->m_DataFile.m_hFile == CFile::hFileNull)
97 BOOL b=m_DataFile.Open(m_GitDir+_T("\\.git\\")+INDEX_FILE_NAME,
98 CFile::modeRead|CFile::shareDenyNone|
99 CFile::modeNoTruncate|CFile::modeCreate);
100 if(!b)
101 return -1;
104 header.m_Magic=LOG_DATA_ITEM_MAGIC;
105 header.m_Version=LOG_INDEX_VERSION;
106 header.m_FileCount=Rev.m_Files.GetCount();
108 m_DataFile.Write(&header,sizeof(SLogCacheRevItemHeader));
110 CArchive ar(&m_DataFile, CArchive::store);
112 ar<<Rev.m_AuthorName;
113 ar<<Rev.m_AuthorEmail;
114 ar<<Rev.m_AuthorDate;
115 ar<<Rev.m_CommitterName;
116 ar<<Rev.m_CommitterEmail;
117 ar<<Rev.m_CommitterDate;
118 ar<<Rev.m_Subject;
119 ar<<Rev.m_Body;
120 ar<<Rev.m_CommitHash;
121 ar<<Rev.m_Action;
123 for(int i=0;i<Rev.m_Files.GetCount();i++)
125 SLogCacheRevFileHeader header;
126 header.m_Magic=LOG_DATA_FILE_MAGIC;
127 header.m_Version=LOG_INDEX_VERSION;
129 ar<<header.m_Magic;
130 ar<<header.m_Version;
131 ar<<Rev.m_Files[i].GetGitPathString();
132 ar<<Rev.m_Files[i].GetGitOldPathString();
133 ar<<Rev.m_Files[i].m_Action;
134 ar<<Rev.m_Files[i].m_Stage;
135 ar<<Rev.m_Files[i].m_StatAdd;
136 ar<<Rev.m_Files[i].m_StatDel;
139 return 0;
142 int CLogCache::LoadOneItem(GitRev &Rev,ULONGLONG offset)
144 SLogCacheRevItemHeader header;
146 if(this->m_DataFile.m_hFile == CFile::hFileNull)
148 BOOL b=m_DataFile.Open(m_GitDir+_T("\\.git\\")+DATA_FILE_NAME,
149 CFile::modeRead|CFile::shareDenyNone|
150 CFile::modeNoTruncate|CFile::modeCreate);
151 if(!b)
152 return -1;
154 m_DataFile.Seek(offset,CFile::begin);
156 UINT count=m_DataFile.Read(&header,sizeof(SLogCacheRevItemHeader));
157 if( count != sizeof(SLogCacheRevItemHeader))
158 return -1;
159 if( !CheckHeader(header))
160 return -2;
163 CArchive ar(&m_DataFile, CArchive::load);
165 ar>>Rev.m_AuthorName;
166 ar>>Rev.m_AuthorEmail;
167 ar>>Rev.m_AuthorDate;
168 ar>>Rev.m_CommitterName;
169 ar>>Rev.m_CommitterEmail;
170 ar>>Rev.m_CommitterDate;
171 ar>>Rev.m_Subject;
172 ar>>Rev.m_Body;
173 ar>>Rev.m_CommitHash;
174 ar>>Rev.m_Action;
176 Rev.m_Files.Clear();
178 for(int i=0;i<header.m_FileCount;i++)
180 CTGitPath path;
181 CString file,oldfile;
182 path.Reset();
183 SLogCacheRevFileHeader header;
185 ar>>header.m_Magic;
186 ar>>header.m_Version;
188 if( this->CheckHeader(header) )
189 return -1;
190 ar>>file;
191 ar>>oldfile;
192 path.SetFromGit(file,&oldfile);
194 ar>>path.m_Action;
195 ar>>path.m_Stage;
196 ar>>path.m_StatAdd;
197 ar>>path.m_StatDel;
200 Rev.m_Files.AddPath(path);
202 return 0;
204 int CLogCache::RebuildCacheFile()
206 m_IndexFile.SetLength(0);
207 m_DataFile.SetLength(0);
209 SLogCacheIndexHeader header;
210 header.m_Magic=LOG_INDEX_MAGIC;
211 header.m_Version=LOG_INDEX_VERSION;
212 m_IndexFile.SeekToBegin();
213 m_IndexFile.Write(&header,sizeof(SLogCacheIndexHeader));
217 SLogCacheRevFileHeader header;
218 header.m_Magic=LOG_DATA_MAGIC;
219 header.m_Version=LOG_INDEX_VERSION;
221 m_DataFile.SeekToBegin();
222 m_DataFile.Write(&header,sizeof(SLogCacheRevFileHeader));
224 return 0;
226 int CLogCache::SaveCache()
228 if( this->m_NewCacheEntry.size() == 0 )
229 return 0;
231 bool bIsRebuild=false;
232 if(this->m_DataFile.m_hFile != CFile::hFileNull)
233 m_DataFile.Close();
234 if(this->m_IndexFile.m_hFile!=CFile::hFileNull)
235 m_IndexFile.Close();
237 if(this->m_IndexFile.m_hFile == CFile::hFileNull)
239 BOOL b=m_IndexFile.Open(m_GitDir+_T("\\.git\\")+INDEX_FILE_NAME,
240 CFile::modeReadWrite|CFile::shareDenyWrite|
241 CFile::modeNoTruncate|CFile::modeCreate);
242 if(!b)
243 return -1;
246 if(this->m_DataFile.m_hFile == CFile::hFileNull)
248 BOOL b=m_DataFile.Open(m_GitDir+_T("\\.git\\")+DATA_FILE_NAME,
249 CFile::modeReadWrite|CFile::shareDenyWrite|
250 CFile::modeNoTruncate|CFile::modeCreate);
253 if(!b)
255 m_IndexFile.Close();
256 return -1;
261 SLogCacheIndexHeader header;
262 memset(&header,0,sizeof(SLogCacheIndexHeader));
263 UINT count=m_IndexFile.Read(&header,sizeof(SLogCacheIndexHeader));
264 if(count != sizeof(SLogCacheIndexHeader) || !this->CheckHeader(header))
265 {// new file
266 RebuildCacheFile();
267 bIsRebuild=true;
273 SLogCacheRevFileHeader header;
275 UINT count=m_DataFile.Read(&header,sizeof(SLogCacheRevFileHeader));
276 if( count != sizeof(SLogCacheRevFileHeader) || !CheckHeader(header))
278 RebuildCacheFile();
279 bIsRebuild=true;
284 m_DataFile.SeekToEnd();
285 m_IndexFile.SeekToEnd();
286 for(int i=0;i<this->m_NewCacheEntry.size();i++)
288 if(this->m_HashMapIndex.find(m_NewCacheEntry[i].m_CommitHash) == m_HashMapIndex.end() || bIsRebuild)
290 ULONGLONG offset = m_DataFile.GetPosition();
291 this->SaveOneItem(m_NewCacheEntry[i],offset);
293 SLogCacheItem item;
294 for(int j=0; j<40;j++)
295 item.m_Hash[j]=(BYTE)m_NewCacheEntry[i].m_CommitHash[j];
296 item.m_Offset=offset;
298 m_IndexFile.Write(&item,sizeof(SLogCacheItem));
301 m_IndexFile.Close();
302 m_DataFile.Close();
303 return 0;