|
SinglePhaseTransducer |
|
1 /* 2 * SinglePhaseTransducer.java - transducer class 3 * 4 * Copyright (c) 1998-2001, The University of Sheffield. 5 * 6 * This file is part of GATE (see http://gate.ac.uk/), and is free 7 * software, licenced under the GNU Library General Public License, 8 * Version 2, June 1991 (in the distribution as file licence.html, 9 * and also available at http://gate.ac.uk/gate/licence.html). 10 * 11 * Hamish Cunningham, 24/07/98 12 * 13 * $Id: SinglePhaseTransducer.java,v 1.64 2002/05/14 09:43:17 valyt Exp $ 14 */ 15 16 17 package gate.jape; 18 19 import java.io.*; 20 21 import gate.annotation.*; 22 import gate.util.*; 23 import gate.*; 24 import gate.fsm.*; 25 import gate.gui.*; 26 import gate.creole.*; 27 import gate.event.*; 28 import java.util.*; 29 30 /** 31 * Represents a complete CPSL grammar, with a phase name, options and 32 * rule set (accessible by name and by sequence). 33 * Implements a transduce method taking a Document as input. 34 * Constructs from String or File. 35 */ 36 public class SinglePhaseTransducer 37 extends Transducer implements JapeConstants, java.io.Serializable 38 { 39 /** Debug flag */ 40 private static final boolean DEBUG = false; 41 42 /** Construction from name. */ 43 public SinglePhaseTransducer(String name) { 44 this.name = name; 45 rules = new PrioritisedRuleList(); 46 finishedAlready = false; 47 } // Construction from name 48 49 /** Type of rule application (constants defined in JapeConstants). */ 50 private int ruleApplicationStyle = BRILL_STYLE; 51 52 /** Set the type of rule application (types defined in JapeConstants). */ 53 public void setRuleApplicationStyle(int style) { 54 ruleApplicationStyle = style; 55 } 56 57 /** The list of rules in this transducer. Ordered by priority and 58 * addition sequence (which will be file position if they come from 59 * a file). 60 */ 61 private PrioritisedRuleList rules; 62 63 FSM fsm; 64 65 public FSM getFSM(){ 66 return fsm; 67 } 68 69 /** Add a rule. */ 70 public void addRule(Rule rule) { 71 rules.add(rule); 72 } // addRule 73 74 /** The values of any option settings given. */ 75 private java.util.HashMap optionSettings = new java.util.HashMap(); 76 77 /** Add an option setting. If this option is set already, the new 78 * value overwrites the previous one. 79 */ 80 public void setOption(String name, String setting) { 81 optionSettings.put(name, setting); 82 } // setOption 83 84 /** Get the value for a particular option. */ 85 public String getOption(String name) { 86 return (String) optionSettings.get(name); 87 } // getOption 88 89 /** Whether the finish method has been called or not. */ 90 private boolean finishedAlready; 91 92 /** Finish: replace dynamic data structures with Java arrays; called 93 * after parsing. 94 */ 95 public void finish(){ 96 // both MPT and SPT have finish called on them by the parser... 97 if(finishedAlready) return; 98 else finishedAlready = true; 99 100 //each rule has a RHS which has a string for java code 101 //those strings need to be compiled now 102 Map actionClasses = new HashMap(rules.size()); 103 for(Iterator i = rules.iterator(); i.hasNext(); ){ 104 Rule rule = (Rule)i.next(); 105 rule.finish(); 106 actionClasses.put(rule.getRHS().getActionClassName(), 107 rule.getRHS().getActionClassString()); 108 } 109 try{ 110 Javac.loadClasses(actionClasses); 111 }catch(Exception e){ 112 Err.prln("Compile error:\n" + e.getMessage()); 113 //e.printStackTrace(); 114 } 115 116 //build the finite state machine transition graph 117 fsm = new FSM(this); 118 //clear the old style data structures 119 rules.clear(); 120 rules = null; 121 } // finish 122 123 //dam: was 124 // private void addAnnotationsByOffset(Map map, SortedSet keys, Set annotations){ 125 private void addAnnotationsByOffset(/*Map map,*/ SimpleSortedSet keys, Set annotations){ 126 Iterator annIter = annotations.iterator(); 127 while(annIter.hasNext()){ 128 Annotation ann = (Annotation)annIter.next(); 129 //ignore empty annotations 130 long offset = ann.getStartNode().getOffset().longValue(); 131 if(offset == ann.getEndNode().getOffset().longValue()) 132 continue; 133 //dam: was 134 /* 135 // Long offset = ann.getStartNode().getOffset(); 136 137 List annsAtThisOffset = null; 138 if(keys.add(offset)){ 139 annsAtThisOffset = new LinkedList(); 140 map.put(offset, annsAtThisOffset); 141 }else{ 142 annsAtThisOffset = (List)map.get(offset); 143 } 144 annsAtThisOffset.add(ann); 145 */ 146 //dam: end 147 keys.add(offset, ann); 148 } 149 }//private void addAnnotationsByOffset() 150 151 152 /** 153 * Transduce a document using the annotation set provided and the current 154 * rule application style. 155 */ 156 public void transduce(Document doc, AnnotationSet inputAS, 157 AnnotationSet outputAS) throws JapeException, 158 ExecutionException { 159 interrupted = false; 160 fireProgressChanged(0); 161 162 //the input annotations will be read from this map 163 //maps offset to list of annotations 164 165 //dam was 166 /* 167 Map annotationsByOffset = new HashMap(); 168 169 SortedSet offsets = new TreeSet(); 170 */ 171 //dam: now 172 SimpleSortedSet offsets = new SimpleSortedSet(); 173 SimpleSortedSet annotationsByOffset = offsets; 174 //dam: end 175 176 //select only the annotations of types specified in the input list 177 // Out.println("Input:" + input); 178 if(input.isEmpty()) 179 { 180 //dam: was 181 // addAnnotationsByOffset(annotationsByOffset, offsets, inputAS); 182 //dam: now 183 addAnnotationsByOffset(offsets, inputAS); 184 //dam: end 185 } else { 186 Iterator typesIter = input.iterator(); 187 AnnotationSet ofOneType = null; 188 while(typesIter.hasNext()){ 189 ofOneType = inputAS.get((String)typesIter.next()); 190 if(ofOneType != null){ 191 //dam: was 192 // addAnnotationsByOffset(annotationsByOffset, offsets, ofOneType); 193 //dam: now 194 addAnnotationsByOffset(offsets, ofOneType); 195 //dam: end 196 } 197 } 198 } 199 200 if(annotationsByOffset.isEmpty()){ 201 fireProcessFinished(); 202 return; 203 } 204 205 annotationsByOffset.sort(); 206 //define data structures 207 //FSM instances that haven't blocked yet 208 // java.util.LinkedList activeFSMInstances = new java.util.LinkedList(); 209 java.util.ArrayList activeFSMInstances = new java.util.ArrayList(); 210 211 // FSM instances that have reached a final state 212 // This is a sorted set and the contained objects are sorted by the length 213 // of the document content covered by the matched annotations 214 //dam: was ArrayList has faster add and remove methods then LinkedList 215 // java.util.LinkedList acceptingFSMInstances = new LinkedList(); 216 //dam: now 217 java.util.ArrayList acceptingFSMInstances = new ArrayList(); 218 //dam: end 219 FSMInstance currentFSM; 220 221 222 //find the first node of the document 223 Node startNode = ((Annotation) 224 ((ArrayList)annotationsByOffset. 225 get(offsets.first())).get(0)). 226 getStartNode(); 227 228 //used to calculate the percentage of processing done 229 long lastNodeOff = doc.getContent().size().longValue(); 230 231 //the offset of the node where the matching currently starts 232 //the value -1 marks no more annotations to parse 233 long startNodeOff = startNode.getOffset().longValue(); 234 235 //used to decide when to fire progress events 236 long oldStartNodeOff = 0; 237 238 //the big while for the actual parsing 239 while(startNodeOff != -1){ 240 //Out.prln(); 241 //Out.pr("Start: " + startNodeOff); 242 //while there are more annotations to parse 243 //create initial active FSM instance starting parsing from new startNode 244 //currentFSM = FSMInstance.getNewInstance( 245 currentFSM = new FSMInstance( 246 fsm, 247 fsm.getInitialState(),//fresh start 248 startNode,//the matching starts form the current startNode 249 startNode,//current position in AG is the start position 250 new java.util.HashMap(),//no bindings yet! 251 doc 252 ); 253 254 // at this point ActiveFSMInstances should always be empty! 255 activeFSMInstances.clear(); 256 acceptingFSMInstances.clear(); 257 //dam: was used LinkedList 258 // activeFSMInstances.addLast(currentFSM); 259 //dam: now used ArrayList 260 activeFSMInstances.add(currentFSM); 261 //dam: end 262 263 //far each active FSM Instance, try to advance 264 whileloop2: 265 while(!activeFSMInstances.isEmpty()){ 266 if(interrupted) throw new ExecutionInterruptedException( 267 "The execution of the \"" + getName() + 268 "\" Jape transducer has been abruptly interrupted!"); 269 270 //Out.pr(" <" + acceptingFSMInstances.size() + "/" + 271 // activeFSMInstances.size() +">"); 272 // take the first active FSM instance 273 currentFSM = (FSMInstance)activeFSMInstances.remove(0); 274 275 // process the current FSM instance 276 if(currentFSM.getFSMPosition().isFinal()){ 277 //the current FSM is in a final state 278 //dam: was LinkedList 279 // acceptingFSMInstances.addLast(currentFSM.clone()); 280 //dam: now 281 acceptingFSMInstances.add(currentFSM.clone()); 282 //dam: end 283 // //if we are in APPELT mode clear all the accepting instances 284 // //apart from the longest one 285 // if(ruleApplicationStyle == APPELT_STYLE && 286 // acceptingFSMInstances.size() > 1){ 287 // Object longestAcceptor = acceptingFSMInstances.last(); 288 // acceptingFSMInstances.clear(); 289 // acceptingFSMInstances.add(longestAcceptor); 290 // } 291 //if we're only looking for the shortest stop here 292 if(ruleApplicationStyle == FIRST_STYLE) break whileloop2; 293 } 294 295 //get all the annotations that start where the current FSM finishes 296 //<<< DAM: was using SortedSet 297 // SortedSet offsetsTailSet = offsets.tailSet( 298 //=== DAM: now 299 SimpleSortedSet offsetsTailSet = offsets.tailSet( 300 //>>> DAM: end 301 currentFSM.getAGPosition().getOffset().longValue()); 302 ArrayList paths; //was linkedList 303 304 //<<< DAM: SortedSet speedup 305 /* 306 if(offsetsTailSet.isEmpty()){ 307 paths = new ArrayList(); 308 }else{ 309 paths = (List)annotationsByOffset.get(offsetsTailSet.first()); 310 } 311 */ 312 //=== DAM: now 313 long theFirst = offsetsTailSet.first(); 314 if(theFirst <0) 315 continue; 316 317 paths = (ArrayList)annotationsByOffset.get(theFirst); 318 // } 319 //System.out.println("Paths: " + paths + "\n^localInputIndex: " + localInputIndex); 320 //>>> DAM: end 321 322 // if(!paths.isEmpty()){ 323 if(paths.isEmpty()) continue; 324 Iterator pathsIter = paths.iterator(); 325 Annotation onePath; 326 State currentState = currentFSM.getFSMPosition(); 327 Iterator transitionsIter; 328 //DAM: doit without intermediate FetureMap 329 // FeatureMap features = null;//Factory.newFeatureMap(); 330 //foreach possible annotation 331 while(pathsIter.hasNext()){ 332 onePath = (Annotation)pathsIter.next(); 333 transitionsIter = currentState.getTransitions().iterator(); 334 Transition currentTransition; 335 Constraint[] currentConstraints; 336 transitionsWhile: 337 while(transitionsIter.hasNext()){ 338 currentTransition = (Transition)transitionsIter.next(); 339 //check if the current transition can use the curent annotation (path) 340 currentConstraints = 341 currentTransition.getConstraints().getConstraints(); 342 String annType; 343 //DAM: introduce index of the constaint to process 344 int currentConstraintsindex = -1; 345 //we assume that all annotations in a contraint are of the same type 346 for(int i = 0; i<currentConstraints.length; i++){ 347 annType = currentConstraints[i].getAnnotType(); 348 //if wrong type try next transition 349 if(!annType.equals(onePath.getType()))continue transitionsWhile; 350 //DAM: doit without intermediate FetureMap 351 // features.clear(); 352 // features.putAll(currentConstraints[i].getAttributeSeq()); 353 currentConstraintsindex = i; 354 break; 355 } 356 // >>> was 357 // if(onePath.getFeatures().entrySet().containsAll(features.entrySet())){ 358 // >>> NASO, FeatArray optimization 359 if(onePath.getFeatures().subsumes( 360 //dam: was 361 // features 362 //dam: now 363 currentConstraints[currentConstraintsindex].getAttributeSeq() 364 //dam: end 365 )){ 366 // >>> end NASO 367 //we have a match 368 //System.out.println("Match!"); 369 //create a new FSMInstance, advance it over the current annotation 370 //take care of the bindings and add it to ActiveFSM 371 FSMInstance newFSMI = (FSMInstance)currentFSM.clone(); 372 newFSMI.setAGPosition(onePath.getEndNode()); 373 newFSMI.setFSMPosition(currentTransition.getTarget()); 374 //bindings 375 java.util.Map binds = newFSMI.getBindings(); 376 java.util.Iterator labelsIter = 377 currentTransition.getBindings().iterator(); 378 String oneLabel; 379 AnnotationSet boundAnnots, newSet; 380 while(labelsIter.hasNext()){ 381 oneLabel = (String)labelsIter.next(); 382 boundAnnots = (AnnotationSet)binds.get(oneLabel); 383 if(boundAnnots != null) 384 newSet = new AnnotationSetImpl((AnnotationSet)boundAnnots); 385 else 386 newSet = new AnnotationSetImpl(doc); 387 newSet.add(onePath); 388 binds.put(oneLabel, newSet); 389 390 }//while(labelsIter.hasNext()) 391 activeFSMInstances.add(newFSMI); 392 //Out.pr("^(" + newFSMI.getStartAGPosition().getOffset() + 393 // "->" + newFSMI.getAGPosition().getOffset() + ")"); 394 }//if match 395 }//while(transitionsIter.hasNext()) 396 }//while(pathsIter.hasNext()) 397 // dam: reverse the paths.isEmpty check 398 // }//if(paths != null) 399 // dam 400 }//while(!activeFSMInstances.isEmpty()) 401 402 403 //FIRE THE RULE 404 //dam: use long 405 // Long lastAGPosition = null; 406 //dam: now 407 long lastAGPosition = -1; 408 //dam: end 409 if(acceptingFSMInstances.isEmpty()){ 410 //no rule to fire, advance to the next input offset 411 lastAGPosition = startNodeOff + 1; 412 } else if(ruleApplicationStyle == BRILL_STYLE) { 413 //System.out.println("Brill acceptor"); 414 // fire the rules corresponding to all accepting FSM instances 415 java.util.Iterator accFSMs = acceptingFSMInstances.iterator(); 416 FSMInstance currentAcceptor; 417 RightHandSide currentRHS; 418 lastAGPosition = startNode.getOffset().longValue(); 419 420 while(accFSMs.hasNext()){ 421 currentAcceptor = (FSMInstance) accFSMs.next(); 422 423 currentRHS = currentAcceptor.getFSMPosition().getAction(); 424 currentRHS.transduce(doc, currentAcceptor.getBindings(), 425 inputAS, outputAS, ontology); 426 //dam: use long 427 // Long currentAGPosition = currentAcceptor.getAGPosition().getOffset(); 428 //dam: now 429 long currentAGPosition = currentAcceptor.getAGPosition().getOffset().longValue(); 430 //dam: end 431 if(currentAGPosition > lastAGPosition) 432 lastAGPosition = currentAGPosition; 433 } 434 435 } else if(ruleApplicationStyle == APPELT_STYLE || 436 ruleApplicationStyle == FIRST_STYLE || 437 ruleApplicationStyle == ONCE_STYLE) { 438 439 //System.out.println("Appelt acceptor"); 440 // AcceptingFSMInstances is an ordered structure: 441 // just execute the longest (last) rule 442 443 Collections.sort(acceptingFSMInstances, Collections.reverseOrder()); 444 445 FSMInstance currentAcceptor =(FSMInstance)acceptingFSMInstances.get(0); 446 if(isDebugMode()){ 447 //see if we have any conflicts 448 Iterator accIter = acceptingFSMInstances.iterator(); 449 FSMInstance anAcceptor; 450 List conflicts = new ArrayList(); 451 while(accIter.hasNext()){ 452 anAcceptor = (FSMInstance)accIter.next(); 453 if(anAcceptor.equals(currentAcceptor)){ 454 conflicts.add(anAcceptor); 455 }else{ 456 break; 457 } 458 } 459 if(conflicts.size() > 1){ 460 Out.prln("\nConflicts found during matching:" + 461 "\n================================"); 462 accIter = conflicts.iterator(); 463 int i = 0; 464 while(accIter.hasNext()){ 465 Out.prln(i++ + ") " + accIter.next().toString()); 466 } 467 } 468 } 469 470 RightHandSide currentRHS = currentAcceptor.getFSMPosition().getAction(); 471 currentRHS.transduce(doc, currentAcceptor.getBindings(), 472 inputAS, outputAS, ontology); 473 474 //if in ONCE mode stop after first match 475 if(ruleApplicationStyle == ONCE_STYLE) return; 476 477 //advance in AG 478 lastAGPosition = currentAcceptor.getAGPosition().getOffset().longValue(); 479 } 480 // else if(ruleApplicationStyle == FIRST_STYLE) { 481 // // AcceptingFSMInstances is an ordered structure: 482 // // just execute the shortest (first) rule 483 // 484 // FSMInstance currentAcceptor =(FSMInstance)acceptingFSMInstances.first(); 485 // RightHandSide currentRHS = currentAcceptor.getFSMPosition().getAction(); 486 // currentRHS.transduce(doc, outputAS, currentAcceptor.getBindings()); 487 // //advance in AG 488 // long lastAGPosition = currentAcceptor.getAGPosition(). 489 // getOffset().longValue(); 490 // //advance the index on input 491 // while(inputIndex < annotations.size() && 492 // ((Annotation)annotations.get(inputIndex)). 493 // getStartNode().getOffset().longValue() < lastAGPosition){ 494 // inputIndex++; 495 // } 496 // } 497 else throw new RuntimeException("Unknown rule application style!"); 498 499 500 //advance on input 501 // SortedSet OffsetsTailSet = offsets.tailSet(lastAGPosition); 502 SimpleSortedSet OffsetsTailSet = offsets.tailSet(lastAGPosition); 503 //<<< DAM: isEmpty speedup 504 /* 505 if(OffsetsTailSet.isEmpty()){ 506 */ 507 //=== DAM: now 508 long theFirst = OffsetsTailSet.first(); 509 if( theFirst < 0){ 510 //>>> DAM: end 511 //no more input, phew! :) 512 startNodeOff = -1; 513 fireProcessFinished(); 514 }else{ 515 //<<< DAM: use long 516 /* 517 Long nextKey = (Long)OffsetsTailSet.first(); 518 */ 519 //=== DAM: now 520 long nextKey = theFirst; 521 //>>> DAM: end 522 startNode = ((Annotation) 523 ((ArrayList)annotationsByOffset.get(nextKey)).get(0)). //nextKey 524 getStartNode(); 525 startNodeOff = startNode.getOffset().longValue(); 526 527 //eliminate the possibility for infinite looping 528 if(oldStartNodeOff == startNodeOff){ 529 //Out.prln(""); 530 //Out.pr("SKIP " + startNodeOff); 531 //we are about to step twice in the same place, ...skip ahead 532 lastAGPosition = startNodeOff + 1; 533 OffsetsTailSet = offsets.tailSet(lastAGPosition); 534 //<<< DAM: isEmpty speedup 535 /* 536 if(OffsetsTailSet.isEmpty()){ 537 */ 538 //=== DAM: now 539 theFirst = OffsetsTailSet.first(); 540 if(theFirst < 0){ 541 //>>> DAM: end 542 //no more input, phew! :) 543 startNodeOff = -1; 544 fireProcessFinished(); 545 }else{ 546 //<<< DAM: use long 547 // nextKey = (Long)OffsetsTailSet.first(); 548 //=== DAM: now 549 nextKey = theFirst; 550 //>>> DAM: end 551 startNode = ((Annotation) 552 ((List)annotationsByOffset.get(theFirst)).get(0)). 553 getStartNode(); 554 startNodeOff =startNode.getOffset().longValue(); 555 } 556 //Out.prln(" ->" + startNodeOff); 557 }//if(oldStartNodeOff == startNodeOff) 558 559 560 //fire the progress event 561 if(startNodeOff - oldStartNodeOff > 256){ 562 if(isInterrupted()) throw new ExecutionInterruptedException( 563 "The execution of the \"" + getName() + 564 "\" Jape transducer has been abruptly interrupted!"); 565 566 fireProgressChanged((int)(100 * startNodeOff / lastNodeOff)); 567 oldStartNodeOff = startNodeOff; 568 } 569 } 570 }//while(startNodeOff != -1) 571 fireProcessFinished(); 572 } // transduce 573 574 575 /** Clean up (delete action class files, for e.g.). */ 576 public void cleanUp() { 577 // for(DListIterator i = rules.begin(); ! i.atEnd(); i.advance()) 578 // ((Rule) i.get()).cleanUp(); 579 } // cleanUp 580 581 /** A string representation of this object. */ 582 public String toString() { 583 return toString(""); 584 } // toString() 585 586 /** A string representation of this object. */ 587 public String toString(String pad) { 588 String newline = Strings.getNl(); 589 String newPad = Strings.addPadding(pad, INDENT_PADDING); 590 591 StringBuffer buf = 592 new StringBuffer(pad + "SPT: name(" + name + "); ruleApplicationStyle("); 593 594 switch(ruleApplicationStyle) { 595 case APPELT_STYLE: buf.append("APPELT_STYLE); "); break; 596 case BRILL_STYLE: buf.append("BRILL_STYLE); "); break; 597 default: break; 598 } 599 600 buf.append("rules(" + newline); 601 Iterator rulesIterator = rules.iterator(); 602 while(rulesIterator.hasNext()) 603 buf.append(((Rule) rulesIterator.next()).toString(newPad) + " "); 604 605 buf.append(newline + pad + ")." + newline); 606 607 return buf.toString(); 608 } // toString(pad) 609 610 //needed by fsm 611 public PrioritisedRuleList getRules() { 612 return rules; 613 } 614 615 /** 616 * Adds a new type of input annotations used by this transducer. 617 * If the list of input types is empty this transducer will parse all the 618 * annotations in the document otherwise the types not found in the input 619 * list will be completely ignored! To be used with caution! 620 */ 621 public void addInput(String ident) { 622 input.add(ident); 623 } 624 public synchronized void removeProgressListener(ProgressListener l) { 625 if (progressListeners != null && progressListeners.contains(l)) { 626 Vector v = (Vector) progressListeners.clone(); 627 v.removeElement(l); 628 progressListeners = v; 629 } 630 } 631 public synchronized void addProgressListener(ProgressListener l) { 632 Vector v = progressListeners == null ? new Vector(2) : (Vector) progressListeners.clone(); 633 if (!v.contains(l)) { 634 v.addElement(l); 635 progressListeners = v; 636 } 637 } 638 639 /** 640 * Defines the types of input annotations that this transducer reads. If this 641 * set is empty the transducer will read all the annotations otherwise it 642 * will only "see" the annotations of types found in this list ignoring all 643 * other types of annotations. 644 */ 645 java.util.Set input = new java.util.HashSet(); 646 private transient Vector progressListeners; 647 648 protected void fireProgressChanged(int e) { 649 if (progressListeners != null) { 650 Vector listeners = progressListeners; 651 int count = listeners.size(); 652 for (int i = 0; i < count; i++) { 653 ((ProgressListener) listeners.elementAt(i)).progressChanged(e); 654 } 655 } 656 } 657 protected void fireProcessFinished() { 658 if (progressListeners != null) { 659 Vector listeners = progressListeners; 660 int count = listeners.size(); 661 for (int i = 0; i < count; i++) { 662 ((ProgressListener) listeners.elementAt(i)).processFinished(); 663 } 664 } 665 } 666 public int getRuleApplicationStyle() { 667 return ruleApplicationStyle; 668 } 669 670 /* 671 private void writeObject(ObjectOutputStream oos) throws IOException { 672 Out.prln("writing spt"); 673 oos.defaultWriteObject(); 674 Out.prln("finished writing spt"); 675 } // writeObject 676 */ 677 678 679 } // class SinglePhaseTransducer 680 681 /* 682 class SimpleSortedSet { 683 684 static final int INCREMENT = 1023; 685 int[] theArray = new int[INCREMENT]; 686 Object[] theObject = new Object[INCREMENT]; 687 int tsindex = 0; 688 int size = 0; 689 public static int avesize = 0; 690 public static int maxsize = 0; 691 public static int avecount = 0; 692 public SimpleSortedSet() 693 { 694 avecount++; 695 java.util.Arrays.fill(theArray, Integer.MAX_VALUE); 696 } 697 698 public Object get(int elValue) 699 { 700 int index = java.util.Arrays.binarySearch(theArray, elValue); 701 if (index >=0) 702 return theObject[index]; 703 return null; 704 } 705 706 public boolean add(int elValue, Object o) 707 { 708 int index = java.util.Arrays.binarySearch(theArray, elValue); 709 if (index >=0) 710 { 711 ((ArrayList)theObject[index]).add(o); 712 return false; 713 } 714 if (size == theArray.length) 715 { 716 int[] temp = new int[theArray.length + INCREMENT]; 717 Object[] tempO = new Object[theArray.length + INCREMENT]; 718 System.arraycopy(theArray, 0, temp, 0, theArray.length); 719 System.arraycopy(theObject, 0, tempO, 0, theArray.length); 720 java.util.Arrays.fill(temp, theArray.length, temp.length , Integer.MAX_VALUE); 721 theArray = temp; 722 theObject = tempO; 723 } 724 index = ~index; 725 System.arraycopy(theArray, index, theArray, index+1, size - index ); 726 System.arraycopy(theObject, index, theObject, index+1, size - index ); 727 theArray[index] = elValue; 728 theObject[index] = new ArrayList(); 729 ((ArrayList)theObject[index]).add(o); 730 size++; 731 return true; 732 } 733 public int first() 734 { 735 if (tsindex >= size) return -1; 736 return theArray[tsindex]; 737 } 738 739 public Object getFirst() 740 { 741 if (tsindex >= size) return null; 742 return theObject[tsindex]; 743 } 744 745 public SimpleSortedSet tailSet(int elValue) 746 { 747 if (tsindex < theArray.length && elValue != theArray[tsindex]) 748 { 749 if (tsindex<(size-1) && elValue > theArray[tsindex] && 750 elValue <= theArray[tsindex+1]) 751 { 752 tsindex++; 753 return this; 754 } 755 int index = java.util.Arrays.binarySearch(theArray, elValue); 756 if (index < 0) 757 index = ~index; 758 tsindex = index; 759 } 760 return this; 761 } 762 763 public boolean isEmpty() 764 { 765 return size ==0; 766 } 767 }; 768 */
|
SinglePhaseTransducer |
|