FlexGazMappingTable.java
001 /*
002  * Copyright (c) 2012, The University of Sheffield.
003  
004  * This file is part of GATE (see http://gate.ac.uk/), and is free software,
005  * licenced under the GNU Library General Public License, Version 2, June1991.
006  
007  * A copy of this licence is included in the distribution in the file
008  * licence.html, and is also available at http://gate.ac.uk/gate/licence.html.
009  * $Id: FlexGazMappingTable.java 16102 2012-10-01 11:35:43Z adamfunk $
010  */
011 package gate.creole.gazetteer;
012 
013 import java.util.*;
014 
015 public class FlexGazMappingTable {
016   
017   private Map<Long, NodePosition> startMap;
018   private Map<Long, NodePosition> endMap;
019   private long[] tempStartOffsets;
020   private long[] tempEndOffsets;
021   private boolean updated;
022   private int size;
023   
024   
025   public FlexGazMappingTable() {
026     startMap = new HashMap<Long, NodePosition>();
027     endMap = new HashMap<Long, NodePosition>();
028     tempStartOffsets = null;
029     tempEndOffsets = null;
030     size = 0;
031     updated = false;
032   }
033   
034   
035   private void add(NodePosition mapping) {
036     startMap.put(mapping.getTempStartOffset(), mapping);
037     endMap.put(mapping.getTempEndOffset(), mapping);
038     size++;
039     updated = false;
040   }
041   
042   
043   public Collection<NodePosition> getMappings() {
044     return startMap.values();
045   }
046   
047   
048   public void add(long originalStart, long originalEnd, long tempStart, long tempEnd) {
049     NodePosition mapping = new NodePosition(originalStart, originalEnd, tempStart, tempEnd);
050     add(mapping);
051   }
052   
053   
054   public int size() {
055     return this.size;
056   }
057   
058   
059   public boolean isEmpty() {
060     return this.size == 0;
061   }
062   
063   
064   private void update() {
065     if (updated) {
066       return;
067     }
068 
069     tempStartOffsets = new long[size];
070     tempEndOffsets = new long[size];
071     
072     int i = 0;
073     for (Long key : startMap.keySet()) {
074       tempStartOffsets[i= key.longValue();
075       tempEndOffsets[i= startMap.get(key).getTempEndOffset();
076       i++;
077     }
078     
079     Arrays.sort(tempStartOffsets);
080     Arrays.sort(tempEndOffsets);
081     updated = true;
082   }
083   
084 
085   /** Find the start offset of the latest original annotation
086    *  that starts at or before this temporary annotation.
087    *  This method MUST return a valid original annotation
088    *  start offset or -1.
089    @param tempStartOffset
090    @return -1 is the error code, sorry
091    */
092 
093   public long getBestOriginalStart(long tempStartOffset) {
094     update();
095     int i = Arrays.binarySearch(tempStartOffsets, tempStartOffset);
096 
097     // According to the binarySearch API, i = - insPt - 1
098 
099     if (i == -1) {
100       // This means we've undershot the first original annotation
101       return -1L;
102     }
103     
104     if (i >= 0) {
105       return startMap.get(tempStartOffsets[i]).getOriginalStartOffset();
106     }
107     
108     /* Now we want the position before the insertion point 
109      * (we've already tested for undershooting the first 
110      * original annotation)   */
111     i = - i - 2;
112     return startMap.get(tempStartOffsets[i]).getOriginalStartOffset();
113   }
114   
115 
116   /** Find the end offset of the first original annotation
117    *  that ends at or after this temporary annotation.  This method
118    *  MUST return a valid original annotation end offset or -1. 
119    
120    @param tempEndOffset
121    @return -1 is the error code, sorry
122    */
123   public long getBestOriginalEnd(long tempEndOffset) {
124     update();
125     int i = Arrays.binarySearch(tempEndOffsets, tempEndOffset);
126     
127     // Exact key is found in the array:
128     if (i >= 0) {
129       return endMap.get(tempEndOffsets[i]).getOriginalEndOffset();
130     }
131     
132     /* Exact key is not in the array; according
133      * to the binarySearch API, i = - insPt - 1
134      * We want the insertion point, but if that is past the 
135      * existing end of the array, then 
136      * we have overshot the first input annotation    */
137     i = - i - 1;
138     if (i >= size) {
139       return -1L;
140     }
141     
142     return endMap.get(tempEndOffsets[i]).getOriginalEndOffset();
143   }
144 
145   
146   public void dump() {
147     update();
148     for (int i = ; i < size ; i++) {
149       long start = tempStartOffsets[i];
150       long end = tempEndOffsets[i];
151       NodePosition m = startMap.get(start);
152       System.out.format("FGMT: %d, %d : o(%d, %d) t(%d, %d)\n", start, end,
153           m.getOriginalStartOffset(), m.getOriginalEndOffset(),
154           m.getTempStartOffset(), m.getTempEndOffset() );
155     }
156     
157     
158   }
159    
160   
161 }