Example #1
0
    private static void Build()
    {
        allTypes = TypeCache.GetTypesDerivedFrom <UnityEngine.Object>().ToArray();

        var sw = new System.Diagnostics.Stopwatch();

        sw.Start();

        QE = new QueryEngine <Type>();
        QE.AddFilter("m", t => t.GetMethods().Length);
        QE.AddFilter("id", t => t.FullName);
        QE.AddFilter("asm", t => Path.GetFileNameWithoutExtension(t.Assembly.Location).ToLowerInvariant());
        QE.SetSearchDataCallback(t => new[] { t.Name });
        Debug.Log($"QuerEngine initialization took {sw.Elapsed.TotalMilliseconds,3:0.##} ms");

        sw.Restart();
        index = new SearchIndexer();
        index.Start();
        foreach (var t in allTypes)
        {
            var di = index.AddDocument(t.AssemblyQualifiedName, false);
            index.AddWord(t.Name.ToLowerInvariant(), 0, di);
            index.AddNumber("m", t.GetMethods().Length, 0, di);
            index.AddProperty("id", t.FullName.ToLowerInvariant(),
                              minVariations: t.FullName.Length, maxVariations: t.FullName.Length,
                              score: 0, documentIndex: di,
                              saveKeyword: false, exact: true);
            index.AddProperty("asm", Path.GetFileNameWithoutExtension(t.Assembly.Location).ToLowerInvariant(), di);
        }
        index.Finish(() => Debug.Log($"Type indexing took {sw.Elapsed.TotalMilliseconds,3:0.##} ms"));
    }
    private static void RunThreadIndexing()
    {
        var sw = new System.Diagnostics.Stopwatch();

        sw.Start();

        index = new SearchIndexer();
        index.Start();
        int completed  = 0;
        var metaFiles  = Directory.GetFiles("Assets", "*.meta", SearchOption.AllDirectories);
        var progressId = Progress.Start($"Scanning dependencies ({metaFiles.Length} assets)");

        var exclude = new[] { ".unity", ".prefab" };

        Parallel.ForEach(metaFiles, mf =>
        {
            Progress.Report(progressId, completed / (float)metaFiles.Length, mf);
            var assetPath = mf.Replace("\\", "/").Substring(0, mf.Length - 5).ToLowerInvariant();
            if (!File.Exists(assetPath))
            {
                return;
            }

            var extension = Path.GetExtension(assetPath);
            if (exclude.Contains(extension))
            {
                return;
            }

            var guid = ToGuid(assetPath);
            Progress.Report(progressId, completed / (float)metaFiles.Length, assetPath);

            TrackGuid(guid);
            pathToGuidMap.TryAdd(assetPath, guid);
            guidToPathMap.TryAdd(guid, assetPath);

            var mfc = File.ReadAllText(mf);
            ScanDependencies(guid, mfc);

            using (var file = new StreamReader(assetPath))
            {
                var header = new char[5];
                if (file.ReadBlock(header, 0, header.Length) == header.Length &&
                    header[0] == '%' && header[1] == 'Y' && header[2] == 'A' && header[3] == 'M' && header[4] == 'L')
                {
                    var ac = file.ReadToEnd();
                    ScanDependencies(guid, ac);
                }
            }

            Progress.Report(progressId, ++completed / (float)metaFiles.Length);
        });
        Progress.Finish(progressId, Progress.Status.Succeeded);

        completed = 0;
        var total = pathToGuidMap.Count + guidToRefsMap.Count + guidFromRefsMap.Count;

        progressId = Progress.Start($"Indexing {total} dependencies");
        foreach (var kvp in pathToGuidMap)
        {
            var guid = kvp.Value;
            var path = kvp.Key;

            var ext = Path.GetExtension(path);
            if (ext.Length > 0 && ext[0] == '.')
            {
                ext = ext.Substring(1);
            }

            Progress.Report(progressId, completed++ / (float)total, path);

            var di = AddGuid(guid);

            index.AddExactWord("all", 0, di);
            AddStaticProperty("id", guid, di);
            AddStaticProperty("path", path, di);
            AddStaticProperty("t", GetExtension(path), di);
            index.AddWord(guid, guid.Length, 0, di);
            index.AddWord(Path.GetFileNameWithoutExtension(path), 0, di);
        }

        foreach (var kvp in guidToRefsMap)
        {
            var guid = kvp.Key;
            var refs = kvp.Value.Keys;
            var di   = AddGuid(guid);

            Progress.Report(progressId, completed++ / (float)total, guid);

            index.AddNumber("count", refs.Count, 0, di);
            foreach (var r in refs)
            {
                AddStaticProperty("to", r, di);
            }
        }

        foreach (var kvp in guidFromRefsMap)
        {
            var guid = kvp.Key;
            var refs = kvp.Value.Keys;
            var di   = AddGuid(guid);

            Progress.Report(progressId, completed++ / (float)total, guid);

            index.AddNumber("in", refs.Count, 0, di);
            foreach (var r in refs)
            {
                AddStaticProperty("from", r, di);

                if (guidToPathMap.TryGetValue(r, out var rp))
                {
                    AddStaticProperty("t", GetExtension(rp), di);
                }
            }

            if (guidToPathMap.TryGetValue(guid, out var path))
            {
                AddStaticProperty("is", "valid", di);
            }
            else
            {
                AddStaticProperty("is", "broken", di);

                var refString = string.Join(", ", refs.Select(r =>
                {
                    if (guidToPathMap.TryGetValue(r, out var rp))
                    {
                        return(rp);
                    }
                    return(r);
                }));
                index.GetDocument(di).metadata = $"Refered by {refString}";
            }
        }

        Progress.SetDescription(progressId, $"Saving dependency index at {dependencyIndexLibraryPath}");

        index.Finish((bytes) =>
        {
            File.WriteAllBytes(dependencyIndexLibraryPath, bytes);
            Progress.Finish(progressId, Progress.Status.Succeeded);

            Debug.Log($"Dependency indexing took {sw.Elapsed.TotalMilliseconds,3:0.##} ms " +
                      $"and was saved at {dependencyIndexLibraryPath} ({EditorUtility.FormatBytes(bytes.Length)} bytes)");
        }, removedDocuments: null);
    }