001: // kelondroBufferedEcoFS.java
002: // (C) 2008 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany
003: // first published 14.01.2008 on http://yacy.net
004: //
005: // $LastChangedDate: 2006-04-02 22:40:07 +0200 (So, 02 Apr 2006) $
006: // $LastChangedRevision: 1986 $
007: // $LastChangedBy: orbiter $
008: //
009: // LICENSE
010: //
011: // This program is free software; you can redistribute it and/or modify
012: // it under the terms of the GNU General Public License as published by
013: // the Free Software Foundation; either version 2 of the License, or
014: // (at your option) any later version.
015: //
016: // This program is distributed in the hope that it will be useful,
017: // but WITHOUT ANY WARRANTY; without even the implied warranty of
018: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
019: // GNU General Public License for more details.
020: //
021: // You should have received a copy of the GNU General Public License
022: // along with this program; if not, write to the Free Software
023: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024:
025: package de.anomic.kelondro;
026:
027: import java.io.File;
028: import java.io.IOException;
029: import java.util.Iterator;
030: import java.util.Map;
031: import java.util.TreeMap;
032:
033: public class kelondroBufferedEcoFS {
034:
035: private kelondroEcoFS efs;
036: private int maxEntries;
037: private TreeMap<Long, byte[]> buffer;
038:
039: /*
040: * The kelondroBufferedEcoFS extends the IO reduction to EcoFS by providing a
041: * write buffer to elements that are inside the filed entries of the file
042: * That means, each time, an entry is written to the end of the file, it is not buffered
043: */
044:
045: public kelondroBufferedEcoFS(kelondroEcoFS efs, int maxEntries)
046: throws IOException {
047: this .efs = efs;
048: this .maxEntries = maxEntries;
049: this .buffer = new TreeMap<Long, byte[]>();
050: }
051:
052: private void flushBuffer() throws IOException {
053: Iterator<Map.Entry<Long, byte[]>> i = buffer.entrySet()
054: .iterator();
055: Map.Entry<Long, byte[]> entry;
056: while (i.hasNext()) {
057: entry = i.next();
058: efs.put(entry.getKey().intValue(), entry.getValue(), 0);
059: }
060: buffer.clear();
061: }
062:
063: public synchronized long size() throws IOException {
064: return efs.size();
065: }
066:
067: public File filename() {
068: return efs.filename();
069: }
070:
071: public synchronized void close() {
072: try {
073: flushBuffer();
074: } catch (IOException e) {
075: e.printStackTrace();
076: }
077: efs.close();
078: efs = null;
079: }
080:
081: public synchronized void finalize() {
082: if (this .efs != null)
083: this .close();
084: }
085:
086: public synchronized void get(long index, byte[] b, int start)
087: throws IOException {
088: assert b.length - start >= efs.recordsize;
089: if (index >= size())
090: throw new IndexOutOfBoundsException(
091: "kelondroBufferedEcoFS.get(" + index
092: + ") outside bounds (" + this .size() + ")");
093: byte[] bb = buffer.get(new Long(index));
094: if (bb == null) {
095: efs.get(index, b, start);
096: } else {
097: System.arraycopy(bb, 0, b, start, efs.recordsize);
098: }
099: }
100:
101: public synchronized void put(long index, byte[] b, int start)
102: throws IOException {
103: assert b.length - start >= efs.recordsize;
104: if (index > size())
105: throw new IndexOutOfBoundsException(
106: "kelondroBufferedEcoFS.put(" + index
107: + ") outside bounds (" + this .size() + ")");
108: if (index == efs.size()) {
109: efs.put(index, b, start);
110: } else {
111: byte[] bb = new byte[efs.recordsize];
112: System.arraycopy(b, start, bb, 0, efs.recordsize);
113: buffer.put(new Long(index), bb);
114: if (buffer.size() > this .maxEntries)
115: flushBuffer();
116: }
117: }
118:
119: public synchronized void add(byte[] b, int start)
120: throws IOException {
121: put(size(), b, start);
122: }
123:
124: /*
125: public synchronized void clean(long index, byte[] b, int start) throws IOException {
126: assert b.length - start >= efs.recordsize;
127: if (index >= size()) throw new IndexOutOfBoundsException("kelondroBufferedEcoFS.clean(" + index + ") outside bounds (" + this.size() + ")");
128: byte[] bb = buffer.get(new Long(index));
129: if (bb == null) {
130: efs.clean(index, b, start);
131: } else {
132: System.arraycopy(bb, 0, b, start, efs.recordsize);
133: buffer.remove(new Long(index));
134: efs.clean(index);
135: }
136: }
137:
138: public synchronized void clean(long index) throws IOException {
139: if (index >= size()) throw new IndexOutOfBoundsException("kelondroBufferedEcoFS.clean(" + index + ") outside bounds (" + this.size() + ")");
140: buffer.remove(new Long(index));
141: efs.clean(index);
142: }
143: */
144: public synchronized void cleanLast(byte[] b, int start)
145: throws IOException {
146: assert b.length - start >= efs.recordsize;
147: Long i = new Long(size() - 1);
148: byte[] bb = buffer.remove(i);
149: if (bb == null) {
150: efs.cleanLast(b, start);
151: } else {
152: System.arraycopy(bb, 0, b, start, efs.recordsize);
153: efs.cleanLast();
154: }
155: }
156:
157: public synchronized void cleanLast() throws IOException {
158: Long i = new Long(size() - 1);
159: buffer.remove(i);
160: efs.cleanLast();
161: }
162:
163: }
|