// kelondroFlexSplitTable.java // (C) 2006 by Michael Peter Christen; mc@anomic.de, Frankfurt a. M., Germany // first published 12.10.2006 on http://www.anomic.de // // This is a part of YaCy, a peer-to-peer based web search engine // // $LastChangedDate: 2006-04-02 22:40:07 +0200 (So, 02 Apr 2006) $ // $LastChangedRevision: 1986 $ // $LastChangedBy: orbiter $ // // LICENSE // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package de.anomic.kelondro; import java.io.File; import java.io.IOException; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Iterator; public class kelondroFlexSplitTable implements kelondroIndex { // this is a set of kelondroFlex tables // the set is divided into FlexTables with different entry date private HashMap tables; private kelondroOrder objectOrder; private kelondroRow rowdef; private File path; private String tablename; private long buffersize; public kelondroFlexSplitTable(File path, String tablename, long buffersize, long preloadTime, kelondroRow rowdef, kelondroOrder objectOrder) throws IOException { this.path = path; this.tablename = tablename; this.objectOrder = objectOrder; this.rowdef = rowdef; // initialized tables map this.tables = new HashMap(); String[] dir = path.list(); String date; // first pass: count tables int count = 0; for (int i = 0; i < dir.length; i++) if (dir[i].startsWith(tablename)) count++; // second pass: open tables for (int i = 0; i < dir.length; i++) { if ((dir[i].startsWith(tablename)) && (dir[i].charAt(tablename.length()) == '.') && (dir[i].length() == tablename.length() + 7)) { // open table date = dir[i].substring(tablename.length() + 1); this.tables.put(date, new kelondroFlexTable(path, dir[i], buffersize / count, preloadTime, rowdef, objectOrder)); } } } private static final Calendar thisCalendar = Calendar.getInstance(); public static final String dateSuffix(Date date) { int month, year; StringBuffer suffix = new StringBuffer(6); synchronized (thisCalendar) { thisCalendar.setTime(date); month = thisCalendar.get(Calendar.MONTH); year = thisCalendar.get(Calendar.YEAR); } if ((year < 1970) && (year >= 70)) suffix.append("19").append(Integer.toString(year)); else if (year < 1970) suffix.append("20").append(Integer.toString(year)); else if (year > 3000) return null; else suffix.append(Integer.toString(year)); if (month < 10) suffix.append("0").append(Integer.toString(month)); else suffix.append(Integer.toString(month)); return new String(suffix); } public kelondroOrder order() { return this.objectOrder; } public synchronized int size() throws IOException { Iterator i = tables.values().iterator(); int s = 0; while (i.hasNext()) { s += ((kelondroFlexTable) i.next()).size(); } return s; } public kelondroRow row() throws IOException { return this.rowdef; } public synchronized kelondroRow.Entry get(byte[] key) throws IOException { Iterator i = tables.values().iterator(); kelondroFlexTable table; kelondroRow.Entry entry; while (i.hasNext()) { table = (kelondroFlexTable) i.next(); entry = table.get(key); if (entry != null) return entry; } return null; } public synchronized kelondroRow.Entry put(kelondroRow.Entry row) throws IOException { return put(row, new Date()); // entry for current date } public synchronized kelondroRow.Entry put(kelondroRow.Entry row, Date entryDate) throws IOException { kelondroRow.Entry r = remove(row.getColBytes(0)); String suffix = dateSuffix(entryDate); if (suffix == null) return null; kelondroFlexTable table = (kelondroFlexTable) tables.get(suffix); if (table == null) { // make new table table = new kelondroFlexTable(path, tablename + "." + suffix, buffersize / (tables.size() + 1), -1, rowdef, objectOrder); tables.put(suffix, table); } table.put(row); return r; } public synchronized kelondroRow.Entry remove(byte[] key) throws IOException { Iterator i = tables.values().iterator(); kelondroFlexTable table; kelondroRow.Entry entry; while (i.hasNext()) { table = (kelondroFlexTable) i.next(); entry = table.remove(key); if (entry != null) return entry; } return null; } public synchronized Iterator rows(boolean up, boolean rotating, byte[] firstKey) throws IOException { return new rowIter(); } public class rowIter implements Iterator { Iterator t, tt; public rowIter() { t = tables.values().iterator(); tt = null; } public boolean hasNext() { return ((t.hasNext()) || ((tt != null) && (tt.hasNext()))); } public Object next() { if (t.hasNext()) { if ((tt == null) || (!(tt.hasNext()))) { try { tt = ((kelondroFlexTable) t.next()).rows(true, false, null); } catch (IOException e) { return null; } } if (tt.hasNext()) { return tt.next(); } else { return null; } } return null; } public void remove() { if (tt != null) tt.remove(); } } public synchronized void close() throws IOException { Iterator i = tables.values().iterator(); while (i.hasNext()) ((kelondroFlexTable) i.next()).close(); tables = null; } public static void main(String[] args) { System.out.println(dateSuffix(new Date())); } }