1 /* 2 * Copyright (C) 2009, Google Inc. 3 * Copyright (C) 2009, Jonas Fonseca <fonseca@diku.dk> 4 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> 5 * and other copyright owners as documented in the project's IP log. 6 * 7 * This program and the accompanying materials are made available 8 * under the terms of the Eclipse Distribution License v1.0 which 9 * accompanies this distribution, is reproduced below, and is 10 * available at http://www.eclipse.org/org/documents/edl-v10.php 11 * 12 * All rights reserved. 13 * 14 * Redistribution and use in source and binary forms, with or 15 * without modification, are permitted provided that the following 16 * conditions are met: 17 * 18 * - Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 21 * - Redistributions in binary form must reproduce the above 22 * copyright notice, this list of conditions and the following 23 * disclaimer in the documentation and/or other materials provided 24 * with the distribution. 25 * 26 * - Neither the name of the Eclipse Foundation, Inc. nor the 27 * names of its contributors may be used to endorse or promote 28 * products derived from this software without specific prior 29 * written permission. 30 * 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 32 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 33 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 34 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 35 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 36 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 37 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 38 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 39 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 40 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 41 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 42 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 43 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 44 */ 45 46 package org.eclipse.jgit.revwalk; 47 48 import java.text.MessageFormat; 49 import java.util.AbstractList; 50 51 import org.eclipse.jgit.internal.JGitText; 52 53 /** 54 * An ordered list of {@link RevObject} subclasses. 55 * 56 * @param <E> 57 * type of subclass of RevObject the list is storing. 58 */ 59 public class RevObjectList<E extends RevObject> extends AbstractList<E> { 60 static final int BLOCK_SHIFT = 8; 61 62 static final int BLOCK_SIZE = 1 << BLOCK_SHIFT; 63 64 /** 65 * Items stored in this list. 66 * <p> 67 * If {@link Block#shift} = 0 this block holds the list elements; otherwise 68 * it holds pointers to other {@link Block} instances which use a shift that 69 * is {@link #BLOCK_SHIFT} smaller. 70 */ 71 protected Block contents = new Block(0); 72 73 /** Current number of elements in the list. */ 74 protected int size = 0; 75 76 /** Create an empty object list. */ 77 public RevObjectList() { 78 // Initialized above. 79 } 80 81 public void add(final int index, final E element) { 82 if (index != size) 83 throw new UnsupportedOperationException(MessageFormat.format( 84 JGitText.get().unsupportedOperationNotAddAtEnd, 85 Integer.valueOf(index))); 86 set(index, element); 87 size++; 88 } 89 90 @SuppressWarnings("unchecked") 91 public E set(int index, E element) { 92 Block s = contents; 93 while (index >> s.shift >= BLOCK_SIZE) { 94 s = new Block(s.shift + BLOCK_SHIFT); 95 s.contents[0] = contents; 96 contents = s; 97 } 98 while (s.shift > 0) { 99 final int i = index >> s.shift; 100 index -= i << s.shift; 101 if (s.contents[i] == null) 102 s.contents[i] = new Block(s.shift - BLOCK_SHIFT); 103 s = (Block) s.contents[i]; 104 } 105 final Object old = s.contents[index]; 106 s.contents[index] = element; 107 return (E) old; 108 } 109 110 @SuppressWarnings("unchecked") 111 public E get(int index) { 112 Block s = contents; 113 if (index >> s.shift >= 1024) 114 return null; 115 while (s != null && s.shift > 0) { 116 final int i = index >> s.shift; 117 index -= i << s.shift; 118 s = (Block) s.contents[i]; 119 } 120 return s != null ? (E) s.contents[index] : null; 121 } 122 123 public int size() { 124 return size; 125 } 126 127 @Override 128 public void clear() { 129 contents = new Block(0); 130 size = 0; 131 } 132 133 /** One level of contents, either an intermediate level or a leaf level. */ 134 protected static class Block { 135 final Object[] contents = new Object[BLOCK_SIZE]; 136 137 final int shift; 138 139 Block(final int s) { 140 shift = s; 141 } 142 } 143 }