001/* A token that contains an array of tokens. 002 003 Copyright (c) 1997-2014 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 027 */ 028package ptolemy.data; 029 030import ptolemy.data.type.Type; 031import ptolemy.data.type.TypeLattice; 032import ptolemy.kernel.util.IllegalActionException; 033import ptolemy.kernel.util.InternalErrorException; 034 035/////////////////////////////////////////////////////////////////// 036//// UpdatedArrayToken 037 038/** 039 A token that contains an array of tokens that is equal to another 040 specified ArrayToken except at one location, where it has a new 041 value. This implementation keeps a reference to the other specified 042 token and records only the diff between this modified array and the 043 original one. 044 <p> 045 This technique is inspired by a similar technique of storing diffs 046 described by Michael Isard in a talk at Berkeley in February, 2012. 047 048 @author Edward A. Lee 049 @version $Id$ 050 @since Ptolemy II 10.0 051 @Pt.ProposedRating Yellow (cxh) 052 @Pt.AcceptedRating Red (cxh) nil token code 053 */ 054public class UpdatedArrayToken extends ArrayToken { 055 /** Construct an UpdatedArrayToken that is equal to the specified 056 * <i>baseToken</i>, except at <i>index</i>, where its value is 057 * <i>newValue</i>. 058 * The type of the resulting array type is the least upper bound 059 * of the types of the elements, which is not necessarily the same 060 * as the type of the base token. 061 * @param baseToken The base array. 062 * @param index The index of the new value. 063 * @param newValue The updated value. 064 * @exception IllegalActionException If the index is out of range 065 * for the base token. 066 */ 067 public UpdatedArrayToken(ArrayToken baseToken, int index, Token newValue) 068 throws IllegalActionException { 069 super(baseToken.getElementType()); 070 if (index >= baseToken.length()) { 071 throw new IllegalActionException("Index " + index + " is out of " 072 + "range for the array of length " + baseToken.length()); 073 074 } 075 _baseToken = baseToken; 076 _index = index; 077 _newValue = newValue; 078 079 Type newValueType = newValue.getType(); 080 Type baseType = baseToken.getElementType(); 081 _elementType = TypeLattice.leastUpperBound(newValueType, baseType); 082 _newValue = _elementType.convert(_newValue); 083 084 _depth = _baseToken._depth + 1; 085 } 086 087 /////////////////////////////////////////////////////////////////// 088 //// public methods //// 089 090 // FindBugs says "Class doesn't override equals in superclass," but 091 // that's ok here. See the tests in test/UpdatedArrayToken.tcl 092 093 /** Return the element at the specified index. 094 * @param index The index of the desired element. 095 * @return The token contained in this array token at the 096 * specified index. 097 * @exception ArrayIndexOutOfBoundsException If the specified index is 098 * outside the range of the token array. 099 */ 100 @Override 101 public Token getElement(int index) { 102 if (index == _index) { 103 return _newValue; 104 } 105 try { 106 return _elementType.convert(_baseToken.getElement(index)); 107 } catch (IllegalActionException e) { 108 // This should not happen because _elementType is an upper bound. 109 throw new InternalErrorException(e); 110 } 111 } 112 113 /** Return the length of the contained token array. 114 * @return The length of the contained token array. 115 */ 116 @Override 117 public int length() { 118 return _baseToken.length(); 119 } 120 121 /////////////////////////////////////////////////////////////////// 122 //// private variables //// 123 124 /** The base array. */ 125 private ArrayToken _baseToken; 126 127 /** The index of the updated value. */ 128 private int _index; 129 130 /** The one updated value. */ 131 private Token _newValue; 132}