Пример #1
0
    // 根据记录数量的多少,少的时候可以立即返回结果,多的时候用线程后台处理,然后可以随时查询状态
    // 线程用线程池,避免过多耗用线程数目

    // 根据结果集名,提取全部书目 XML 记录,然后批处理经过 MarcFilter 过滤,创建若干个子结果集
    // 最基本的功能是返回子结果集的显示名,文件名,包含记录数量,供前端显示在界面上
    // 较为深入的功能是,将子结果集按照 key 排序归并,而显示出二级条目和数量。二级结果集是子结果集的子结果集

    // TODO: 如何及时清理Task对象,避免内存过度膨胀? 是否仅保存最新10个Task对象?
    void GetFilterInfo(
        string strResultsetName,
        string strSelected,
        string strLang)
    {
        string        strError    = "";
        GetFilterInfo result_info = new GetFilterInfo();

        if (string.IsNullOrEmpty(strResultsetName) == true)
        {
            strError = "结果集名不应为空";
            goto ERROR1;
        }

        FilterTask t = app.FindFilterTask(strResultsetName);    // Task对象是利用 Session 内结果集名来进行管理的

        if (t == null)
        {
            // 如果一个结果集还没有被后台任务处理,就立即启动一个后台任务
            t = new FilterTask();
            app.SetFilterTask(strResultsetName, t);

            string strGlobalResultSetName = "";
            bool   bShare = false;

            if (strResultsetName[0] == '#')
            {
                strGlobalResultSetName = strResultsetName.Substring(1);
            }
            else
            {
                // 构造全局结果集名
                strGlobalResultSetName = sessioninfo.GetHashCode() + "_" + strResultsetName;

                LibraryChannel channel = sessioninfo.GetChannel(true);
                try
                {
                    // 先把结果集共享
                    // 管理结果集
                    // parameters:
                    //      strAction   share/remove 分别表示共享为全局结果集对象/删除全局结果集对象
                    long lRet = // sessioninfo.Channel.
                                channel.ManageSearchResult(
                        null,
                        "share",
                        strResultsetName,
                        strGlobalResultSetName,
                        out strError);
                    if (lRet == -1)
                    {
                        goto ERROR1;
                    }

                    bShare = true;
                }
                finally
                {
                    sessioninfo.ReturnChannel(channel);
                }
            }

            FilterTaskInput i = new FilterTaskInput();
            i.App            = app;
            i.FilterFileName = Path.Combine(app.DataDir, "cfgs/facet.fltx");
            i.ResultSetName  = strGlobalResultSetName;
            i.ShareResultSet = bShare;
            // i.SessionInfo = sessioninfo;
            i.TempDir  = app.TempDir;
            i.TaskName = strResultsetName;  // Task对象是利用Session内结果集名来进行管理的
            i.MaxCount = 1000;
            // i.aggregation_names = new List<string>() {"author"};

            XmlDocument def_dom = GetFacetDefDom(out strError);
            if (def_dom == null)
            {
                goto ERROR1;
            }
            i.DefDom = def_dom;

            ThreadPool.QueueUserWorkItem(t.ThreadPoolCallBack, i);
            strError = "#pending";  // 表示正在处理,希望前端稍后重新访问
            goto ERROR1;
        }
        else
        {
            if (t.TaskState == TaskState.Processing)
            {
                if (t.ProgressRange != 0)
                {
                    result_info.ProgressValue = (int)(((double)t.ProgressValue / (double)t.ProgressRange) * 100);
                }
                strError = "#pending";  // 表示正在处理,希望前端稍后重新访问
                goto ERROR1;
            }
            if (string.IsNullOrEmpty(t.ErrorInfo) == false)
            {
                strError = t.ErrorInfo;
                goto ERROR1;
            }

            GC.Collect();   // 试着释放 Hashtable 等

            long lHitCount = MyWebPage.GetServerResultCount(sessioninfo, strResultsetName);

            XmlDocument def_dom = GetFacetDefDom(out strError);
            if (def_dom == null)
            {
                goto ERROR1;
            }
            this.m_facetDom = def_dom;
            this.m_strLang  = strLang;

            try
            {
                // 创建FilterInfo数组
                result_info.Items = ResultsetFilter.BuildFilterInfos(
                    strResultsetName,
                    lHitCount,
                    strSelected,
                    GetKeyNameCaption,
                    t.ResultItems,
                    app.TempDir,    // sessioninfo.GetTempDir(),
                    10);
                // GC.Collect();    // 担心 DpResultSet 未能回收
            }
            catch (Exception ex)
            {
                strError = ExceptionUtil.GetAutoText(ex);
                goto ERROR1;
            }

            if (t.HitCount > 1000)
            {
                result_info.Comment = "分面导航只提取了当前结果集的前 1000 条记录";
            }
        }

        // 返回一级节点的名字和包含记录数量
        this.Response.Write(MyWebPage.GetResultString(result_info));
        this.Response.End();
        return;

ERROR1:
        result_info.ErrorString = strError;
        this.Response.Write(MyWebPage.GetResultString(result_info));
        this.Response.End();
    }