Skip to content

Commit

Permalink
Use IsIncluded only on folder entries (#1345)
Browse files Browse the repository at this point in the history
* Use IsIncluded only on folder entries

* Add more tests for SortedFolderEntries

* Add comments for better understanding of the code

* Remove call to GetFolderSparseState in UpdateOrDeleteFilePlaceholder
  • Loading branch information
Kevin Willford committed Jul 30, 2019
1 parent aa12919 commit 8974e45
Show file tree
Hide file tree
Showing 9 changed files with 232 additions and 192 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public override bool IsProjectionParseComplete()
return this.ProjectionParseComplete;
}

public override PathSparseState GetPathSparseState(string virtualPath)
public override PathSparseState GetFolderPathSparseState(string virtualPath)
{
return PathSparseState.Included;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public void AddItemAtEnd()
{
SortedFolderEntries sfe = SetupDefaultEntries();
LazyUTF8String name = ConstructLazyUTF8String("{{shouldbeattheend");
sfe.AddFolder(name);
sfe.AddFile(name, new byte[20]);
sfe[defaultFiles.Length + defaultFolders.Length].Name.ShouldEqual(name, "Item added at incorrect index.");
}

Expand All @@ -98,7 +98,7 @@ public void AddItemAtTheBeginning()
{
SortedFolderEntries sfe = SetupDefaultEntries();
LazyUTF8String name = ConstructLazyUTF8String("((shouldbeatthestart");
sfe.AddFolder(name);
sfe.AddFile(name, new byte[20]);
sfe[0].Name.ShouldEqual(name, "Item added at incorrect index.");
}

Expand All @@ -117,15 +117,83 @@ public void ValidateOrderOfDefaultEntries()
}

[TestCase]
public void AddItemWithIsIncludedFalse()
public void FoldersShouldBeIncludedWhenSparseFolderDataIsEmpty()
{
SortedFolderEntries sfe = SetupDefaultEntries();
LazyUTF8String name = ConstructLazyUTF8String("IsIncludedFalse");
sfe.AddFile(name, new byte[20], isIncluded: false);
sfe.TryGetValue(name, out FolderEntryData folderEntryData).ShouldBeTrue();
folderEntryData.ShouldNotBeNull();
folderEntryData.IsFolder.ShouldBeFalse();
folderEntryData.IsIncluded.ShouldBeFalse();
sfe.GetOrAddFolder(new[] { name }, partIndex: 0, parentIsIncluded: false, rootSparseFolderData: new SparseFolderData());
ValidateFolder(sfe, name, isIncludedValue: true);
}

[TestCase]
public void AddFolderWhereParentIncludedIsFalseAndIncluded()
{
SortedFolderEntries sfe = SetupDefaultEntries();
LazyUTF8String name = ConstructLazyUTF8String("Child");
SparseFolderData sparseFolderData = new SparseFolderData();
sparseFolderData.Children.Add("Child", new SparseFolderData());
sfe.GetOrAddFolder(new[] { name }, partIndex: 0, parentIsIncluded: false, rootSparseFolderData: sparseFolderData);
ValidateFolder(sfe, name, isIncludedValue: false);
}

[TestCase]
public void AddFolderWhereParentIncludedIsTrueAndChildIsIncluded()
{
SortedFolderEntries sfe = SetupDefaultEntries();
LazyUTF8String name = ConstructLazyUTF8String("Child");
SparseFolderData sparseFolderData = new SparseFolderData();
sparseFolderData.Children.Add("Child", new SparseFolderData());
sfe.GetOrAddFolder(new[] { name }, partIndex: 0, parentIsIncluded: true, rootSparseFolderData: sparseFolderData);
ValidateFolder(sfe, name, isIncludedValue: true);
}

[TestCase]
public void AddFolderWhereParentIncludedIsTrueAndChildIsNotIncluded()
{
SortedFolderEntries sfe = SetupDefaultEntries();
LazyUTF8String name = ConstructLazyUTF8String("ChildNotIncluded");
SparseFolderData sparseFolderData = new SparseFolderData();
sparseFolderData.Children.Add("Child", new SparseFolderData());
sfe.GetOrAddFolder(new[] { name }, partIndex: 0, parentIsIncluded: true, rootSparseFolderData: sparseFolderData);
ValidateFolder(sfe, name, isIncludedValue: false);
}

[TestCase]
public void AddFolderWhereParentIsRecursive()
{
SortedFolderEntries sfe = SetupDefaultEntries();
LazyUTF8String name = ConstructLazyUTF8String("Child");
LazyUTF8String name2 = ConstructLazyUTF8String("GrandChild");
SparseFolderData sparseFolderData = new SparseFolderData() { IsRecursive = true };
sparseFolderData.Children.Add("Child", new SparseFolderData());
sfe.GetOrAddFolder(new[] { name, name2 }, partIndex: 1, parentIsIncluded: true, rootSparseFolderData: sparseFolderData);
ValidateFolder(sfe, name2, isIncludedValue: true);
}

[TestCase]
public void AddFolderBelowTopLevelNotIncluded()
{
SortedFolderEntries sfe = SetupDefaultEntries();
LazyUTF8String name = ConstructLazyUTF8String("Child");
LazyUTF8String name2 = ConstructLazyUTF8String("GrandChild");
SparseFolderData sparseFolderData = new SparseFolderData();
sparseFolderData.Children.Add("Child", new SparseFolderData());
sfe.GetOrAddFolder(new[] { name, name2 }, partIndex: 1, parentIsIncluded: true, rootSparseFolderData: sparseFolderData);
ValidateFolder(sfe, name2, isIncludedValue: false);
}

[TestCase]
public void AddFolderBelowTopLevelIsIncluded()
{
SortedFolderEntries sfe = SetupDefaultEntries();
LazyUTF8String name = ConstructLazyUTF8String("Child");
LazyUTF8String name2 = ConstructLazyUTF8String("GrandChild");
SparseFolderData sparseFolderData = new SparseFolderData();
SparseFolderData childSparseFolderData = new SparseFolderData();
childSparseFolderData.Children.Add("GrandChild", new SparseFolderData());
sparseFolderData.Children.Add("Child", childSparseFolderData);
sfe.GetOrAddFolder(new[] { name, name2 }, partIndex: 1, parentIsIncluded: true, rootSparseFolderData: sparseFolderData);
ValidateFolder(sfe, name2, isIncludedValue: true);
}

[TestCase]
Expand Down Expand Up @@ -178,10 +246,9 @@ private static void AddFiles(SortedFolderEntries entries, params string[] names)
for (int i = 0; i < names.Length; i++)
{
LazyUTF8String entryString = ConstructLazyUTF8String(names[i]);
entries.AddFile(entryString, new byte[20], isIncluded: true);
entries.AddFile(entryString, new byte[20]);
entries.TryGetValue(entryString, out FolderEntryData folderEntryData).ShouldBeTrue();
folderEntryData.ShouldNotBeNull();
folderEntryData.IsIncluded.ShouldBeTrue();
folderEntryData.IsFolder.ShouldBeFalse();
}
}
Expand All @@ -191,12 +258,20 @@ private static void AddFolders(SortedFolderEntries entries, params string[] name
for (int i = 0; i < names.Length; i++)
{
LazyUTF8String entryString = ConstructLazyUTF8String(names[i]);
entries.AddFolder(entryString);
entries.TryGetValue(entryString, out FolderEntryData folderEntryData).ShouldBeTrue();
folderEntryData.ShouldNotBeNull();
folderEntryData.IsIncluded.ShouldBeTrue();
folderEntryData.IsFolder.ShouldBeTrue();
entries.GetOrAddFolder(new[] { entryString }, partIndex: 0, parentIsIncluded: true, rootSparseFolderData: new SparseFolderData());
ValidateFolder(entries, entryString, isIncludedValue: true);
}
}

private static void ValidateFolder(SortedFolderEntries entries, LazyUTF8String entryToValidate, bool isIncludedValue)
{
entries.TryGetValue(entryToValidate, out FolderEntryData folderEntryData).ShouldBeTrue();
folderEntryData.ShouldNotBeNull();
folderEntryData.IsFolder.ShouldBeTrue();

FolderData folderData = folderEntryData as FolderData;
folderData.ShouldNotBeNull();
folderData.IsIncluded.ShouldEqual(isIncludedValue, "IsIncluded does not match expected value.");
}
}
}
2 changes: 1 addition & 1 deletion GVFS/GVFS.Virtualization/FileSystemCallbacks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ public void OnFilePreDelete(string relativePath)
public void OnFolderCreated(string relativePath, out bool sparseFoldersUpdated)
{
sparseFoldersUpdated = false;
GitIndexProjection.PathSparseState pathProjectionState = this.GitIndexProjection.GetPathSparseState(relativePath);
GitIndexProjection.PathSparseState pathProjectionState = this.GitIndexProjection.GetFolderPathSparseState(relativePath);
if (pathProjectionState == GitIndexProjection.PathSparseState.Excluded)
{
if (this.GitIndexProjection.TryAddSparseFolder(relativePath))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,10 @@ public string ConvertShaToString()
return this.Sha.ToString();
}

public void ResetData(LazyUTF8String name, byte[] shaBytes, bool isIncluded)
public void ResetData(LazyUTF8String name, byte[] shaBytes)
{
this.Name = name;
this.Size = InvalidSize;
this.IsIncluded = isIncluded;
Sha1Id.ShaBufferToParts(shaBytes, out this.shaBytes1through8, out this.shaBytes9Through16, out this.shaBytes17Through20);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ internal class FolderData : FolderEntryData

public SortedFolderEntries ChildEntries { get; private set; }
public bool ChildrenHaveSizes { get; private set; }
public bool IsIncluded { get; set; } = true;

public void ResetData(LazyUTF8String name)
public void ResetData(LazyUTF8String name, bool isIncluded)
{
this.Name = name;
this.ChildrenHaveSizes = false;
this.IsIncluded = true;
this.IsIncluded = isIncluded;
if (this.ChildEntries == null)
{
this.ChildEntries = new SortedFolderEntries();
Expand All @@ -30,22 +31,21 @@ public void ResetData(LazyUTF8String name)
this.ChildEntries.Clear();
}

public FolderData AddChildFolder(LazyUTF8String name)
{
return this.ChildEntries.AddFolder(name);
}

public FileData AddChildFile(LazyUTF8String name, byte[] shaBytes)
{
return this.ChildEntries.AddFile(name, shaBytes, this.IsIncluded);
return this.ChildEntries.AddFile(name, shaBytes);
}

public override void Include()
public void Include()
{
base.Include();
this.IsIncluded = true;
for (int i = 0; i < this.ChildEntries.Count; i++)
{
this.ChildEntries[i].Include();
FolderData childFolder = this.ChildEntries[i] as FolderData;
if (childFolder != null)
{
childFolder.Include();
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@ internal abstract class FolderEntryData
{
public LazyUTF8String Name { get; protected set; }
public abstract bool IsFolder { get; }
public bool IsIncluded { get; set; } = true;

public virtual void Include()
{
this.IsIncluded = true;
}

protected static EventMetadata CreateEventMetadata(Exception e = null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,30 +67,6 @@ public bool BuildingProjection_HasSameParentAsLastEntry
get; private set;
}

public bool BuildingProjection_ShouldInclude
{
get; set;
}

/// <summary>
/// This property is for when using sparse folder mode to indicate whether
/// all children should be being included so it is including entries recursively
/// </summary>
public bool BuildingProjection_ShouldIncludeRecursive
{
get; set;
}

/// <summary>
/// This property is for when using sparse folder mode to have the included folder data
/// to check if an index entry should be included. This get set to the root when a folder
/// is not found in the Children of the included folder or index path parts gets reset.
/// </summary>
public SparseFolderData BuildingProjection_SparseFolderToCheck
{
get; set;
}

/// <summary>
/// Parses the path using LazyUTF8Strings. It should only be called when building a new projection.
/// </summary>
Expand Down Expand Up @@ -235,9 +211,6 @@ public void ClearLastParent()
{
this.buildingProjectionPreviousFinalSeparatorIndex = int.MaxValue;
this.BuildingProjection_HasSameParentAsLastEntry = false;
this.BuildingProjection_ShouldInclude = false;
this.BuildingProjection_ShouldIncludeRecursive = false;
this.BuildingProjection_SparseFolderToCheck = null;
this.BuildingProjection_LastParent = null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,27 +88,57 @@ public void Clear()
this.sortedEntries.Clear();
}

public FolderData AddFolder(LazyUTF8String name)
public FileData AddFile(LazyUTF8String name, byte[] shaBytes)
{
int insertionIndex = this.GetInsertionIndex(name);
return this.InsertFolder(name, insertionIndex);
return this.InsertFile(name, shaBytes, insertionIndex);
}

public FileData AddFile(LazyUTF8String name, byte[] shaBytes, bool isIncluded)
public FolderData GetOrAddFolder(
LazyUTF8String[] pathParts,
int partIndex,
bool parentIsIncluded,
SparseFolderData rootSparseFolderData)
{
int insertionIndex = this.GetInsertionIndex(name);
return this.InsertFile(name, shaBytes, isIncluded, insertionIndex);
}

public FolderData GetOrAddFolder(LazyUTF8String name)
{
int index = this.GetSortedEntriesIndexOfName(name);
int index = this.GetSortedEntriesIndexOfName(pathParts[partIndex]);
if (index >= 0)
{
return (FolderData)this.sortedEntries[index];
}

return this.InsertFolder(name, ~index);
bool isIncluded = true;
if (rootSparseFolderData.Children.Count > 0)
{
if (parentIsIncluded)
{
// Need to check if this child folder should be included
SparseFolderData folderData = rootSparseFolderData;
for (int i = 0; i <= partIndex; i++)
{
if (folderData.IsRecursive)
{
break;
}

string childFolderName = pathParts[i].GetString();
if (!folderData.Children.ContainsKey(childFolderName))
{
isIncluded = false;
break;
}
else
{
folderData = folderData.Children[childFolderName];
}
}
}
else
{
isIncluded = false;
}
}

return this.InsertFolder(pathParts[partIndex], ~index, isIncluded: isIncluded);
}

public bool TryGetValue(LazyUTF8String name, out FolderEntryData value)
Expand Down Expand Up @@ -143,18 +173,18 @@ private int GetInsertionIndex(LazyUTF8String name)
return insertionIndex;
}

private FolderData InsertFolder(LazyUTF8String name, int insertionIndex)
private FolderData InsertFolder(LazyUTF8String name, int insertionIndex, bool isIncluded)
{
FolderData data = folderPool.GetNew();
data.ResetData(name);
data.ResetData(name, isIncluded);
this.sortedEntries.Insert(insertionIndex, data);
return data;
}

private FileData InsertFile(LazyUTF8String name, byte[] shaBytes, bool isIncluded, int insertionIndex)
private FileData InsertFile(LazyUTF8String name, byte[] shaBytes, int insertionIndex)
{
FileData data = filePool.GetNew();
data.ResetData(name, shaBytes, isIncluded);
data.ResetData(name, shaBytes);
this.sortedEntries.Insert(insertionIndex, data);
return data;
}
Expand Down
Loading

0 comments on commit 8974e45

Please sign in to comment.