/* * 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; } }