| /******************************************************************************* |
| * Copyright (c) 2015, 2016 Google, Inc 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: |
| * Stefan Xenos (Google) - Initial implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.core.nd; |
| |
| import org.eclipse.jdt.internal.core.nd.db.IndexException; |
| |
| public final class NdLinkedList<T> { |
| private final NdRawLinkedList rawList; |
| final ITypeFactory<T> elementFactory; |
| |
| public static interface ILinkedListVisitor<T> { |
| public void visit(T record, short metadataBits, int index) throws IndexException; |
| } |
| |
| public NdLinkedList(Nd nd, long address, ITypeFactory<T> elementFactory, int recordsInFirstBlock, |
| int recordsInSubsequentBlocks) { |
| this(nd, address, elementFactory, recordsInFirstBlock, recordsInSubsequentBlocks, 0); |
| } |
| |
| public NdLinkedList(Nd nd, long address, ITypeFactory<T> elementFactory, int recordsInFirstBlock, |
| int recordsInSubsequentBlocks, int metadataBitsPerElement) { |
| this.rawList = new NdRawLinkedList(nd, address, elementFactory.getRecordSize(), recordsInFirstBlock, |
| recordsInSubsequentBlocks, metadataBitsPerElement); |
| this.elementFactory = elementFactory; |
| } |
| |
| /** |
| * Computes the size of this list. This is an O(n) operation. |
| * |
| * @return the size of this list |
| * @throws IndexException |
| */ |
| public int size() throws IndexException { |
| return this.rawList.size(); |
| } |
| |
| public T addMember(short metadataBits) throws IndexException { |
| long address = this.rawList.addMember(metadataBits); |
| |
| return this.elementFactory.create(this.rawList.getNd(), address); |
| } |
| |
| public void accept(final ILinkedListVisitor<T> visitor) throws IndexException { |
| final NdRawLinkedList localRawList = this.rawList; |
| final ITypeFactory<T> localElementFactory = this.elementFactory; |
| localRawList.accept(new NdRawLinkedList.ILinkedListVisitor() { |
| @Override |
| public void visit(long address, short metadataBits, int index) throws IndexException { |
| visitor.visit(localElementFactory.create(localRawList.getNd(), |
| address), metadataBits, index); |
| } |
| }); |
| } |
| |
| public static <T> ITypeFactory<NdLinkedList<T>> getFactoryFor( |
| final ITypeFactory<T> elementFactory, final int recordsInFirstBlock, final int recordsInSubsequentBlocks) { |
| return getFactoryFor(elementFactory, recordsInSubsequentBlocks, 0); |
| } |
| |
| public static <T> ITypeFactory<NdLinkedList<T>> getFactoryFor( |
| final ITypeFactory<T> elementFactory, final int recordsInFirstBlock, final int recordsInSubsequentBlocks, |
| final int metadataBitsPerElement) { |
| |
| return new AbstractTypeFactory<NdLinkedList<T>>() { |
| public NdLinkedList<T> create(Nd dom, long address) { |
| return new NdLinkedList<T>(dom, address, elementFactory, recordsInFirstBlock, recordsInSubsequentBlocks, metadataBitsPerElement); |
| } |
| |
| @Override |
| public int getRecordSize() { |
| return NdRawLinkedList.recordSize(elementFactory.getRecordSize(), recordsInFirstBlock, |
| metadataBitsPerElement); |
| } |
| |
| @Override |
| public Class<?> getElementClass() { |
| return NdLinkedList.class; |
| } |
| |
| @Override |
| public boolean hasDestructor() { |
| return true; |
| } |
| |
| @Override |
| public void destructFields(Nd dom, long address) { |
| create(dom, address).destruct(); |
| } |
| |
| @Override |
| public void destruct(Nd dom, long address) { |
| destructFields(dom, address); |
| } |
| }; |
| } |
| |
| /** |
| * |
| */ |
| protected void destruct() { |
| if (this.elementFactory.hasDestructor()) { |
| final Nd nd = this.rawList.getNd(); |
| this.rawList.accept(new NdRawLinkedList.ILinkedListVisitor() { |
| @Override |
| public void visit(long address, short metadataBits, int index) throws IndexException { |
| NdLinkedList.this.elementFactory.destruct(nd, address); |
| } |
| }); |
| } |
| this.rawList.destruct(); |
| } |
| } |