Lucene.Net  3.0.3
Lucene.Net is a .NET port of the Java Lucene Indexing Library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties
FilterManager.cs
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 using System;
19 using System.Collections.Generic;
20 using System.Linq;
21 using Lucene.Net.Support;
22 
23 namespace Lucene.Net.Search
24 {
25 
37  public class FilterManager
38  {
39 
40  protected internal static FilterManager manager;
41 
43  protected internal const int DEFAULT_CACHE_CLEAN_SIZE = 100;
45  protected internal const long DEFAULT_CACHE_SLEEP_TIME = 1000 * 60 * 10;
46 
48  protected internal IDictionary<int, FilterItem> cache;
50  protected internal int cacheCleanSize;
52  protected internal long cleanSleepTime;
54  protected internal FilterCleaner internalFilterCleaner;
55 
56  private static readonly object _staticSyncObj = new object();
57  public static FilterManager Instance
58  {
59  get
60  {
61  lock (_staticSyncObj)
62  {
63  return manager ?? (manager = new FilterManager());
64  }
65  }
66  }
67 
69  protected internal FilterManager()
70  {
71  cache = new HashMap<int, FilterItem>();
72  cacheCleanSize = DEFAULT_CACHE_CLEAN_SIZE; // Let the cache get to 100 items
73  cleanSleepTime = DEFAULT_CACHE_SLEEP_TIME; // 10 minutes between cleanings
74 
75  internalFilterCleaner = new FilterCleaner(this);
76  ThreadClass fcThread = new ThreadClass(new System.Threading.ThreadStart(internalFilterCleaner.Run));
77  // setto be a Daemon so it doesn't have to be stopped
78  fcThread.IsBackground = true;
79  fcThread.Start();
80  }
81 
84  public virtual void SetCacheSize(int value)
85  {
86  this.cacheCleanSize = value;
87  }
88 
91  public virtual void SetCleanThreadSleepTime(long value)
92  {
93  this.cleanSleepTime = value;
94  }
95 
105  public virtual Filter GetFilter(Filter filter)
106  {
107  lock (cache)
108  {
109  FilterItem fi = null;
110  fi = cache[filter.GetHashCode()];
111  if (fi != null)
112  {
113  fi.timestamp = System.DateTime.UtcNow.Ticks;
114  return fi.filter;
115  }
116  cache[filter.GetHashCode()] = new FilterItem(filter);
117  return filter;
118  }
119  }
120 
125  protected internal class FilterItem
126  {
127  public Filter filter;
128  public long timestamp;
129 
130  public FilterItem(Filter filter)
131  {
132  this.filter = filter;
133  this.timestamp = System.DateTime.UtcNow.Ticks;
134  }
135  }
136 
137 
151  protected internal class FilterCleaner : IThreadRunnable
152  {
153  private class FilterItemComparer : IComparer<KeyValuePair<int, FilterItem>>
154  {
155  #region IComparer<FilterItem> Members
156 
157  public int Compare(KeyValuePair<int, FilterItem> x, KeyValuePair<int, FilterItem> y)
158  {
159  return x.Value.timestamp.CompareTo(y.Value.timestamp);
160  }
161 
162  #endregion
163  }
164 
165  private bool running = true;
166  private FilterManager manager;
167  private ISet<KeyValuePair<int, FilterItem>> sortedFilterItems;
168 
169  public FilterCleaner(FilterManager enclosingInstance)
170  {
171  this.manager = enclosingInstance;
172  sortedFilterItems = new SortedSet<KeyValuePair<int, FilterItem>>(new FilterItemComparer());
173  }
174 
175  public virtual void Run()
176  {
177  while (running)
178  {
179  // sort items from oldest to newest
180  // we delete the oldest filters
181  if (this.manager.cache.Count > this.manager.cacheCleanSize)
182  {
183  // empty the temporary set
184  sortedFilterItems.Clear();
185  lock (this.manager.cache)
186  {
187  sortedFilterItems.UnionWith(this.manager.cache);
188  int numToDelete = (int)((this.manager.cache.Count - this.manager.cacheCleanSize) * 1.5);
189 
190  //delete all of the cache entries not used in a while
191  sortedFilterItems.ExceptWith(sortedFilterItems.Take(numToDelete).ToArray());
192  }
193  // empty the set so we don't tie up the memory
194  sortedFilterItems.Clear();
195  }
196  // take a nap
197  System.Threading.Thread.Sleep(new System.TimeSpan((System.Int64)10000 * this.manager.cleanSleepTime));
198 
199  }
200  }
201  }
202  }
203 }