DeletedArrayFilter.java revision 1040:cc3000241e57
1239268Sgonzo/* 2239268Sgonzo * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3239268Sgonzo * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4239268Sgonzo * 5239268Sgonzo * This code is free software; you can redistribute it and/or modify it 6239268Sgonzo * under the terms of the GNU General Public License version 2 only, as 7239268Sgonzo * published by the Free Software Foundation. Oracle designates this 8239268Sgonzo * particular file as subject to the "Classpath" exception as provided 9239268Sgonzo * by Oracle in the LICENSE file that accompanied this code. 10239268Sgonzo * 11239268Sgonzo * This code is distributed in the hope that it will be useful, but WITHOUT 12239268Sgonzo * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13239268Sgonzo * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14239268Sgonzo * version 2 for more details (a copy is included in the LICENSE file that 15239268Sgonzo * accompanied this code). 16239268Sgonzo * 17239268Sgonzo * You should have received a copy of the GNU General Public License version 18239268Sgonzo * 2 along with this work; if not, write to the Free Software Foundation, 19239268Sgonzo * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20239268Sgonzo * 21239268Sgonzo * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22239268Sgonzo * or visit www.oracle.com if you need additional information or have any 23239268Sgonzo * questions. 24239268Sgonzo */ 25239268Sgonzo 26239268Sgonzopackage jdk.nashorn.internal.runtime.arrays; 27254461Sandrew 28239268Sgonzoimport static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; 29239268Sgonzoimport java.lang.reflect.Array; 30239268Sgonzoimport jdk.nashorn.internal.runtime.BitVector; 31254461Sandrew 32239268Sgonzo/** 33239268Sgonzo * This filter handles the deletion of array elements. 34239268Sgonzo */ 35239268Sgonzofinal class DeletedArrayFilter extends ArrayFilter { 36239268Sgonzo /** Bit vector tracking deletions. */ 37239268Sgonzo private final BitVector deleted; 38239268Sgonzo 39239268Sgonzo DeletedArrayFilter(final ArrayData underlying) { 40239268Sgonzo super(underlying); 41239268Sgonzo 42239268Sgonzo this.deleted = new BitVector(underlying.length); 43239268Sgonzo } 44239268Sgonzo 45239268Sgonzo @Override 46239268Sgonzo public ArrayData copy() { 47239268Sgonzo final DeletedArrayFilter copy = new DeletedArrayFilter(underlying.copy()); 48239268Sgonzo copy.getDeleted().copy(deleted); 49239268Sgonzo return copy; 50239268Sgonzo } 51249176Sandrew 52239268Sgonzo @Override 53251712Sandrew public Object[] asObjectArray() { 54251712Sandrew final Object[] value = super.asObjectArray(); 55239268Sgonzo 56239268Sgonzo for (int i = 0; i < value.length; i++) { 57239268Sgonzo if (deleted.isSet(i)) { 58251712Sandrew value[i] = UNDEFINED; 59239268Sgonzo } 60239268Sgonzo } 61239268Sgonzo 62239268Sgonzo return value; 63251712Sandrew } 64251712Sandrew 65239268Sgonzo @Override 66239268Sgonzo public Object asArrayOfType(final Class<?> componentType) { 67239268Sgonzo final Object value = super.asArrayOfType(componentType); 68239268Sgonzo final Object undefValue = convertUndefinedValue(componentType); 69239268Sgonzo final int l = Array.getLength(value); 70239268Sgonzo for (int i = 0; i < l; i++) { 71239268Sgonzo if (deleted.isSet(i)) { 72239268Sgonzo Array.set(value, i, undefValue); 73239268Sgonzo } 74239268Sgonzo } 75239268Sgonzo 76239268Sgonzo return value; 77239268Sgonzo } 78239268Sgonzo 79239268Sgonzo @Override 80247340Scognet public void shiftLeft(final int by) { 81239268Sgonzo super.shiftLeft(by); 82239268Sgonzo deleted.shiftLeft(by, length); 83239268Sgonzo } 84239268Sgonzo 85239268Sgonzo @Override 86239268Sgonzo public ArrayData shiftRight(final int by) { 87239268Sgonzo super.shiftRight(by); 88239268Sgonzo deleted.shiftRight(by, length); 89251712Sandrew 90239268Sgonzo return this; 91239268Sgonzo } 92239268Sgonzo 93239268Sgonzo @Override 94239268Sgonzo public ArrayData ensure(final long safeIndex) { 95251712Sandrew if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= length) { 96251712Sandrew return new SparseArrayData(this, safeIndex + 1); 97239268Sgonzo } 98239268Sgonzo 99239268Sgonzo super.ensure(safeIndex); 100251712Sandrew deleted.resize(length); 101239268Sgonzo 102251712Sandrew return this; 103251712Sandrew } 104251712Sandrew 105251712Sandrew @Override 106251712Sandrew public ArrayData shrink(final long newLength) { 107251712Sandrew super.shrink(newLength); 108239268Sgonzo deleted.resize(length); 109251712Sandrew 110251712Sandrew return this; 111251712Sandrew } 112251712Sandrew 113251712Sandrew @Override 114239268Sgonzo public ArrayData set(final int index, final Object value, final boolean strict) { 115239268Sgonzo deleted.clear(ArrayIndex.toLongIndex(index)); 116251712Sandrew 117239268Sgonzo return super.set(index, value, strict); 118239268Sgonzo } 119239268Sgonzo 120239268Sgonzo @Override 121239268Sgonzo public ArrayData set(final int index, final int value, final boolean strict) { 122239268Sgonzo deleted.clear(ArrayIndex.toLongIndex(index)); 123239268Sgonzo 124239268Sgonzo return super.set(index, value, strict); 125239268Sgonzo } 126239268Sgonzo 127239268Sgonzo @Override 128239268Sgonzo public ArrayData set(final int index, final long value, final boolean strict) { 129239268Sgonzo deleted.clear(ArrayIndex.toLongIndex(index)); 130239268Sgonzo 131239268Sgonzo return super.set(index, value, strict); 132239268Sgonzo } 133239268Sgonzo 134239268Sgonzo @Override 135239268Sgonzo public ArrayData set(final int index, final double value, final boolean strict) { 136239268Sgonzo deleted.clear(ArrayIndex.toLongIndex(index)); 137239268Sgonzo 138239268Sgonzo return super.set(index, value, strict); 139239268Sgonzo } 140239268Sgonzo 141239268Sgonzo @Override 142239268Sgonzo public boolean has(final int index) { 143239268Sgonzo return super.has(index) && deleted.isClear(ArrayIndex.toLongIndex(index)); 144239268Sgonzo } 145251712Sandrew 146239268Sgonzo @Override 147239268Sgonzo public ArrayData delete(final int index) { 148239268Sgonzo final long longIndex = ArrayIndex.toLongIndex(index); 149239268Sgonzo assert longIndex >= 0 && longIndex < length; 150239268Sgonzo deleted.set(longIndex); 151239268Sgonzo underlying.setEmpty(index); 152239268Sgonzo return this; 153239268Sgonzo } 154239268Sgonzo 155247340Scognet @Override 156239268Sgonzo public ArrayData delete(final long fromIndex, final long toIndex) { 157239268Sgonzo assert fromIndex >= 0 && fromIndex <= toIndex && toIndex < length; 158239268Sgonzo deleted.setRange(fromIndex, toIndex + 1); 159239268Sgonzo underlying.setEmpty(fromIndex, toIndex); 160239268Sgonzo return this; 161239268Sgonzo } 162239268Sgonzo 163251712Sandrew @Override 164239268Sgonzo public Object pop() { 165239268Sgonzo final long index = length - 1; 166239268Sgonzo 167239268Sgonzo if (super.has((int)index)) { 168239268Sgonzo final boolean isDeleted = deleted.isSet(index); 169239268Sgonzo final Object value = super.pop(); 170239268Sgonzo 171239268Sgonzo return isDeleted ? UNDEFINED : value; 172239268Sgonzo } 173239268Sgonzo 174251712Sandrew return super.pop(); 175239268Sgonzo } 176239268Sgonzo 177239268Sgonzo @Override 178239268Sgonzo public ArrayData slice(final long from, final long to) { 179239268Sgonzo final ArrayData newArray = underlying.slice(from, to); 180239268Sgonzo final DeletedArrayFilter newFilter = new DeletedArrayFilter(newArray); 181239268Sgonzo newFilter.getDeleted().copy(deleted); 182239268Sgonzo newFilter.getDeleted().shiftLeft(from, newFilter.length); 183247340Scognet 184239268Sgonzo return newFilter; 185239268Sgonzo } 186239268Sgonzo 187239268Sgonzo private BitVector getDeleted() { 188239268Sgonzo return deleted; 189239268Sgonzo } 190239268Sgonzo} 191239268Sgonzo