/* * 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. */ package org.apache.geode.cache.lucene.internal.distributed; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import org.apache.geode.DataSerializer; import org.apache.geode.cache.lucene.LuceneQueryFactory; import org.apache.geode.internal.DataSerializableFixedID; import org.apache.geode.internal.Version; /** * Holds a ordered collection of entries matching a search query. * * @param <K> the type of key */ public class TopEntries<K> implements DataSerializableFixedID { // ordered collection of entries private List<EntryScore<K>> hits = new ArrayList<>(); // the maximum number of entries stored in this private int limit; // comparator to order entryScore instances final Comparator<EntryScore<K>> comparator = new EntryScoreComparator(); public TopEntries() { this(LuceneQueryFactory.DEFAULT_LIMIT); } public TopEntries(int limit) { if (limit < 0) { throw new IllegalArgumentException(); } this.limit = limit; } /** * Adds an entry to the collection. The new entry must have a lower score than all previous * entries added to the collection. The new entry will be ignored if the limit is already reached. * * @param entry */ public void addHit(EntryScore<K> entry) { if (hits.size() > 0) { EntryScore lastEntry = hits.get(hits.size() - 1); if (comparator.compare(lastEntry, entry) < 0) { throw new IllegalArgumentException(); } } if (hits.size() >= limit) { return; } hits.add(entry); } /** * @return count of entries in the collection */ public int size() { return hits.size(); } /** * @return The entries collection managed by this instance */ public List<EntryScore<K>> getHits() { return hits; } /** * @return The maximum capacity of this collection */ public int getLimit() { return limit; } /** * Compares scores of two entries using natural ordering. I.e. it returns -1 if the first entry's * score is less than the second one. */ class EntryScoreComparator implements Comparator<EntryScore<K>> { @Override public int compare(EntryScore<K> o1, EntryScore<K> o2) { return Float.compare(o1.getScore(), o2.getScore()); } } @Override public Version[] getSerializationVersions() { // TODO Auto-generated method stub return null; } @Override public int getDSFID() { return LUCENE_TOP_ENTRIES; } @Override public void toData(DataOutput out) throws IOException { out.writeInt(limit); DataSerializer.writeObject(hits, out); } @Override public void fromData(DataInput in) throws IOException, ClassNotFoundException { limit = in.readInt(); hits = DataSerializer.readObject(in); }; }