Log in Help
Print
HomegatepluginsJAPE_Plussrccomontotextjapepda 〉 SimpleSet.java
 
/*
 *  SimpleSet.java
 *
 *  Copyright (c) 2010-2011, Ontotext (www.ontotext.com).
 *
 *  This file is part of GATE (see http://gate.ac.uk/), and is free
 *  software, licenced under the GNU Library General Public License,
 *  Version 2, June 1991 (in the distribution as file licence.html,
 *  and also available at http://gate.ac.uk/gate/licence.html).
 *
 *
 *  $Id$
 */
package com.ontotext.jape.pda;

import gate.Annotation;

import java.util.ArrayList;

/**
 * This class stores an index of annotations. The index provides the following
 * functionalities: 1. Given i, for worst case constant time extracts the list
 * of all annotations with start node having offset i. 2. Given j, for worst
 * case constant time finds the smallest i >= j such that there is an annotation
 * with start node having offset i. The time complexity to build the index is
 * O(the length of the document).
 */
public class SimpleSet {

	/**
	 * annotations[i] is the list of all annotations with start node having
	 * offset i; annotations[i] is null iff there is not an annotation with
	 * start node having offset i.
	 */
	private ArrayList<Annotation>[] annotations;

	/**
	 * next[j] is the smallest i such that j <= i and annotations[i] != null. If
	 * there is not such i, then next[j] = -1.
	 */
	private int[] next;

	/**
	 * size is |{i : annotations[i] != 0}|
	 */
	private int size;

	/**
	 * The constructor. Allocates the whole needed space.
	 */
	@SuppressWarnings({"unchecked","rawtypes"})
	public SimpleSet(int documentLength) {
		annotations = new ArrayList[documentLength];
		next = new int[documentLength];
	}

	/**
	 * the get method retrieves a list of all annotations with start node having
	 * offset startOffset
	 * 
	 * @param startOffset
	 *            the offset to which the list should be retrieved.
	 * @return the list of all annotations with start node having offset elValue
	 *         or null if there is no annotation with start node having offset
	 *         elValue
	 */
	public ArrayList<Annotation> get(int startOffset) {
		return annotations[startOffset];
	}

	/**
	 * Adds annotation.
	 * 
	 * @param annot
	 *            the annotation to be added
	 */
	public void add(Annotation annot) {
		int offset = annot.getStartNode().getOffset().intValue();
		if (annotations[offset] == null) {
			annotations[offset] = new ArrayList<Annotation>();
			size++;
		}
		annotations[offset].add(annot);
	}

	/**
	 * Precomputes the index to be used by the firstStartAfter method. This
	 * method must be called when there are no more annotations to be added.
	 */
	public void finish() {
		int i, j;

		i = j = 0;
		while (true) {
			for (; j < annotations.length && annotations[j] == null; j++)
				;
			if (j == annotations.length) {
				for (; i < annotations.length; i++) {
					next[i] = -1;
				}
				break;
			}
			for (; i <= j; i++) {
				next[i] = j;
			}
			j++;
		}
	}

	/**
	 * If endOffset is the offset of the end node of some annotation, for worst
	 * case constant time returns the smallest i >= endOffset such that there is
	 * an annotation with start node having offset i. Returns -1 if no
	 * annotation starts after endOffset. If endOffset is 0, returns the
	 * smallest i such that there is an annotation with start node having offset
	 * i.
	 */
	public int firstStartOffsetAfter(int offset) {
		if (offset >= annotations.length) {
			return -1;
		}
		return next[offset];
	}

	/**
	 * @return true if there is no annotation added
	 */
	public boolean isEmpty() {
		return size == 0;
	}

	/**
	 * @return the number of distinct start offsets
	 */
	public int size() {
		return size;
	}
}