/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Runtime.CompilerServices;
using Lucene.Net.Index;
using Spatial4n.Core.Shapes;
#if NET35
using Lucene.Net.Support;
#endif
namespace Lucene.Net.Spatial.Util
{
///
/// Provides access to a {@link ShapeFieldCache} for a given {@link AtomicReader}.
///
/// If a Cache does not exist for the Reader, then it is built by iterating over
/// the all terms for a given field, reconstructing the Shape from them, and adding
/// them to the Cache.
///
///
public abstract class ShapeFieldCacheProvider where T : Shape
{
//private Logger log = Logger.getLogger(getClass().getName());
// it may be a List or T
#if !NET35
private readonly ConditionalWeakTable> sidx =
new ConditionalWeakTable>(); // WeakHashMap
#else
private readonly WeakDictionary> sidx =
new WeakDictionary>();
#endif
protected readonly int defaultSize;
protected readonly String shapeField;
protected ShapeFieldCacheProvider(String shapeField, int defaultSize)
{
this.shapeField = shapeField;
this.defaultSize = defaultSize;
}
protected abstract T ReadShape(/*BytesRef*/ Term term);
private readonly object locker = new object();
public ShapeFieldCache GetCache(IndexReader reader)
{
lock (locker)
{
ShapeFieldCache idx;
if (sidx.TryGetValue(reader, out idx) && idx != null)
{
return idx;
}
//long startTime = System.CurrentTimeMillis();
//log.fine("Building Cache [" + reader.MaxDoc() + "]");
idx = new ShapeFieldCache(reader.MaxDoc, defaultSize);
var count = 0;
var tec = new TermsEnumCompatibility(reader, shapeField);
var term = tec.Next();
while (term != null)
{
var shape = ReadShape(term);
if (shape != null)
{
var docs = reader.TermDocs(new Term(shapeField, tec.Term().Text));
while (docs.Next())
{
idx.Add(docs.Doc, shape);
count++;
}
}
term = tec.Next();
}
sidx.Add(reader, idx);
tec.Close();
//long elapsed = System.CurrentTimeMillis() - startTime;
//log.fine("Cached: [" + count + " in " + elapsed + "ms] " + idx);
return idx;
}
}
}
}