Coverage Report - com.sun.javafx.runtime.sequence.AbstractBoundComprehension
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractBoundComprehension
94%
29/31
100%
4/4
0
AbstractBoundComprehension$1
100%
3/3
N/A
0
AbstractBoundComprehension$2
100%
16/16
100%
8/8
0
AbstractBoundComprehension$State
100%
7/7
N/A
0
 
 1  
 /*
 2  
  * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
 3  
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 4  
  *
 5  
  * This code is free software; you can redistribute it and/or modify it
 6  
  * under the terms of the GNU General Public License version 2 only, as
 7  
  * published by the Free Software Foundation.  Sun designates this
 8  
  * particular file as subject to the "Classpath" exception as provided
 9  
  * by Sun in the LICENSE file that accompanied this code.
 10  
  *
 11  
  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  
  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  
  * version 2 for more details (a copy is included in the LICENSE file that
 15  
  * accompanied this code).
 16  
  *
 17  
  * You should have received a copy of the GNU General Public License version
 18  
  * 2 along with this work; if not, write to the Free Software Foundation,
 19  
  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  
  *
 21  
  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 22  
  * CA 95054 USA or visit www.sun.com if you need additional information or
 23  
  * have any questions.
 24  
  */
 25  
 
 26  
 package com.sun.javafx.runtime.sequence;
 27  
 
 28  
 import com.sun.javafx.runtime.Util;
 29  
 import com.sun.javafx.runtime.location.*;
 30  
 
 31  
 /**
 32  
  * BoundComprehension -- one-dimensional bound list comprehension, supporting where clauses and variable number of
 33  
  * elements per iteration
 34  
  *
 35  
  * @param T The element type for the input sequence
 36  
  * @param V The element type for the resulting sequence
 37  
  * @param L The Location type corresponding to the element type T
 38  
  *
 39  
  * @author Brian Goetz
 40  
  */
 41  253
 public abstract class AbstractBoundComprehension<T, L extends ObjectLocation<T>, V>
 42  
         extends AbstractBoundSequence<V> implements SequenceLocation<V> {
 43  
 
 44  
     private final SequenceLocation<T> sequenceLocation;
 45  
     protected final boolean useIndex;
 46  
     private DumbMutableSequence<State<T, L, V>> state;
 47  
     private BoundCompositeSequence<V> underlying;
 48  
 
 49  
     public AbstractBoundComprehension(Class<V> clazz,
 50  
                                       SequenceLocation<T> sequenceLocation,
 51  
                                       boolean useIndex) {
 52  45
         super(clazz);
 53  45
         this.sequenceLocation = sequenceLocation;
 54  45
         this.useIndex = useIndex;
 55  45
         setInitialValue(computeValue());
 56  45
         addTriggers();
 57  45
     }
 58  
 
 59  
     public AbstractBoundComprehension(Class<V> clazz,
 60  
                               SequenceLocation<T> sequenceLocation) {
 61  0
         this(clazz, sequenceLocation, false);
 62  0
     }
 63  
 
 64  768
     protected static class State<T, L extends ObjectLocation<T>, V> {
 65  
         private SequenceLocation<V> mapped;
 66  
         private final L element;
 67  
         private final IntLocation index;
 68  
 
 69  627
         State(L element, IntLocation index, SequenceLocation<V> mapped) {
 70  627
             this.element = element;
 71  627
             this.index = index;
 72  627
             this.mapped = mapped;
 73  627
         }
 74  
 
 75  
         @SuppressWarnings("unchecked")
 76  
         private static<T, L extends ObjectLocation<T>, V> State<T, L, V>[] newArray(int size) {
 77  97
             return (State<T, L, V>[]) new State[size];
 78  
         }
 79  
 
 80  
     }
 81  
 
 82  
     private Sequence<V> computeValue() {
 83  45
         Sequence<T> sequence = sequenceLocation.getAsSequence();
 84  45
         state = new DumbMutableSequence<State<T, L, V>>(sequence.size());
 85  45
         SequenceLocation<V>[] locationsArray = Util.<SequenceLocation<V>>newArray(SequenceLocation.class, sequence.size());
 86  45
         State<T, L, V>[] newStates = State.newArray(sequence.size());
 87  45
         fillInNewValues(sequence, newStates, locationsArray, 0);
 88  45
         state.replaceSlice(0, -1, newStates);
 89  45
         underlying = new BoundCompositeSequence<V>(getClazz(), locationsArray);
 90  45
         return underlying.getAsSequence();
 91  
     }
 92  
 
 93  
     private void fillInNewValues(Sequence<? extends T> sequence, State<T, L, V>[] newStates, SequenceLocation<V>[] locationsArray, int offset) {
 94  97
         int i = 0;
 95  97
         for (T value : sequence) {
 96  627
             State<T, L, V> stateElt = makeState(i + offset, value);
 97  627
             newStates[i] = stateElt;
 98  627
             locationsArray[i++] = stateElt.mapped;
 99  627
         }
 100  97
     }
 101  
 
 102  
     protected abstract SequenceLocation<V> computeElements$(L elementLocation, IntLocation indexLocation);
 103  
 
 104  
     protected abstract L makeInductionLocation(T value);
 105  
 
 106  
     private State<T, L, V> makeState(int index, T value) {
 107  627
         L elementLocation = makeInductionLocation(value);
 108  627
         IntVariable indexLocation = useIndex ? IntVariable.make(index) : null;
 109  627
         SequenceLocation<V> mapped = computeElements$(elementLocation, indexLocation);
 110  627
         return new State<T, L, V>(elementLocation, indexLocation, mapped);
 111  
     }
 112  
 
 113  
     private void addTriggers() {
 114  45
         underlying.addChangeListener(new SequenceChangeListener<V>() {
 115  
             public void onChange(int startPos, int endPos, Sequence<? extends V> newElements, Sequence<V> oldValue, Sequence<V> newValue) {
 116  394
                 AbstractBoundComprehension.this.updateSlice(startPos, endPos, newElements);
 117  394
             }
 118  
         });
 119  
 
 120  45
         sequenceLocation.addChangeListener(new SequenceChangeListener<T>() {
 121  
             public void onChange(int startPos, int endPos, Sequence<? extends T> newElements, Sequence<T> oldValue, Sequence<T> newValue) {
 122  62
                 int insertedCount = Sequences.size(newElements);
 123  62
                 int deletedCount = endPos - startPos + 1;
 124  62
                 int netAdded = insertedCount - deletedCount;
 125  62
                 if (netAdded == 0) {
 126  20
                     for (int i = startPos; i <= endPos; i++)
 127  10
                         state.get(i).element.set(newElements.get(i - startPos));
 128  
                 }
 129  
                 else {
 130  52
                     SequenceLocation<V>[] locationsArray = Util.<SequenceLocation<V>>newArray(SequenceLocation.class, newElements.size());
 131  52
                     State<T, L, V>[] newStates = State.newArray(newElements.size());
 132  52
                     fillInNewValues(newElements, newStates, locationsArray, startPos);
 133  52
                     underlying.replaceSlice(startPos, endPos, locationsArray);
 134  52
                     state.replaceSlice(startPos, endPos, newStates);
 135  52
                     if (useIndex) {
 136  53
                         for (int i = endPos + 1 + netAdded; i < state.size(); i++)
 137  34
                             state.get(i).index.set(i);
 138  
                     }
 139  
                 }
 140  62
             }
 141  
         });
 142  45
     }
 143  
 }