public override int GetOrdinal(FacetLabel cp) { EnsureOpen(); if (cp.Length == 0) { return(ROOT_ORDINAL); } // First try to find the answer in the LRU cache: // LUCENENET: Lock was removed here because the underlying cache is thread-safe, // and removing the lock seems to make the performance better. Int32Class res = ordinalCache.Get(cp); if (res != null) { if ((int)res.Value < indexReader.MaxDoc) { // Since the cache is shared with DTR instances allocated from // doOpenIfChanged, we need to ensure that the ordinal is one that // this DTR instance recognizes. return((int)res.Value); } else { // if we get here, it means that the category was found in the cache, // but is not recognized by this TR instance. Therefore there's no // need to continue search for the path on disk, because we won't find // it there too. return(TaxonomyReader.INVALID_ORDINAL); } } // If we're still here, we have a cache miss. We need to fetch the // value from disk, and then also put it in the cache: int ret = TaxonomyReader.INVALID_ORDINAL; DocsEnum docs = MultiFields.GetTermDocsEnum(indexReader, null, Consts.FULL, new BytesRef(FacetsConfig.PathToString(cp.Components, cp.Length)), 0); if (docs != null && docs.NextDoc() != DocIdSetIterator.NO_MORE_DOCS) { ret = docs.DocID; // we only store the fact that a category exists, not its inexistence. // This is required because the caches are shared with new DTR instances // that are allocated from doOpenIfChanged. Therefore, if we only store // information about found categories, we cannot accidently tell a new // generation of DTR that a category does not exist. // LUCENENET: Lock was removed here because the underlying cache is thread-safe, // and removing the lock seems to make the performance better. ordinalCache.Put(cp, new Int32Class { Value = Convert.ToInt32(ret) }); } return(ret); }
public override FacetLabel GetPath(int ordinal) { EnsureOpen(); // Since the cache is shared with DTR instances allocated from // doOpenIfChanged, we need to ensure that the ordinal is one that this DTR // instance recognizes. Therefore we do this check up front, before we hit // the cache. if (ordinal < 0 || ordinal >= indexReader.MaxDoc) { return(null); } // TODO: can we use an int-based hash impl, such as IntToObjectMap, // wrapped as LRU? int catIDInteger = Convert.ToInt32(ordinal); lock (categoryCache) { var res = categoryCache.Get(catIDInteger, false); if (res != null) { return(res); } } Document doc = indexReader.Document(ordinal); FacetLabel ret = new FacetLabel(FacetsConfig.StringToPath(doc.Get(Consts.FULL))); lock (categoryCache) { categoryCache.Put(catIDInteger, ret); } return(ret); }
public virtual void TestLru() { LRUHashMap<string, string> lru = new LRUHashMap<string, string>(3); Assert.AreEqual(0, lru.Size()); lru.Put("one", "Hello world"); Assert.AreEqual(1, lru.Size()); lru.Put("two", "Hi man"); Assert.AreEqual(2, lru.Size()); lru.Put("three", "Bonjour"); Assert.AreEqual(3, lru.Size()); lru.Put("four", "Shalom"); Assert.AreEqual(3, lru.Size()); Assert.NotNull(lru.Get("three")); Assert.NotNull(lru.Get("two")); Assert.NotNull(lru.Get("four")); Assert.Null(lru.Get("one")); lru.Put("five", "Yo!"); Assert.AreEqual(3, lru.Size()); Assert.Null(lru.Get("three")); // three was last used, so it got removed Assert.NotNull(lru.Get("five")); lru.Get("four"); lru.Put("six", "hi"); lru.Put("seven", "hey dude"); Assert.AreEqual(3, lru.Size()); Assert.Null(lru.Get("one")); Assert.Null(lru.Get("two")); Assert.Null(lru.Get("three")); Assert.NotNull(lru.Get("four")); Assert.Null(lru.Get("five")); Assert.NotNull(lru.Get("six")); Assert.NotNull(lru.Get("seven")); }