solr&lucene3.6.0源码解析(二)

2019-03-27 01:13|来源: 网路

上文描述了solr3.6.0怎么采用maven管理的方式在eclipse中搭建开发环境,在solr中,为了提高搜索性能,采用了缓存机制,这里描述的是LRU缓存,这里用到了 LinkedHashMap类

要基于LinkedHashMap来实现LRU缓存,我们可以选择inheritance, 也可以选择 delegation, 下面是基于delegation的实现方式:

import java.util.LinkedHashMap;
import java.util.Collection;
import java.util.Map;
import java.util.ArrayList;

/**
 * An LRU cache, based on <code>LinkedHashMap</code>.
 * 
 * <p>
 * This cache has a fixed maximum number of elements (<code>cacheSize</code>).
 * If the cache is full and another entry is added, the LRU (least recently
 * used) entry is dropped.
 * 
 * <p>
 * This class is thread-safe. All methods of this class are synchronized.
 * 
 * <p>
 * Author: Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland<br>
 * Multi-licensed: EPL / LGPL / GPL / AL / BSD.
 */
public class LRUCache<K, V> {

    private static final float hashTableLoadFactor = 0.75f;

    private LinkedHashMap<K, V> map;
    private int cacheSize;

    /**
     * Creates a new LRU cache.
     * 
     * @param cacheSize
     *            the maximum number of entries that will be kept in this cache.
     */
    public LRUCache(int cacheSize) {
        this.cacheSize = cacheSize;
        int hashTableCapacity = (int) Math
                .ceil(cacheSize / hashTableLoadFactor) + 1;
        map = new LinkedHashMap<K, V>(hashTableCapacity, hashTableLoadFactor,
                true) {
            // (an anonymous inner class)
            private static final long serialVersionUID = 1;

            @Override
            protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
                return size() > LRUCache.this.cacheSize;
            }
        };
    }

    /**
     * Retrieves an entry from the cache.<br>
     * The retrieved entry becomes the MRU (most recently used) entry.
     * 
     * @param key
     *            the key whose associated value is to be returned.
     * @return the value associated to this key, or null if no value with this
     *         key exists in the cache.
     */
    public synchronized V get(K key) {
        return map.get(key);
    }

    /**
     * Adds an entry to this cache. The new entry becomes the MRU (most recently
     * used) entry. If an entry with the specified key already exists in the
     * cache, it is replaced by the new entry. If the cache is full, the LRU
     * (least recently used) entry is removed from the cache.
     * 
     * @param key
     *            the key with which the specified value is to be associated.
     * @param value
     *            a value to be associated with the specified key.
     */
    public synchronized void put(K key, V value) {
        map.put(key, value);
    }

    /**
     * Clears the cache.
     */
    public synchronized void clear() {
        map.clear();
    }

    /**
     * Returns the number of used entries in the cache.
     * 
     * @return the number of entries currently in the cache.
     */
    public synchronized int usedEntries() {
        return map.size();
    }

    /**
     * Returns a <code>Collection</code> that contains a copy of all cache
     * entries.
     * 
     * @return a <code>Collection</code> with a copy of the cache content.
     */
    public synchronized Collection<Map.Entry<K, V>> getAll() {
        return new ArrayList<Map.Entry<K, V>>(map.entrySet());
    }

    // Test routine for the LRUCache class.
    public static void main(String[] args) {
        LRUCache<String, String> c = new LRUCache<String, String>(3);
        c.put("1", "one"); // 1
        c.put("2", "two"); // 2 1
        c.put("3", "three"); // 3 2 1
        c.put("4", "four"); // 4 3 2
        if (c.get("2") == null)
            throw new Error(); // 2 4 3
        c.put("5", "five"); // 5 2 4
        c.put("4", "second four"); // 4 5 2
        // Verify cache content.
        if (c.usedEntries() != 3)
            throw new Error();
        if (!c.get("4").equals("second four"))
            throw new Error();
        if (!c.get("5").equals("five"))
            throw new Error();
        if (!c.get("2").equals("two"))
            throw new Error();
        // List cache content.
        for (Map.Entry<String, String> e : c.getAll())
            System.out.println(e.getKey() + " : " + e.getValue());
    }

} // end class LRUCache
// ------------------------------------------------------------------------------------------

--------------------------------------------------------------------------- 

本系列solr&lucene3.6.0源码解析系本人原创 

转载请注明出处 博客园 刺猬的温驯 

本人邮箱: chenying998179#163.com (#改为@)

本文链接http://www.cnblogs.com/chenying99/p/3440812.html 


转自:http://www.cnblogs.com/chenying99/p/3440812

相关问答

更多
  • @darkheir:Lucene和Solr是两个不同的Apache项目,一起工作,我不明白每个项目的目的是什么。 1)Solr在底漆下使用Lucene。 Lucene没有关于Solr API的线索。 2)Lucene是一个功能强大的搜索引擎框架,可以让我们为我们的应用程序添加搜索功能。 它暴露了一个易于使用的API,同时隐藏所有与搜索相关的复杂操作。 任何应用程序都可以使用这个库,而不仅仅是Solr。 3)Solr是围绕Lucene建造的。 Lucene不仅仅是一个http包装,而且已经知道可以向Lucen ...
  • Lucene是一个用Java构建的搜索库,而Solr和Elastic Search(ES)是使用Lucene的Web应用程序。 在大多数情况下,您更喜欢Solr或ES到Lucene,主要是因为开箱即用的机制:多个节点上的分布式搜索,复制,分片和索引管理。 因为使用自定义Java应用程序和Lucene很难实现和维护这样的机制。 你会选择Lucene: 要有更多的控制权,因为它只是一个没有严格依赖关系的jar; 你不希望被任何特定的服务器约束; 您不希望构建自动化以在生产中部署Solr或ES(使用他们的服务器, ...
  • 您的案例中的搜索条件是不同的。 您需要使用solr.SynonymFilterFactory并将此组合定义为同义词。 查看上面链接中的示例。 这将使您能够搜索香港和香港,并仍然可以得到结果。 通常WordDelimiterFilterFactory将用于没有空间的组合。 它用于您想要以任意组合进行搜索的情况下更改案例或字母数字组合。 例如 无线网络应该可以通过wifi,wifi,wifi等搜索.... iPhone应该可以搜索iphone,iPhone,手机等... j2se可以通过j2se,j 2 se等 ...
  • Solr 100%是否要求Lucene作为后端? 是。 没有Lucene,Solr无法运行。 它可能是一个独立的应用程序,但它使用Lucene的核心。 至于您是否可以将索引存储在数据库中,这似乎建议您可以: https : //stackoverflow.com/a/17371651/2039359(通过扩展指向使用JdbcDirectory在数据库中创建Lucene索引 ) 指南针,但似乎已经不复存在( http://thedudeabides.com/articles/the_future_of_com ...
  • Lucene使用Vector空间模型的概念来计算文档的分数。 总之,查询和文档可以看作是矢量。 为了计算特定查询的文档分数,Lucene计算每个文档向量与查询向量的距离。 VSM查询附近的文档越多,分数越高。 你可以通过查看Lucene的Similarity类和Lucene的Scoring文档来获得更多的细节。 Lucene uses concepts from the Vector space model to compute the score of documents. In summary, que ...
  • 给定完全相同的索引,结果对于确定性查询应该是相同的(记住查询可以取决于一天中的时间等)。 否则分页等会表现得很奇怪。 但这假设所有因素都完全相同 - 相同的索引,相同的Solr版本,相同的底层JVM(我确信这里也存在差异)。 Given the exact same index, the results should be identical for deterministic queries (remember that queries can be dependent on the time of da ...
  • 虽然帖子已经存在了一段时间,但你可以看看这个帖子https://github.com/SpringSource/spring-data-solr/ I found a good read here - http://adeithzya.wordpress.com/2011/08/25/using-apache-solr-with-spring-framework - that hits the nail on its head!
  • 使用Solr的bin/post工具和Tika处理程序(名为ExtractingRequestHandler),您应该可以快速启动并运行原型进行原型设计。 请参阅使用Apache Tika上传使用Solr Cell上传数据的介绍。 Tika用于处理各种不同的文档类型。 您可以为Solr post工具提供目录或要提交到索引的文件列表 。 自动检测文件夹中的内容类型,并递归扫描文档以便索引到gettingstarted。 bin/post -c gettingstarted afolder/ Using the ...
  • 由于Solr&Lucene是同一项目的一部分。 它建议你使用相同的Solr和Lucene 3.5版本。 在Lucene版本之间必须更改索引格式,如果是这样,索引肯定会不兼容。 但是当您使用Lucene构建索引并通过Solr公开它时,您可以在solrconfig.xml中相应地检查luceneMatchVersion参数,看它是否有效。 LUCENE_30 As the Solr & Lucene are part of th ...
  • 我们可以定制嵌入在Solr中的Lucene吗? 是的,你可以 。 但请记住这一点: Lucene和Solr提交者是全文搜索领域的一些最重要的专家。 他们在这个领域有多年的经验。 如果你认为你可以比他们做得更好,那么继续改变Solr以满足你的需求(它是Apache许可的,所以没有任何商业限制),如果你这样做,试着这样做,以便你以后可以贡献它回到项目,这样每个人都可以受益,项目也会向前发展。 对于绝大多数Solr用户而言,库存产品绰绰有余并满足所有需求。 换句话说,在进入更改代码之前,在邮件列表(stackov ...