Beispiel #1
0
            /// <summary>
            /// Get the index of the name in the sorted folder entries list
            /// </summary>
            /// <param name="name">The name to search for in the entries</param>
            /// <returns>
            /// The zero based index of the entry if found;
            /// otherwise, a negative number that is the bitwise complement of the index of the next element that is larger than item or,
            /// if there is no larger element, the bitwise complement of this.entries.ObjectsUsed.
            /// </returns>
            private int GetSortedEntriesIndexOfName(LazyUTF8String name)
            {
                if (this.sortedEntries.Count == 0)
                {
                    return(-1);
                }

                // Insertions are almost always at the end, because the inputs are pre-sorted by git.
                // We only have to insert at a different spot where Windows/Mac and git disagree on the sort order;
                // on Linux we use a case-sensitive comparsion, which we expect to align with git.
                bool caseSensitive = GVFSPlatform.Instance.Constants.CaseSensitiveFileSystem;
                int  compareResult = this.sortedEntries[this.sortedEntries.Count - 1].Name.Compare(name, caseSensitive);

                if (compareResult == 0)
                {
                    return(this.sortedEntries.Count - 1);
                }
                else if (compareResult < 0)
                {
                    return(~this.sortedEntries.Count);
                }

                int left  = 0;
                int right = this.sortedEntries.Count - 2;

                while (right - left > 2)
                {
                    int middle     = left + ((right - left) / 2);
                    int comparison = this.sortedEntries[middle].Name.Compare(name, caseSensitive);

                    if (comparison == 0)
                    {
                        return(middle);
                    }

                    if (comparison < 0)
                    {
                        left = middle + 1;
                    }
                    else
                    {
                        right = middle - 1;
                    }
                }

                for (int i = right; i >= left; i--)
                {
                    compareResult = this.sortedEntries[i].Name.Compare(name, caseSensitive);
                    if (compareResult == 0)
                    {
                        return(i);
                    }
                    else if (compareResult < 0)
                    {
                        return(~(i + 1));
                    }
                }

                return(~left);
            }
Beispiel #2
0
            public static unsafe LazyUTF8String FromByteArray(byte *bufferPtr, int length)
            {
                bytePool.MakeFreeSpace(length);
                LazyUTF8String lazyString = stringPool.GetNew();

                byte *poolPtrForLoop   = bytePool.RawPointer + bytePool.FreeIndex;
                byte *bufferPtrForLoop = bufferPtr;
                int   index            = 0;

                while (index < length)
                {
                    if (*bufferPtrForLoop <= 127)
                    {
                        *poolPtrForLoop = *bufferPtrForLoop;
                    }
                    else
                    {
                        // The string has non-ASCII characters in it, fall back to full parsing
                        lazyString.SetToString(Encoding.UTF8.GetString(bufferPtr, length));
                        return(lazyString);
                    }

                    ++poolPtrForLoop;
                    ++bufferPtrForLoop;
                    ++index;
                }

                lazyString.ResetState(bytePool.FreeIndex, length);
                bytePool.AdvanceFreeIndex(length);
                return(lazyString);
            }
        public unsafe void ExpandAfterShrinkPool_AllocatesDefault()
        {
            LazyUTF8String.ResetPool(new MockTracer(), DefaultIndexEntryCount);
            string fileAndFolderNames = "folderSDKfile.txtDKfolders";

            UseASCIIBytePointer(
                fileAndFolderNames,
                bufferPtr =>
            {
                int initialBytePoolSize   = LazyUTF8String.BytePoolSize();
                int initialStringPoolSize = LazyUTF8String.StringPoolSize();

                LazyUTF8String.FromByteArray(bufferPtr + 6, 3);
                LazyUTF8String.FromByteArray(bufferPtr + 17, 2);
                LazyUTF8String.ShrinkPool();
                CheckPoolSizes(expectedBytePoolSize: 6, expectedStringPoolSize: 2);
                LazyUTF8String.FreePool();
                CheckPoolSizes(expectedBytePoolSize: 6, expectedStringPoolSize: 2);
                LazyUTF8String.ShrinkPool();
                CheckPoolSizes(expectedBytePoolSize: 0, expectedStringPoolSize: 0);
                LazyUTF8String.FromByteArray(bufferPtr + 6, 3);
                CheckPoolSizes(expectedBytePoolSize: initialBytePoolSize, expectedStringPoolSize: initialStringPoolSize);
                LazyUTF8String.ShrinkPool();
                CheckPoolSizes(expectedBytePoolSize: 3, expectedStringPoolSize: 1);
            });
        }
        public void AddItemAtEnd()
        {
            SortedFolderEntries sfe  = SetupDefaultEntries();
            LazyUTF8String      name = ConstructLazyUTF8String("{{shouldbeattheend");

            sfe.AddFolder(name);
            sfe[defaultFiles.Length + defaultFolders.Length].Name.ShouldEqual(name, "Item added at incorrect index.");
        }
 private static void AddFolders(SortedFolderEntries entries, params string[] names)
 {
     for (int i = 0; i < names.Length; i++)
     {
         LazyUTF8String entryString = ConstructLazyUTF8String(names[i]);
         entries.AddFolder(entryString);
     }
 }
            private FolderData InsertFolder(LazyUTF8String name, int insertionIndex)
            {
                FolderData data = folderPool.GetNew();

                data.ResetData(name);
                this.sortedEntries.Insert(insertionIndex, data);
                return(data);
            }
        public void EntryFoundDifferentCase()
        {
            SortedFolderEntries sfe      = SetupDefaultEntries();
            LazyUTF8String      findName = ConstructLazyUTF8String("Folder");

            sfe.TryGetValue(findName, out FolderEntryData folderEntryData).ShouldBeTrue();
            folderEntryData.ShouldNotBeNull();
        }
        public void EntryNotFound()
        {
            SortedFolderEntries sfe      = SetupDefaultEntries();
            LazyUTF8String      findName = ConstructLazyUTF8String("Anything");

            sfe.TryGetValue(findName, out FolderEntryData folderEntryData).ShouldBeFalse();
            folderEntryData.ShouldBeNull();
        }
            private FileData InsertFile(LazyUTF8String name, byte[] shaBytes, int insertionIndex)
            {
                FileData data = filePool.GetNew();

                data.ResetData(name, shaBytes);
                this.sortedEntries.Insert(insertionIndex, data);
                return(data);
            }
 private static unsafe LazyUTF8String ConstructLazyUTF8String(string name)
 {
     byte[] buffer = Encoding.ASCII.GetBytes(name);
     fixed(byte *bufferPtr = buffer)
     {
         return(LazyUTF8String.FromByteArray(bufferPtr, name.Length));
     }
 }
        public void FoldersShouldBeIncludedWhenSparseFolderDataIsEmpty()
        {
            SortedFolderEntries sfe  = SetupDefaultEntries();
            LazyUTF8String      name = ConstructLazyUTF8String("IsIncludedFalse");

            sfe.GetOrAddFolder(new[] { name }, partIndex: 0, parentIsIncluded: false, rootSparseFolderData: new SparseFolderData());
            ValidateFolder(sfe, name, isIncludedValue: true);
        }
        public void AddItemAtEnd()
        {
            SortedFolderEntries sfe  = SetupDefaultEntries();
            LazyUTF8String      name = ConstructLazyUTF8String("{{shouldbeattheend");

            sfe.AddFile(name, new byte[20]);
            sfe[GetDefaultEntriesLength()].Name.ShouldEqual(name, "Item added at incorrect index.");
        }
        public void AddItemAtTheBeginning()
        {
            SortedFolderEntries sfe  = SetupDefaultEntries();
            LazyUTF8String      name = ConstructLazyUTF8String("((shouldbeatthestart");

            sfe.AddFile(name, new byte[20]);
            sfe[0].Name.ShouldEqual(name, "Item added at incorrect index.");
        }
            /// <summary>
            /// Get the index of the name in the sorted folder entries list
            /// </summary>
            /// <param name="name">The name to search for in the entries</param>
            /// <returns>
            /// The zero based index of the entry if found;
            /// otherwise, a negative number that is the bitwise complement of the index of the next element that is larger than item or,
            /// if there is no larger element, the bitwise complement of this.entries.ObjectsUsed.
            /// </returns>
            private int GetSortedEntriesIndexOfName(LazyUTF8String name)
            {
                if (this.sortedEntries.Count == 0)
                {
                    return(-1);
                }

                // Insertions are almost always at the end, because the inputs are pre-sorted by git.
                // We only have to insert at a different spot where Windows and git disagree on the sort order.
                int compareResult = this.sortedEntries[this.sortedEntries.Count - 1].Name.CaseInsensitiveCompare(name);

                if (compareResult == 0)
                {
                    return(this.sortedEntries.Count - 1);
                }
                else if (compareResult < 0)
                {
                    return(~this.sortedEntries.Count);
                }

                int left  = 0;
                int right = this.sortedEntries.Count - 2;

                while (right - left > 2)
                {
                    int middle     = left + ((right - left) / 2);
                    int comparison = this.sortedEntries[middle].Name.CaseInsensitiveCompare(name);

                    if (comparison == 0)
                    {
                        return(middle);
                    }

                    if (comparison < 0)
                    {
                        left = middle + 1;
                    }
                    else
                    {
                        right = middle - 1;
                    }
                }

                for (int i = right; i >= left; i--)
                {
                    compareResult = this.sortedEntries[i].Name.CaseInsensitiveCompare(name);
                    if (compareResult == 0)
                    {
                        return(i);
                    }
                    else if (compareResult < 0)
                    {
                        return(~(i + 1));
                    }
                }

                return(~left);
            }
 private static void AddFolders(SortedFolderEntries entries, params string[] names)
 {
     for (int i = 0; i < names.Length; i++)
     {
         LazyUTF8String entryString = ConstructLazyUTF8String(names[i]);
         entries.GetOrAddFolder(new[] { entryString }, partIndex: 0, parentIsIncluded: true, rootSparseFolderData: new SparseFolderData());
         ValidateFolder(entries, entryString, isIncludedValue: true);
     }
 }
        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);
        }
        public void MinimumPoolSize()
        {
            LazyUTF8String.ResetPool(new MockTracer(), 0);

            LazyUTF8String.FreePool();
            LazyUTF8String.BytePoolSize().ShouldBeAtLeast(1);

            LazyUTF8String.InitializePools(new MockTracer(), 0);
            LazyUTF8String.BytePoolSize().ShouldBeAtLeast(1);
        }
 public unsafe void CaseInsensitiveEquals_OneNameShorterEqualsFalse()
 {
     UseASCIIBytePointer(
         "folderonefile.txtFold",
         bufferPtr =>
     {
         LazyUTF8String firstFolder  = LazyUTF8String.FromByteArray(bufferPtr + 0, 6);
         LazyUTF8String secondFolder = LazyUTF8String.FromByteArray(bufferPtr + 17, 4);
         firstFolder.CaseInsensitiveEquals(secondFolder).ShouldBeFalse(nameof(firstFolder.CaseInsensitiveEquals));
     });
 }
        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);
        }
 public unsafe void CaseInsensitiveCompare_EqualsGreaterThanZero2()
 {
     UseASCIIBytePointer(
         "folderSDKfile.txtDKfolders",
         bufferPtr =>
     {
         LazyUTF8String firstFolder  = LazyUTF8String.FromByteArray(bufferPtr + 6, 3);
         LazyUTF8String secondFolder = LazyUTF8String.FromByteArray(bufferPtr + 17, 2);
         firstFolder.CaseInsensitiveCompare(secondFolder).ShouldBeAtLeast(1, nameof(firstFolder.CaseInsensitiveCompare));
     });
 }
 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]);
         entries.TryGetValue(entryString, out FolderEntryData folderEntryData).ShouldBeTrue();
         folderEntryData.ShouldNotBeNull();
         folderEntryData.IsFolder.ShouldBeFalse();
     }
 }
 public unsafe void CaseInsensitiveCompare_EqualsLessThanZero()
 {
     UseASCIIBytePointer(
         "folderonefile.txtfolders",
         bufferPtr =>
     {
         LazyUTF8String firstFolder  = LazyUTF8String.FromByteArray(bufferPtr + 0, 6);
         LazyUTF8String secondFolder = LazyUTF8String.FromByteArray(bufferPtr + 17, 7);
         firstFolder.CaseInsensitiveCompare(secondFolder).ShouldBeAtMost(-1, nameof(firstFolder.CaseInsensitiveCompare));
     });
 }
            public FolderData GetOrAddFolder(LazyUTF8String name)
            {
                int index = this.GetSortedEntriesIndexOfName(name);

                if (index >= 0)
                {
                    return((FolderData)this.sortedEntries[index]);
                }

                return(this.InsertFolder(name, ~index));
            }
 public unsafe void CaseInsensitiveEquals_SameNameDifferentCase2_EqualsTrue()
 {
     UseASCIIBytePointer(
         "FOlderonefile.txtFolder",
         bufferPtr =>
     {
         LazyUTF8String firstFolder  = LazyUTF8String.FromByteArray(bufferPtr + 0, 6);
         LazyUTF8String secondFolder = LazyUTF8String.FromByteArray(bufferPtr + 17, 6);
         firstFolder.CaseInsensitiveEquals(secondFolder).ShouldBeTrue(nameof(firstFolder.CaseInsensitiveEquals));
     });
 }
 public unsafe void NonASCIICharacters_Compare()
 {
     UseUTF8BytePointer(
         "folderSDKfile.txtريلٌأكتوبرDKfolders",
         bufferPtr =>
     {
         LazyUTF8String firstFolder  = LazyUTF8String.FromByteArray(bufferPtr + 6, 3);
         LazyUTF8String secondFolder = LazyUTF8String.FromByteArray(bufferPtr + 17, 20);
         firstFolder.CaseInsensitiveCompare(secondFolder).ShouldBeAtMost(-1, nameof(firstFolder.CaseInsensitiveCompare));
     });
 }
            public void ResetData(LazyUTF8String name)
            {
                this.Name = name;
                this.ChildrenHaveSizes = false;
                if (this.ChildEntries == null)
                {
                    this.ChildEntries = new SortedFolderEntries();
                }

                this.ChildEntries.Clear();
            }
        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.");
        }
 public unsafe void PoolSizeCheck()
 {
     UseASCIIBytePointer(
         "folderSDKfile.txtDKfolders",
         bufferPtr =>
     {
         int bytePoolSizeBeforeFreePool   = LazyUTF8String.BytePoolSize();
         int stringPoolSizeBeforeFreePool = LazyUTF8String.StringPoolSize();
         LazyUTF8String firstFolder       = LazyUTF8String.FromByteArray(bufferPtr + 6, 3);
         LazyUTF8String secondFolder      = LazyUTF8String.FromByteArray(bufferPtr + 17, 2);
         CheckPoolSizes(bytePoolSizeBeforeFreePool, stringPoolSizeBeforeFreePool);
     });
 }
            public bool TryGetValue(LazyUTF8String name, out FolderEntryData value)
            {
                int index = this.GetSortedEntriesIndexOfName(name);

                if (index >= 0)
                {
                    value = this.sortedEntries[index];
                    return(true);
                }

                value = null;
                return(false);
            }
 public unsafe void GetString()
 {
     UseASCIIBytePointer(
         "folderonefile.txt",
         bufferPtr =>
     {
         LazyUTF8String firstFolder = LazyUTF8String.FromByteArray(bufferPtr + 0, 6);
         firstFolder.GetString().ShouldEqual("folder");
         LazyUTF8String secondFolder = LazyUTF8String.FromByteArray(bufferPtr + 6, 3);
         secondFolder.GetString().ShouldEqual("one");
         LazyUTF8String file = LazyUTF8String.FromByteArray(bufferPtr + 9, 8);
         file.GetString().ShouldEqual("file.txt");
     });
 }