I want to build Git class where i can store integers. FilesSet is where I store current state of integers. Commits' key is basically commit number so I can checkout pretty fast. Hashes is used for quick search of hashes that I need in commit part.
Update is for updating current state of integers.
In Commit I want to save a copy of current state and do it fast. First of all I don't want to compare arrays of integers, so I calculate hash of current state. Then if Hashes already has that hash as a key, I add to Commits Pair of commitNumber and integer array that corresponds to that hash so I won't have to store another copy of array. And in Hashes of this key I add commit Number so I can see which commits have that hash. This one is a bottleneck for my solution.
In Checkout I basically get int that I need by arguments. I think this method is already really fast.
I need this class to be fast but I can't really provide test cases as they are hidden at my college testing system. My current solution is too slow with int Commit() .
Here it is :
using System.Collections.Generic;
using System.Linq;
using System;
namespace GitTask
{
public class Git
{
int[] FilesSet { get; set; }
Dictionary<int, int[]> Commits { get; set; }
SortedList<int, List<int>> Hashes { get; set; }
public Git(int filesCount)
{
FilesSet = new int[filesCount];
Commits = new Dictionary<int, int[]>();
Hashes = new SortedList<int, List<int>>();
}
public void Update(int fileNumber, int value)
{
FilesSet[fileNumber] = value;
}
public int Commit()
{
var commitNumber = Commits.Count;
var tempHash = GetMyHashCode(FilesSet);
if (Hashes.TryGetValue(tempHash, out List<int> key))
{
Commits.Add(commitNumber, Commits[key[0]]);
Hashes[tempHash].Add(commitNumber);
return commitNumber;
}
Commits.Add(Commits.Count, FilesSet.Clone() as int[]);
Hashes.Add(tempHash, new List<int>(new int[] { commitNumber }));
return commitNumber;
}
public int Checkout(int commitNumber, int fileNumber)
{
if (commitNumber >= Commits.Count)
throw new ArgumentException();
else
{
var commit = Commits[commitNumber];
return commit[fileNumber];
}
}
private int GetMyHashCode(int[] array)
{
int result = 0;
for (int i = 0; i < array.Length; ++i)
{
result = unchecked(result * 31 + array[i]);
}
return result;
}
}
}
I expect you to come up with tips on speeding it up or creating new kind of storing files. I also tried to measure performance of methods and it seems like calculating hash of big array is a problem and adding to SortedList<int,List<int>> is a problem as well.