3 * see AUTHORS for the list of contributors
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 package org.sonews.storage;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.List;
24 import org.sonews.util.Pair;
27 * An aggregated group is a group consisting of several "real" group.
28 * @author Christian Lins
31 class AggregatedGroup extends Channel
34 static class GroupElement
37 private long offsetStart, offsetEnd;
39 public GroupElement(Group group, long offsetStart, long offsetEnd)
42 this.offsetEnd = offsetEnd;
43 this.offsetStart = offsetStart;
47 public static List<Channel> getAll()
49 List<Channel> all = new ArrayList<Channel>();
50 all.add(getByName("agg.test"));
54 public static AggregatedGroup getByName(String name)
56 if("agg.test".equals(name))
58 AggregatedGroup agroup = new AggregatedGroup(name);
59 agroup.addGroup(Group.getByName("agg.test0"), 0, 1000);
60 agroup.addGroup(Group.getByName("agg.test1"), 2000, 4000);
67 private GroupElement[] groups = new GroupElement[2];
70 public AggregatedGroup(String name)
75 private long aggIdxToIdx(long aggIdx)
76 throws StorageBackendException
78 assert groups != null && groups.length == 2;
79 assert groups[0] != null;
80 assert groups[1] != null;
82 // Search in indices of group one
83 List<Long> idxs0 = groups[0].group.getArticleNumbers();
84 Collections.sort(idxs0);
93 // Given aggIdx must be an index of group two
94 List<Long> idxs1 = groups[1].group.getArticleNumbers();
98 private long idxToAggIdx(long idx)
104 * Adds the given group to this aggregated set.
106 * @param offsetStart Lower limit for the article ids range
108 public void addGroup(Group group, long offsetStart, long offsetEnd)
110 this.groups[groups[0] == null ? 0 : 1]
111 = new GroupElement(group, offsetStart, offsetEnd);
115 public Article getArticle(long idx)
116 throws StorageBackendException
118 Article article = null;
120 for(GroupElement groupEl : groups)
122 if(groupEl.offsetStart <= idx && groupEl.offsetEnd >= idx)
124 article = groupEl.group.getArticle(idx - groupEl.offsetStart);
133 public List<Pair<Long, ArticleHead>> getArticleHeads(
134 final long first, final long last)
135 throws StorageBackendException
137 List<Pair<Long, ArticleHead>> heads = new ArrayList<Pair<Long, ArticleHead>>();
139 for(GroupElement groupEl : groups)
141 List<Pair<Long, ArticleHead>> partHeads = new ArrayList<Pair<Long, ArticleHead>>();
142 if(groupEl.offsetStart <= first && groupEl.offsetEnd >= first)
144 long end = Math.min(groupEl.offsetEnd, last);
145 partHeads = groupEl.group.getArticleHeads
146 (first - groupEl.offsetStart, end - groupEl.offsetStart);
148 else if(groupEl.offsetStart <= last && groupEl.offsetEnd >= last)
150 long start = Math.max(groupEl.offsetStart, first);
151 partHeads = groupEl.group.getArticleHeads
152 (start - groupEl.offsetStart, last - groupEl.offsetStart);
155 for(Pair<Long, ArticleHead> partHead : partHeads)
157 heads.add(new Pair<Long, ArticleHead>(
158 partHead.getA() + groupEl.offsetStart, partHead.getB()));
166 public List<Long> getArticleNumbers()
167 throws StorageBackendException
169 List<Long> articleNumbers = new ArrayList<Long>();
171 for(GroupElement groupEl : groups)
173 List<Long> partNums = groupEl.group.getArticleNumbers();
174 for(Long partNum : partNums)
176 articleNumbers.add(partNum + groupEl.offsetStart);
180 return articleNumbers;
184 public long getIndexOf(Article art)
185 throws StorageBackendException
187 for(GroupElement groupEl : groups)
189 long idx = groupEl.group.getIndexOf(art);
198 public long getInternalID()
204 public String getName()
210 public long getFirstArticleNumber()
211 throws StorageBackendException
213 long first = Long.MAX_VALUE;
215 for(GroupElement groupEl : groups)
217 first = Math.min(first, groupEl.group.getFirstArticleNumber() + groupEl.offsetStart);
224 public long getLastArticleNumber()
225 throws StorageBackendException
229 for(GroupElement groupEl : groups)
231 last = Math.max(last, groupEl.group.getLastArticleNumber() + groupEl.offsetStart);
234 return last + getPostingsCount(); // This is a hack
237 public long getPostingsCount()
238 throws StorageBackendException
242 for(GroupElement groupEl : groups)
244 postings += groupEl.group.getPostingsCount();
250 public boolean isDeleted()
255 public boolean isWriteable()