/// <summary>Read the cache file into memory.</summary> /// <remarks>Read the cache file into memory.</remarks> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public virtual void Read() { changed = false; statDirty = false; if (!cacheFile.Exists()) { header = null; entries.Clear(); lastCacheTime = 0; return; } cache = new RandomAccessFile(cacheFile, "r"); try { FileChannel channel = cache.GetChannel(); ByteBuffer buffer = ByteBuffer.AllocateDirect((int)cacheFile.Length()); buffer.Order(ByteOrder.BIG_ENDIAN); int j = channel.Read(buffer); if (j != buffer.Capacity()) { throw new IOException(MessageFormat.Format(JGitText.Get().couldNotReadIndexInOneGo , j, buffer.Capacity())); } buffer.Flip(); header = new GitIndex.Header(buffer); entries.Clear(); for (int i = 0; i < header.entries; ++i) { GitIndex.Entry entry = new GitIndex.Entry(this, buffer); GitIndex.Entry existing = entries.Get(entry.name); entries.Put(entry.name, entry); if (existing != null) { entry.stages |= existing.stages; } } lastCacheTime = cacheFile.LastModified(); } finally { cache.Close(); } }
/// <summary>Write content of index to disk.</summary> /// <remarks>Write content of index to disk.</remarks> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public virtual void Write() { CheckWriteOk(); FilePath tmpIndex = new FilePath(cacheFile.GetAbsoluteFile() + ".tmp"); FilePath Lock = new FilePath(cacheFile.GetAbsoluteFile() + ".lock"); if (!Lock.CreateNewFile()) { throw new IOException(JGitText.Get().indexFileIsInUse); } try { FileOutputStream fileOutputStream = new FileOutputStream(tmpIndex); FileChannel fc = fileOutputStream.GetChannel(); ByteBuffer buf = ByteBuffer.Allocate(4096); MessageDigest newMessageDigest = Constants.NewMessageDigest(); header = new GitIndex.Header(entries); header.Write(buf); buf.Flip(); newMessageDigest.Update(((byte[])buf.Array()), buf.ArrayOffset(), buf.Limit()); fc.Write(buf); buf.Flip(); buf.Clear(); for (Iterator i = entries.Values.Iterator(); i.HasNext();) { GitIndex.Entry e = (GitIndex.Entry)i.Next(); e.Write(buf); buf.Flip(); newMessageDigest.Update(((byte[])buf.Array()), buf.ArrayOffset(), buf.Limit()); fc.Write(buf); buf.Flip(); buf.Clear(); } buf.Put(newMessageDigest.Digest()); buf.Flip(); fc.Write(buf); fc.Close(); fileOutputStream.Close(); if (cacheFile.Exists()) { if (db.FileSystem.RetryFailedLockFileCommit()) { // file deletion fails on windows if another // thread is reading the file concurrently // So let's try 10 times... bool deleted = false; for (int i_1 = 0; i_1 < 10; i_1++) { if (cacheFile.Delete()) { deleted = true; break; } try { Sharpen.Thread.Sleep(100); } catch (Exception) { } } // ignore if (!deleted) { throw new IOException(JGitText.Get().couldNotRenameDeleteOldIndex); } } else { if (!cacheFile.Delete()) { throw new IOException(JGitText.Get().couldNotRenameDeleteOldIndex); } } } if (!tmpIndex.RenameTo(cacheFile)) { throw new IOException(JGitText.Get().couldNotRenameTemporaryIndexFileToIndex); } changed = false; statDirty = false; lastCacheTime = cacheFile.LastModified(); db.FireEvent(new IndexChangedEvent()); } finally { if (!Lock.Delete()) { throw new IOException(JGitText.Get().couldNotDeleteLockFileShouldNotHappen); } if (tmpIndex.Exists() && !tmpIndex.Delete()) { throw new IOException(JGitText.Get().couldNotDeleteTemporaryIndexFileShouldNotHappen ); } } }