DeletedArrayFilter.java revision 1040:cc3000241e57
1113674Smtm/*
2113674Smtm * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
3113674Smtm * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4113674Smtm *
5113674Smtm * This code is free software; you can redistribute it and/or modify it
6113674Smtm * under the terms of the GNU General Public License version 2 only, as
7113674Smtm * published by the Free Software Foundation.  Oracle designates this
8113674Smtm * particular file as subject to the "Classpath" exception as provided
9113674Smtm * by Oracle in the LICENSE file that accompanied this code.
10113674Smtm *
11113674Smtm * This code is distributed in the hope that it will be useful, but WITHOUT
12113674Smtm * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13113674Smtm * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14113674Smtm * version 2 for more details (a copy is included in the LICENSE file that
15113674Smtm * accompanied this code).
16113674Smtm *
17113674Smtm * You should have received a copy of the GNU General Public License version
18113674Smtm * 2 along with this work; if not, write to the Free Software Foundation,
19113674Smtm * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20113674Smtm *
21113674Smtm * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22113674Smtm * or visit www.oracle.com if you need additional information or have any
23113674Smtm * questions.
24113674Smtm */
25113674Smtm
26113674Smtmpackage jdk.nashorn.internal.runtime.arrays;
27113674Smtm
28113674Smtmimport static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
29126392Sgreenimport java.lang.reflect.Array;
30136224Smtmimport jdk.nashorn.internal.runtime.BitVector;
31113674Smtm
32113674Smtm/**
33113674Smtm * This filter handles the deletion of array elements.
34113674Smtm */
35113674Smtmfinal class DeletedArrayFilter extends ArrayFilter {
36113674Smtm    /** Bit vector tracking deletions. */
37113674Smtm    private final BitVector deleted;
38113674Smtm
39113674Smtm    DeletedArrayFilter(final ArrayData underlying) {
40113674Smtm        super(underlying);
41117021Smtm
42113674Smtm        this.deleted = new BitVector(underlying.length);
43113674Smtm    }
44113674Smtm
45132892Smtm    @Override
46132892Smtm    public ArrayData copy() {
47132892Smtm        final DeletedArrayFilter copy = new DeletedArrayFilter(underlying.copy());
48132892Smtm        copy.getDeleted().copy(deleted);
49117021Smtm        return copy;
50117021Smtm    }
51117021Smtm
52117021Smtm    @Override
53113674Smtm    public Object[] asObjectArray() {
54149789Skeramida        final Object[] value = super.asObjectArray();
55149730Sbrooks
56149725Sbrooks        for (int i = 0; i < value.length; i++) {
57117021Smtm            if (deleted.isSet(i)) {
58117021Smtm                value[i] = UNDEFINED;
59113674Smtm            }
60117021Smtm        }
61117021Smtm
62137070Spjd        return value;
63137070Spjd    }
64137070Spjd
65117021Smtm    @Override
66117021Smtm    public Object asArrayOfType(final Class<?> componentType) {
67117021Smtm        final Object value = super.asArrayOfType(componentType);
68117021Smtm        final Object undefValue = convertUndefinedValue(componentType);
69117021Smtm        final int l = Array.getLength(value);
70128714Sphk        for (int i = 0; i < l; i++) {
71128714Sphk            if (deleted.isSet(i)) {
72128714Sphk                Array.set(value, i, undefValue);
73128714Sphk            }
74117021Smtm        }
75117021Smtm
76117021Smtm        return value;
77117021Smtm    }
78132892Smtm
79132892Smtm    @Override
80132892Smtm    public void shiftLeft(final int by) {
81132892Smtm        super.shiftLeft(by);
82117021Smtm        deleted.shiftLeft(by, length);
83117021Smtm    }
84117021Smtm
85117021Smtm    @Override
86117021Smtm    public ArrayData shiftRight(final int by) {
87117021Smtm        super.shiftRight(by);
88117021Smtm        deleted.shiftRight(by, length);
89117021Smtm
90117021Smtm        return this;
91117021Smtm    }
92117021Smtm
93117021Smtm    @Override
94117021Smtm    public ArrayData ensure(final long safeIndex) {
95117021Smtm        if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= length) {
96117021Smtm            return new SparseArrayData(this, safeIndex + 1);
97117021Smtm        }
98117021Smtm
99117021Smtm        super.ensure(safeIndex);
100117021Smtm        deleted.resize(length);
101117021Smtm
102129492Smtm        return this;
103117021Smtm    }
104117021Smtm
105117021Smtm    @Override
106117021Smtm    public ArrayData shrink(final long newLength) {
107117021Smtm        super.shrink(newLength);
108117021Smtm        deleted.resize(length);
109113674Smtm
110132892Smtm        return this;
111117021Smtm    }
112147681Sbrooks
113147681Sbrooks    @Override
114147681Sbrooks    public ArrayData set(final int index, final Object value, final boolean strict) {
115147681Sbrooks        deleted.clear(ArrayIndex.toLongIndex(index));
116132892Smtm
117149725Sbrooks        return super.set(index, value, strict);
118117021Smtm    }
119113674Smtm
120117021Smtm    @Override
121117021Smtm    public ArrayData set(final int index, final int value, final boolean strict) {
122117021Smtm        deleted.clear(ArrayIndex.toLongIndex(index));
123117021Smtm
124117021Smtm        return super.set(index, value, strict);
125117021Smtm    }
126113674Smtm
127113674Smtm    @Override
128113674Smtm    public ArrayData set(final int index, final long value, final boolean strict) {
129113674Smtm        deleted.clear(ArrayIndex.toLongIndex(index));
130117021Smtm
131113674Smtm        return super.set(index, value, strict);
132113674Smtm    }
133117021Smtm
134117021Smtm    @Override
135117021Smtm    public ArrayData set(final int index, final double value, final boolean strict) {
136117021Smtm        deleted.clear(ArrayIndex.toLongIndex(index));
137117021Smtm
138113674Smtm        return super.set(index, value, strict);
139113674Smtm    }
140117021Smtm
141117021Smtm    @Override
142113674Smtm    public boolean has(final int index) {
143117021Smtm        return super.has(index) && deleted.isClear(ArrayIndex.toLongIndex(index));
144117021Smtm    }
145117021Smtm
146117021Smtm    @Override
147117021Smtm    public ArrayData delete(final int index) {
148117021Smtm        final long longIndex = ArrayIndex.toLongIndex(index);
149117021Smtm        assert longIndex >= 0 && longIndex < length;
150117021Smtm        deleted.set(longIndex);
151117021Smtm        underlying.setEmpty(index);
152117021Smtm        return this;
153117021Smtm    }
154117021Smtm
155117021Smtm    @Override
156117021Smtm    public ArrayData delete(final long fromIndex, final long toIndex) {
157113674Smtm        assert fromIndex >= 0 && fromIndex <= toIndex && toIndex < length;
158113674Smtm        deleted.setRange(fromIndex, toIndex + 1);
159117021Smtm        underlying.setEmpty(fromIndex, toIndex);
160113674Smtm        return this;
161117021Smtm    }
162117021Smtm
163117021Smtm    @Override
164113674Smtm    public Object pop() {
165117021Smtm        final long index = length - 1;
166117021Smtm
167117021Smtm        if (super.has((int)index)) {
168117021Smtm            final boolean isDeleted = deleted.isSet(index);
169117021Smtm            final Object value = super.pop();
170117021Smtm
171117021Smtm            return isDeleted ? UNDEFINED : value;
172117021Smtm        }
173113674Smtm
174113674Smtm        return super.pop();
175113674Smtm    }
176132892Smtm
177    @Override
178    public ArrayData slice(final long from, final long to) {
179        final ArrayData newArray = underlying.slice(from, to);
180        final DeletedArrayFilter newFilter = new DeletedArrayFilter(newArray);
181        newFilter.getDeleted().copy(deleted);
182        newFilter.getDeleted().shiftLeft(from, newFilter.length);
183
184        return newFilter;
185    }
186
187    private BitVector getDeleted() {
188        return deleted;
189    }
190}
191