Example #1
0
        void ClearFilterTask()
        {
            // string strTempDir = this.GetTempDir();
            string strTempDir = this.TempDir;

            List <FilterTask> delete_items = new List <FilterTask>();

            _filterTaskLock.EnterWriteLock();
            try
            {
                foreach (string key in this.FilterTasks.Keys)
                {
                    FilterTask task = (FilterTask)this.FilterTasks[key];
                    if (task != null)
                    {
                        delete_items.Add(task);
                    }
                }
                this.FilterTasks.Clear();
            }
            finally
            {
                _filterTaskLock.ExitWriteLock();
            }

            foreach (FilterTask task in delete_items)
            {
                task.DeleteTempFiles(strTempDir);
            }
        }
Example #2
0
 public FilterTask FindFilterTask(string strName)
 {
     _filterTaskLock.EnterReadLock();
     try
     {
         FilterTask task = (FilterTask)this.FilterTasks[strName];
         if (task != null)
         {
             task.Touch();
         }
         return(task);
     }
     finally
     {
         _filterTaskLock.ExitReadLock();
     }
 }
Example #3
0
        // parameters:
        //      task    要设置的 FilterTask 对象。如果为 null,表示要删除名字为 strName 的对象
        public void SetFilterTask(string strName, FilterTask task)
        {
            _filterTaskLock.EnterWriteLock();
            try
            {
                FilterTask old_task = (FilterTask)this.FilterTasks[strName];
                if (old_task == task)
                {
                    if (old_task != null)
                    {
                        old_task.Touch();
                    }
                    return;
                }

                // 删除任务所创建的结果集文件
                if (old_task != null)
                {
                    old_task.DeleteTempFiles(
                        // this.GetTempDir()
                        this.TempDir
                        );
                }

                // TODO: 是否要定义一个极限值,不让元素数超过这个数目
                if (task == null)
                {
                    this.FilterTasks.Remove(strName);
                }
                else
                {
                    task.Touch();
                    this.FilterTasks[strName] = task;
                }
            }
            finally
            {
                _filterTaskLock.ExitWriteLock();
            }
        }
Example #4
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();
    }
Example #5
0
        // 清除最近没有使用过的 FilterTask 对象
        // parameters:
        //      delta   最近一次用过的时刻距离现在的时间长度。长于这个的对象才会被清除
        public void CleanFilterTask(TimeSpan delta)
        {
            List <string> remove_keys = new List <string>();

            // 第一步,找出过期的 key
            // 读锁定并不阻碍一般性访问
            _filterTaskLock.EnterReadLock();
            try
            {
                foreach (string key in this.FilterTasks.Keys)
                {
                    FilterTask task = (FilterTask)this.FilterTasks[key];
                    if (task == null ||
                        (DateTime.Now - task.LastUsedTime) >= delta)
                    {
                        remove_keys.Add(key);   // 这里暂时无法删除,因为 foreach 还要用枚举器
                    }
                }
            }
            finally
            {
                _filterTaskLock.ExitReadLock();
            }

            if (remove_keys.Count == 0)
            {
                return;
            }

            // 第二步,清除 hashtable 中的对象
            // 因为要删除某些元素,所以用写锁定
            List <FilterTask> delete_items = new List <FilterTask>();

            _filterTaskLock.EnterWriteLock();
            try
            {
                foreach (string key in remove_keys)
                {
                    FilterTask task = (FilterTask)this.FilterTasks[key];
                    if (task == null)
                    {
                        continue;
                    }

                    // 和 hashtable 脱离关系
                    this.FilterTasks.Remove(key);

                    delete_items.Add(task);
                }
            }
            finally
            {
                _filterTaskLock.ExitWriteLock();
            }

            // 第三步,删除临时文件
            string strTempDir = this.TempDir;

            foreach (FilterTask task in delete_items)
            {
                task.DeleteTempFiles(strTempDir);
            }
        }
Example #6
0
        public void SetFilterTask(string strName, FilterTask task)
        {
            lock (this.FilterTasks)
            {
                FilterTask old_task = (FilterTask)this.FilterTasks[strName];
                if (old_task == task)
                    return;

                // 删除任务所创建的结果集文件
                if (old_task != null)
                    old_task.DeleteTempFiles(this.GetTempDir());

                if (task == null)
                    this.FilterTasks.Remove(strName);
                else
                    this.FilterTasks[strName] = task;
            }
        }
Example #7
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();
    }
Example #8
0
        // parameters:
        //      task    要设置的 FilterTask 对象。如果为 null,表示要删除名字为 strName 的对象
        public void SetFilterTask(string strName, FilterTask task)
        {
            _filterTaskLock.EnterWriteLock();
            try
            {
                FilterTask old_task = (FilterTask)this.FilterTasks[strName];
                if (old_task == task)
                {
                    if (old_task != null)
                        old_task.Touch();
                    return;
                }

                // 删除任务所创建的结果集文件
                if (old_task != null)
                    old_task.DeleteTempFiles(
                        // this.GetTempDir()
                        this.TempDir
                        );

                // TODO: 是否要定义一个极限值,不让元素数超过这个数目
                if (task == null)
                    this.FilterTasks.Remove(strName);
                else
                {
                    task.Touch();
                    this.FilterTasks[strName] = task;
                }
            }
            finally
            {
                _filterTaskLock.ExitWriteLock();
            }
        }