Exemplo n.º 1
0
        public void ThreadPoolCallBack(object context)
        {
            FilterTaskInput input = (FilterTaskInput)context;

            string strError = "";

#if NO
            // 临时的SessionInfo对象
            SessionInfo session = new SessionInfo(input.App);
            session.UserID   = input.App.ManagerUserName;
            session.Password = input.App.ManagerPassword;
            session.IsReader = false;
#endif
            LibraryChannel channel = input.App.GetChannel();

            try
            {
                Hashtable result_table = null;
                long      lHitCount    = 0;
                int       nRet         = ResultsetFilter.DoFilter(
                    input.App,
                    channel,    // session.Channel,
                    input.ResultSetName,
                    input.FilterFileName,
                    input.MaxCount,
                    _SetProgress,
                    ref result_table,
                    out lHitCount,
                    out strError);
                if (nRet == -1)
                {
                    this.ErrorInfo = strError;
                    this.TaskState = TaskState.Done;
                    return;
                }

                this.HitCount = lHitCount;

                // 继续加工
                List <NodeInfo> output_items = null;
                nRet = ResultsetFilter.BuildResultsetFile(result_table,
                                                          input.DefDom,
                                                                         // input.aggregation_names,
                                                          input.TempDir, // input.SessionInfo.GetTempDir(),
                                                          out output_items,
                                                          out strError);
                if (nRet == -1)
                {
                    this.ErrorInfo = strError;
                    this.TaskState = TaskState.Done;
                    return;
                }

                {
                    this.ResultItems = output_items;
                    this.TaskState   = TaskState.Done;
                }

                if (input.ShareResultSet == true)
                {
                    // 删除全局结果集对象
                    // 管理结果集
                    // parameters:
                    //      strAction   share/remove 分别表示共享为全局结果集对象/删除全局结果集对象
                    long lRet = // session.Channel.
                                channel.ManageSearchResult(
                        null,
                        "remove",
                        "",
                        input.ResultSetName,
                        out strError);
                    if (lRet == -1)
                    {
                        this.ErrorInfo = strError;
                    }

                    input.ShareResultSet = false;
                    input.ResultSetName  = "";
                }
            }
            finally
            {
#if NO
                session.CloseSession();
#endif
                input.App.ReturnChannel(channel);
            }

#if NO
            if (input.SessionInfo != null && string.IsNullOrEmpty(input.TaskName) == false)
            {
                input.SessionInfo.SetFilterTask(input.TaskName, this);
            }
#endif
            input.App.SetFilterTask(input.TaskName, this);
        }
Exemplo n.º 2
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;
        }
#if NO
        Hashtable result_table = null;
        string strFilterFileName = PathUtil.MergePath(app.DataDir, "cfgs/facet.fltx");
        int nRet = ResultsetFilter.DoFilter(
            app,
            sessioninfo.Channel,
            strResultsetName,
            strFilterFileName,
            1000,
            ref result_table,
            out strError);
        if (nRet == -1)
            goto ERROR1;
#endif
        FilterTask t = sessioninfo.FindFilterTask(strResultsetName);    // Task对象是利用Session内结果集名来进行管理的
        if (t == null)
        {
            // 如果一个结果集还没有被后台任务处理,就立即启动一个后台任务
            t = new FilterTask();
            sessioninfo.SetFilterTask(strResultsetName, t);

            string strGlobalResultSetName = "";
            bool bShare = false;

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

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

                bShare = true;
            }

            FilterTaskInput i = new FilterTaskInput();
            i.App = app;
            i.FilterFileName = PathUtil.MergePath(app.DataDir, "cfgs/facet.fltx");
            i.ResultSetName = strGlobalResultSetName;
            i.ShareResultSet = bShare;
            i.SessionInfo = sessioninfo;
            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;
            }

#if NO
            string[] names = new string[t.ResultTable.Keys.Count];
            t.ResultTable.Keys.CopyTo(names, 0);
            Array.Sort(names);

            List<FilterInfo> infos = new List<FilterInfo>();
            foreach (string strName in names)
            {
                KeyValueCollection items = (KeyValueCollection)t.ResultTable[strName];
                FilterInfo info = new FilterInfo();
                info.Name = strName;
                if (items != null)
                    info.Count = items.Count.ToString();
                else
                    info.Count = "0";

                infos.Add(info);
            }
            result_info.Items = new FilterInfo[infos.Count];
            infos.CopyTo(result_info.Items);
#endif

#if NO
            Hashtable keyname_table = null;
            // 获得名称对照表
            // parameters:
            //      keyname_table   keyname --> 当前语言的名称
            int nRet = ResultsetFilter.GetKeyNameTable(
                app,
                PathUtil.MergePath(app.DataDir, "cfgs/facet.fltx"),
                t.ResultItems,
                string.IsNullOrEmpty(strLang) == true ? Thread.CurrentThread.CurrentUICulture.Name : strLang,
                out keyname_table,
                out strError);
            if (nRet == -1)
                goto ERROR1;
#endif

            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,
                    sessioninfo.GetTempDir(),
                    10);
            }
            catch (Exception ex)
            {
                strError = ex.Message;
                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();
    }
Exemplo n.º 3
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();
    }