コード例 #1
0
ファイル: FileStatus.cs プロジェクト: eatplayhate/versionr
        private static void ProcessListFast(FSScan scan, Area area, List <FlatFSEntry> results, string rootFolder, System.Threading.CountdownEvent ce, System.Collections.Concurrent.ConcurrentBag <Entry> e2, int start, int end, Entry parentEntry = null, bool ignoreFiles = false)
        {
            int rflen = rootFolder.Length;

            if (rootFolder[rflen - 2] == ':')
            {
                rflen--;
            }
            rflen++;
            for (int i = start; i < end; i++)
            {
                var r = results[i];
                if (r.Length == -1)
                {
                    bool   ignoreDirectory     = false;
                    bool   ignoreContents      = false;
                    bool   hide                = false;
                    string slashedSubdirectory = r.FullName.Substring(rflen);

                    if (slashedSubdirectory == ".versionr/")
                    {
                        if (parentEntry == null)
                        {
                            if (r.ChildCount != 0)
                            {
                                throw new Exception();
                            }
                            continue;
                        }
                    }

                    CheckDirectoryIgnores(area, slashedSubdirectory, ref ignoreDirectory, ref ignoreContents, ref hide);

                    if (hide)
                    {
                        i += r.ChildCount;
                        continue;
                    }

                    var parent = new Entry(area, parentEntry, slashedSubdirectory, r.FullName, parentEntry == null ? slashedSubdirectory : r.FullName.Substring(parentEntry.FullName.Length), r.FileTime, 0, ignoreDirectory, (FileAttributes)r.Attributes);

                    if (parent.IsSymlink)
                    {
                        i += r.ChildCount;
                        continue;
                    }

                    e2.Add(parent);
                    if (ignoreDirectory)
                    {
                        // have to find child files and mark them specifically as ignored
                        int next = r.ChildCount + i + 1;
                        for (int x = i + 1; x < next; x++)
                        {
                            if (results[x].Length != -1)
                            {
                                var    f  = results[x];
                                string fn = f.FullName.Substring(rflen);

                                var ignoredFile = new Entry(area, parent, fn, f.FullName, f.FullName.Substring(parent.FullName.Length), f.FileTime, f.Length, true, (FileAttributes)f.Attributes);
                                e2.Add(ignoredFile);
                            }
                            else
                            {
                                x += results[x].ChildCount;
                            }
                        }
                        i += r.ChildCount;
                    }
                    else
                    {
                        int s = i + 1;
                        int e = i + 1 + r.ChildCount;
                        if (r.ChildCount > 16)
                        {
                            ce.AddCount();
                            System.Threading.Tasks.Task.Factory.StartNew(() => { ProcessListFast(scan, area, results, rootFolder, ce, e2, s, e, parent, ignoreContents); ce.Signal(); });
                        }
                        else
                        {
                            ProcessListFast(scan, area, results, rootFolder, ce, e2, s, e, parent, ignoreContents);
                        }
                        i += r.ChildCount;
                    }
                }
                else
                {
                    if (!ignoreFiles)
                    {
                        string fn      = r.FullName.Substring(rflen);
                        string fnI     = fn.ToLowerInvariant();
                        bool   ignored = CheckFileIgnores(area, fn, fnI, scan.FRIncludes, scan.FRIgnores, scan.ExtIncludes, scan.ExtIgnores);
                        e2.Add(new Entry(area, parentEntry, fn, r.FullName, parentEntry == null ? fn : r.FullName.Substring(parentEntry.FullName.Length), r.FileTime, r.Length, ignored, (FileAttributes)r.Attributes));
                    }
                }
            }
        }
コード例 #2
0
ファイル: FileStatus.cs プロジェクト: eatplayhate/versionr
        private static List <Entry> GetEntryList(Area area, DirectoryInfo root, DirectoryInfo adminFolder)
        {
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Restart();
            try
            {
                Func <string, List <FlatFSEntry> > nativeGenerator = null;
                if (!Utilities.MultiArchPInvoke.IsRunningOnMono)
                {
                    if (GetFSFast == null)
                    {
                        var asm = System.Reflection.Assembly.LoadFrom(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "/x64/VersionrCore.Win32.dll");
                        GetFSFast = asm.GetType("Versionr.Win32.FileSystem").GetMethod("EnumerateFileSystem").CreateDelegate(typeof(Func <string, List <FlatFSEntry> >)) as Func <string, List <FlatFSEntry> >;
                    }
                    nativeGenerator = GetFSFast;
                }
                else
                {
                    nativeGenerator = PosixFS.GetFlatEntries;
                }

                List <FlatFSEntry> flatEntries = null;
                if (!Utilities.MultiArchPInvoke.IsRunningOnMono)
                {
                }

                if (nativeGenerator != null)
                {
                    string fn = root.FullName.Replace('\\', '/');
                    if (fn[fn.Length - 1] != '/')
                    {
                        fn += '/';
                    }
                    System.Net.Sockets.Socket socket = new System.Net.Sockets.Socket(System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
                    if (flatEntries == null)
                    {
                        Printer.PrintDiagnostics("#q#Using native file scanner...##");
                        sw.Restart();
                        flatEntries = nativeGenerator(fn);
                        if (area.GetLocalPath(fn) != "")
                        {
                            flatEntries.Insert(0, new FlatFSEntry()
                            {
                                Attributes = (int)root.Attributes, ChildCount = flatEntries.Count, Length = -1, FileTime = root.LastWriteTimeUtc.Ticks, FullName = fn
                            });
                        }
                        sw.Restart();
                    }
                }
                if (flatEntries != null)
                {
                    FSScan scan = new FSScan();
                    scan.FRIgnores   = area?.Directives?.Ignore?.RegexFilePatterns;
                    scan.FRIncludes  = area?.Directives?.Include?.RegexFilePatterns;
                    scan.ExtIgnores  = area?.Directives?.Ignore?.Extensions;
                    scan.ExtIncludes = area?.Directives?.Include?.Extensions;
                    List <Entry> e2 = new List <Entry>(flatEntries.Count);
                    System.Collections.Concurrent.ConcurrentBag <Entry> entries2 = new System.Collections.Concurrent.ConcurrentBag <Entry>();
                    System.Threading.CountdownEvent ce2 = new System.Threading.CountdownEvent(1);
                    ProcessListFast(scan, area, flatEntries, area.RootDirectory.FullName, ce2, entries2, 0, flatEntries.Count, null);
                    ce2.Signal();
                    ce2.Wait();
                    var ea = entries2.ToArray();
                    e2.Capacity = ea.Length;
                    e2.AddRange(ea);
                    return(e2);
                }
            }
            catch (System.Exception e)
            {
                // try again with the slow mode
                Printer.PrintDiagnostics("#q#Couldn't use fast scanners {0}##", e);
            }
            Printer.PrintDiagnostics("#q#Using fallback file scanner...##");
            sw.Restart();
            System.Collections.Concurrent.ConcurrentBag <Entry> entries = new System.Collections.Concurrent.ConcurrentBag <Entry>();
            System.Threading.CountdownEvent ce = new System.Threading.CountdownEvent(1);
            PopulateList(entries, ce, area, null, root, area.GetLocalPath(root.FullName), adminFolder, false);
            ce.Signal();
            ce.Wait();
            Entry[] entryArray = entries.ToArray();
            Array.Sort(entryArray, (Entry x, Entry y) => { return(string.CompareOrdinal(x.CanonicalName, y.CanonicalName)); });
            return(entryArray.ToList());
        }