001/* 002// This software is subject to the terms of the Eclipse Public License v1.0 003// Agreement, available at the following URL: 004// http://www.eclipse.org/legal/epl-v10.html. 005// You must accept the terms of that agreement to use this software. 006// 007// Copyright (C) 2011-2011 Pentaho 008// All Rights Reserved. 009*/ 010package mondrian.calc.impl; 011 012import mondrian.calc.TupleIterator; 013import mondrian.calc.TupleList; 014import mondrian.olap.Member; 015import mondrian.olap.Util; 016 017import java.util.*; 018 019/** 020 * Implementation of {@link mondrian.calc.TupleList} that stores tuples 021 * end-to-end in a backing list. 022 * 023 * <pre> 024 * l1: {A,B,C},{D,E,F} 025 * l2: {a,b},{c,d},{e,f} 026 * 027 * externally looks like: 028 * [] <- {A,B,C,a,b} 029 * [] <- {A,B,C,c,d} 030 * [] <- {A,B,C,e,f} 031 * [] <- {D,E,F,a,b} 032 * [] <- {D,E,F,c,d} 033 * [] <- {D,E,F,e,d} 034 * 035 * but internally is: 036 * A,B,C,a,b,A,B,C,c,d,A,B,C,e,f,D,E,F,a,b,D,E,F,c,d,D,E,F,e,d 037 * </pre> 038 * 039 * @author jhyde 040 */ 041public class ListTupleList extends AbstractEndToEndTupleList 042{ 043 private final List<Member> list; 044 045 /** 046 * Creates a ListTupleList. 047 * 048 * @param arity Arity 049 * @param list Backing list 050 */ 051 public ListTupleList(int arity, List<Member> list) { 052 super(arity); 053 this.list = list; 054 } 055 056 protected List<Member> backingList() { 057 return list; 058 } 059 060 public Member get(int slice, int index) { 061 return list.get(index * arity + slice); 062 } 063 064 public List<Member> get(int index) { 065 final int startIndex = index * arity; 066 final List<Member> list1 = 067 new AbstractList<Member>() { 068 public Member get(int index) { 069 return list.get(startIndex + index); 070 } 071 072 public int size() { 073 return arity; 074 } 075 }; 076 if (mutable) { 077 return Util.flatList(list1); 078 } 079 return list1; 080 } 081 082 public void add(int index, List<Member> element) { 083 assert mutable; 084 list.addAll(index * arity, element); 085 } 086 087 public void addTuple(Member... members) { 088 assert mutable; 089 list.addAll(Arrays.asList(members)); 090 } 091 092 @Override 093 public void clear() { 094 assert mutable; 095 list.clear(); 096 } 097 098 @Override 099 public List<Member> remove(int index) { 100 assert mutable; 101 for (int i = 0, n = index * arity; i < arity; i++) { 102 list.remove(n); 103 } 104 return null; // breach of List contract 105 } 106 107 @Override 108 protected void removeRange(int fromIndex, int toIndex) { 109 assert mutable; 110 list.subList(fromIndex * arity, toIndex * arity).clear(); 111 } 112 113 public int size() { 114 return list.size() / arity; 115 } 116 117 public List<Member> slice(final int column) { 118 if (column < 0 || column >= arity) { 119 throw new IllegalArgumentException(); 120 } 121 return new AbstractList<Member>() { 122 @Override 123 public Member get(int index) { 124 return ListTupleList.this.get(column, index); 125 } 126 127 @Override 128 public int size() { 129 return ListTupleList.this.size(); 130 } 131 }; 132 } 133 134 public TupleList cloneList(int capacity) { 135 return new ListTupleList( 136 arity, 137 capacity < 0 138 ? new ArrayList<Member>(list) 139 : new ArrayList<Member>(capacity * arity)); 140 } 141 142 public TupleIterator tupleIteratorInternal() { 143 return new AbstractTupleListIterator(); 144 } 145} 146 147// End ListTupleList.java