| /* |
| * Copyright (c) 2010-2013, 2016 Eike Stepper (Loehne, Germany) and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Simon McDuff - initial API and implementation |
| * Ibrahim Sallam - code refactoring for CDO 3.0 |
| */ |
| package org.eclipse.emf.cdo.server.internal.objectivity.schema; |
| |
| import com.objy.as.app.Class_Object; |
| import com.objy.as.app.Numeric_Value; |
| import com.objy.as.app.VArray_Object; |
| import com.objy.db.app.ooId; |
| |
| /** |
| * @author Simon McDuff |
| */ |
| public abstract class ObjyArrayList<T> |
| { |
| static final String sizeName = "elementCount"; |
| |
| static final String arrayName = "curr"; |
| |
| protected Class_Object classObject; |
| |
| private VArray_Object vArray; |
| |
| protected transient long cacheSize; |
| |
| transient long position; |
| |
| public static void initObject(Class_Object classObject) |
| { |
| // set the size to 0; |
| classObject.nset_numeric(sizeName, new Numeric_Value(0)); |
| } |
| |
| public ObjyArrayList(Class_Object classObject) |
| { |
| this.classObject = classObject; |
| this.cacheSize = -1; |
| |
| } |
| |
| public ooId getID() |
| { |
| return classObject.objectID(); |
| } |
| |
| // /** |
| // * TODO - verify need. |
| // */ |
| // private Class_Object getClassObject() |
| // { |
| // return classObject; |
| // } |
| |
| public void clear() |
| { |
| getVArray().resize(0); |
| cacheSize = 0; |
| saveSize(); |
| } |
| |
| private void shiftRight(int index) |
| { |
| shiftRight(index, 1); |
| } |
| |
| private void shiftRight(int index, int sizeToShift) |
| { |
| long size = this.cachedSize(); |
| |
| for (long i = size - 1; i >= index; i--) |
| { |
| setValue(i + sizeToShift, getValue(i)); |
| } |
| |
| cacheSize += sizeToShift; |
| saveSize(); |
| } |
| |
| private void shiftLeft(int index) |
| { |
| long size = this.cachedSize(); |
| for (long i = index; i < size - 1; i++) |
| { |
| setValue(i, getValue(i + 1)); |
| } |
| |
| cacheSize--; |
| saveSize(); |
| } |
| |
| /** |
| * |
| */ |
| protected void grow(int item) |
| { |
| getVArray().resize(getVArraySize() + Math.max(item + 10, 10)); |
| } |
| |
| /** |
| * |
| */ |
| private void prepareToInsert(int numberToAdd) |
| { |
| long size = cachedSize(); |
| update(); |
| |
| if (size + numberToAdd > getVArraySize()) |
| { |
| grow(numberToAdd); |
| } |
| } |
| |
| protected long getVArraySize() |
| { |
| return getVArray().size(); |
| } |
| |
| protected void update() |
| { |
| getVArray().update(); |
| } |
| |
| protected VArray_Object getVArray() |
| { |
| if (vArray == null) |
| { |
| vArray = classObject.nget_varray(arrayName); |
| } |
| return vArray; |
| } |
| |
| public void add(int index, T newValue) |
| { |
| prepareToInsert(1); |
| shiftRight(index); |
| basicSet(index, newValue); |
| } |
| |
| public void addAll(int index, Object[] newValue) |
| { |
| prepareToInsert(newValue.length); |
| shiftRight(index, newValue.length); |
| |
| for (int i = 0; i < newValue.length; i++) |
| { |
| @SuppressWarnings("unchecked") |
| T value = (T)newValue[i]; |
| basicSet(index + i, value); |
| } |
| } |
| |
| public void remove(int index) |
| { |
| shiftLeft(index); |
| } |
| |
| public void add(T newValue) |
| { |
| long size = cachedSize(); |
| |
| prepareToInsert(1); |
| setValue(size, newValue); |
| cacheSize++; |
| saveSize(); |
| } |
| |
| public void set(long index, T newValue) |
| { |
| basicSet(index, newValue); |
| // cacheSize = -1; |
| } |
| |
| public void move(long newPosition, long oldPosition) |
| { |
| if (oldPosition == newPosition) |
| { |
| return; |
| } |
| |
| // get the object at oldPosition. |
| T value = getValue(oldPosition); |
| // remove the oldPosition. |
| remove((int)oldPosition); |
| // make a space at the newPosition by shifting elements |
| shiftRight((int)newPosition); |
| set(newPosition, value); |
| } |
| |
| protected void basicSet(long index, T newValue) |
| { |
| if (index >= cachedSize()) |
| { |
| throw new ArrayIndexOutOfBoundsException(); |
| } |
| |
| update(); |
| |
| setValue(index, newValue); |
| } |
| |
| public T get(long index) |
| { |
| if (index >= size()) |
| { |
| throw new ArrayIndexOutOfBoundsException(); |
| } |
| |
| return getValue(index); |
| } |
| |
| protected abstract void setValue(long index, T newValue); |
| |
| protected abstract T getValue(long index); |
| |
| protected void saveSize() |
| { |
| // System.out.println(">>> classObject: " + classObject.objectID().getStoreString() + " <<<"); |
| // System.out.println("ooArrayList.saveSize() - value to store in objy is: " + cacheSize); |
| classObject.nset_numeric(sizeName, new Numeric_Value(cacheSize)); |
| resetCachedSize(); |
| } |
| |
| protected void resetCachedSize() |
| { |
| cacheSize = -1; |
| } |
| |
| protected long cachedSize() |
| { |
| if (cacheSize == -1) |
| { |
| cacheSize = classObject.nget_numeric(sizeName).longValue(); |
| // System.out.println(">>> classObject: " + classObject.objectID().getStoreString() + " <<<"); |
| // System.out.println("ooArrayList.privateSize() - cacheSize was -1, value from objy is: " + cacheSize); |
| } |
| return cacheSize; |
| } |
| |
| public long size() |
| { |
| // System.out.println(">>> classObject: " + classObject.objectID().getStoreString() + " <<<"); |
| // Numeric_Value nValue = classObject.nget_numeric(sizeName); |
| // System.out.println("ooArrayList.size() - nValue: " + nValue.toString()); |
| // return classObject.nget_numeric(sizeName).longValue(); |
| return cachedSize(); |
| } |
| |
| } |