| /* |
| * Copyright (c) 2009, 2011, 2012, 2015 Eike Stepper (Berlin, 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 |
| * Eike Stepper - maintenance |
| */ |
| package org.eclipse.emf.internal.cdo.session; |
| |
| import org.eclipse.emf.cdo.common.revision.CDOElementProxy; |
| import org.eclipse.emf.cdo.common.revision.CDORevision; |
| import org.eclipse.emf.cdo.session.CDOCollectionLoadingPolicy; |
| import org.eclipse.emf.cdo.session.CDOSession; |
| import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; |
| |
| import org.eclipse.net4j.util.collection.MoveableList; |
| |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.spi.cdo.CDOSessionProtocol; |
| import org.eclipse.emf.spi.cdo.InternalCDOSession; |
| |
| /** |
| * @author Simon McDuff |
| * @since 2.0 |
| */ |
| public class CDOCollectionLoadingPolicyImpl implements CDOCollectionLoadingPolicy |
| { |
| private CDOSession session; |
| |
| private int initialChunkSize; |
| |
| private int resolveChunkSize; |
| |
| public CDOCollectionLoadingPolicyImpl(int initialChunkSize, int resolveChunkSize) |
| { |
| this.resolveChunkSize = resolveChunkSize <= 0 ? CDORevision.UNCHUNKED : resolveChunkSize; |
| this.initialChunkSize = initialChunkSize < 0 ? this.resolveChunkSize : initialChunkSize; |
| } |
| |
| public CDOSession getSession() |
| { |
| return session; |
| } |
| |
| public void setSession(CDOSession session) |
| { |
| this.session = session; |
| } |
| |
| public int getInitialChunkSize() |
| { |
| return initialChunkSize; |
| } |
| |
| public int getResolveChunkSize() |
| { |
| return resolveChunkSize; |
| } |
| |
| public void resolveAllProxies(CDORevision revision, EStructuralFeature feature) |
| { |
| doResolveProxy(revision, feature, 0, 0, Integer.MAX_VALUE); |
| } |
| |
| public Object resolveProxy(CDORevision rev, EStructuralFeature feature, int accessIndex, int serverIndex) |
| { |
| int chunkSize = resolveChunkSize; |
| if (chunkSize == CDORevision.UNCHUNKED) |
| { |
| // Can happen if CDOSession.setReferenceChunkSize() was called meanwhile |
| chunkSize = Integer.MAX_VALUE; |
| } |
| |
| return doResolveProxy(rev, feature, accessIndex, serverIndex, chunkSize); |
| } |
| |
| private Object doResolveProxy(CDORevision rev, EStructuralFeature feature, int accessIndex, int serverIndex, |
| int chunkSize) |
| { |
| // Get proxy values |
| InternalCDORevision revision = (InternalCDORevision)rev; |
| int fetchIndex = serverIndex; |
| |
| MoveableList<Object> list = revision.getList(feature); |
| int size = list.size(); |
| int fromIndex = accessIndex; |
| int toIndex = accessIndex; |
| boolean minReached = false; |
| boolean maxReached = false; |
| boolean alternation = false; |
| for (int i = 0; i < chunkSize; i++) |
| { |
| if (alternation) |
| { |
| if (!maxReached && toIndex < size - 1 && list.get(toIndex + 1) instanceof CDOElementProxy) |
| { |
| ++toIndex; |
| } |
| else |
| { |
| maxReached = true; |
| } |
| |
| if (!minReached) |
| { |
| alternation = false; |
| } |
| } |
| else |
| { |
| if (!minReached && fromIndex > 0 && list.get(fromIndex - 1) instanceof CDOElementProxy) |
| { |
| --fromIndex; |
| } |
| else |
| { |
| minReached = true; |
| } |
| |
| if (!maxReached) |
| { |
| alternation = true; |
| } |
| } |
| |
| if (minReached && maxReached) |
| { |
| break; |
| } |
| } |
| |
| CDOSessionProtocol protocol = ((InternalCDOSession)session).getSessionProtocol(); |
| return protocol.loadChunk(revision, feature, accessIndex, fetchIndex, fromIndex, toIndex); |
| } |
| } |