001: // kelondroArray.java
002: // ------------------
003: // part of the Kelondro Database
004: // (C) by Michael Peter Christen; mc@anomic.de
005: // first published on http://www.anomic.de
006: // Frankfurt, Germany, 2005
007: // last major change: 20.06.2005
008: //
009: // This program is free software; you can redistribute it and/or modify
010: // it under the terms of the GNU General Public License as published by
011: // the Free Software Foundation; either version 2 of the License, or
012: // (at your option) any later version.
013: //
014: // This program is distributed in the hope that it will be useful,
015: // but WITHOUT ANY WARRANTY; without even the implied warranty of
016: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
017: // GNU General Public License for more details.
018: //
019: // You should have received a copy of the GNU General Public License
020: // along with this program; if not, write to the Free Software
021: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
022: //
023: // Using this software in any meaning (reading, learning, copying, compiling,
024: // running) means that you agree that the Author(s) is (are) not responsible
025: // for cost, loss of data or any harm that may be caused directly or indirectly
026: // by usage of this softare or this documentation. The usage of this software
027: // is on your own risk. The installation and usage (starting/running) of this
028: // software may allow other people or application to access your computer and
029: // any attached devices and is highly dependent on the configuration of the
030: // software which must be done by the user of the software; the author(s) is
031: // (are) also not responsible for proper configuration and usage of the
032: // software, even if provoked by documentation provided together with
033: // the software.
034: //
035: // Any changes to this file according to the GPL as documented in the file
036: // gpl.txt aside this file in the shipment you received can be done to the
037: // lines that follows this copyright notice here, but changes must not be
038: // done inside the copyright notive above. A re-distribution must contain
039: // the intact and unchanged copyright notice.
040: // Contributions and changes to the program code must be marked as such.
041:
042: /*
043: This class extends the kelondroRecords and adds a array structure
044: */
045:
046: package de.anomic.kelondro;
047:
048: import java.io.File;
049: import java.io.IOException;
050: import java.util.Iterator;
051: import java.util.Map;
052: import java.util.TreeMap;
053:
054: public class kelondroFixedWidthArray extends kelondroFullRecords
055: implements kelondroArray {
056:
057: // define the Over-Head-Array
058: private static short this OHBytes = 0; // our record definition does not need extra bytes
059: private static short this OHHandles = 0; // and no handles
060:
061: public kelondroFixedWidthArray(File file, kelondroRow rowdef,
062: int intprops) throws IOException {
063: // this creates a new array
064: //super(file, true, -1, thisOHBytes, thisOHHandles, rowdef, intprops, rowdef.columns() /* txtProps */, 80 /* txtPropWidth */);
065: super (file, this OHBytes, this OHHandles, rowdef, intprops,
066: rowdef.columns() /* txtProps */, 80 /* txtPropWidth */);
067: if (!(super .fileExisted)) {
068: for (int i = 0; i < intprops; i++) {
069: setHandle(i, new kelondroHandle(kelondroHandle.NUL));
070: }
071: // store column description
072: for (int i = 0; i < rowdef.columns(); i++) {
073: try {
074: super .setText(i, rowdef.column(i).toString()
075: .getBytes());
076: } catch (IOException e) {
077: }
078: }
079: }
080: }
081:
082: public kelondroFixedWidthArray(kelondroRA ra, String filename,
083: kelondroRow rowdef, int intprops) throws IOException {
084: // this creates a new array
085: //super(ra, filename, true, -1, thisOHBytes, thisOHHandles, rowdef, intprops, rowdef.columns() /* txtProps */, 80 /* txtPropWidth */, false);
086: super (ra, filename, this OHBytes, this OHHandles, rowdef,
087: intprops, rowdef.columns() /* txtProps */,
088: 80 /* txtPropWidth */, false);
089: for (int i = 0; i < intprops; i++) {
090: setHandle(i, new kelondroHandle(0));
091: }
092: // store column description
093: for (int i = 0; i < rowdef.columns(); i++) {
094: try {
095: super
096: .setText(i, rowdef.column(i).toString()
097: .getBytes());
098: } catch (IOException e) {
099: }
100: }
101: }
102:
103: public static kelondroFixedWidthArray open(File file,
104: kelondroRow rowdef, int intprops) {
105: try {
106: return new kelondroFixedWidthArray(file, rowdef, intprops);
107: } catch (IOException e) {
108: file.delete();
109: try {
110: return new kelondroFixedWidthArray(file, rowdef,
111: intprops);
112: } catch (IOException ee) {
113: e.printStackTrace();
114: ee.printStackTrace();
115: System.exit(-1);
116: return null;
117: }
118: }
119: }
120:
121: public synchronized void set(int index, kelondroRow.Entry rowentry)
122: throws IOException {
123: // this writes a row without reading the row from the file system first
124:
125: // create a node at position index with rowentry
126: kelondroHandle h = new kelondroHandle(index);
127: (new EcoNode(h, (rowentry == null) ? null : rowentry.bytes(), 0))
128: .commit();
129: // attention! this newNode call wants that the OH bytes are passed within the bulkchunk
130: // field. Here, only the rowentry.bytes() raw payload is passed. This is valid, because
131: // the OHbytes and OHhandles are zero.
132: }
133:
134: public synchronized void setMultiple(
135: TreeMap<Integer, kelondroRow.Entry> rows)
136: throws IOException {
137: Iterator<Map.Entry<Integer, kelondroRow.Entry>> i = rows
138: .entrySet().iterator();
139: Map.Entry<Integer, kelondroRow.Entry> entry;
140: int k;
141: while (i.hasNext()) {
142: entry = i.next();
143: k = entry.getKey().intValue();
144: set(k, entry.getValue());
145: }
146: }
147:
148: public synchronized kelondroRow.Entry getIfValid(int index)
149: throws IOException {
150: byte[] b = (new EcoNode(new kelondroHandle(index)))
151: .getValueRow();
152: if (b[0] == 0)
153: return null;
154: if ((b[0] == -128) && (b[1] == 0))
155: return null;
156: return row().newEntry(b);
157: }
158:
159: public synchronized kelondroRow.Entry get(int index)
160: throws IOException {
161: return row().newEntry(
162: new EcoNode(new kelondroHandle(index)).getValueRow());
163: }
164:
165: protected synchronized int seti(int index, int value)
166: throws IOException {
167: int before = getHandle(index).hashCode();
168: setHandle(index, new kelondroHandle(value));
169: return before;
170: }
171:
172: protected synchronized int geti(int index) {
173: return getHandle(index).hashCode();
174: }
175:
176: public synchronized int add(kelondroRow.Entry rowentry)
177: throws IOException {
178: // adds a new rowentry, but re-uses a previously as-deleted marked entry
179: kelondroNode n = new EcoNode(rowentry.bytes());
180: n.commit();
181: return n.handle().hashCode();
182: }
183:
184: public synchronized void remove(int index) throws IOException {
185: assert (index < (super .free() + super .size())) : "remove: index "
186: + index
187: + " out of bounds "
188: + (super .free() + super .size());
189:
190: // get the node at position index
191: kelondroHandle h = new kelondroHandle(index);
192: kelondroNode n = new EcoNode(h);
193:
194: // erase the row
195: n.setValueRow(null);
196: n.commit();
197:
198: // mark row as deleted so it can be re-used
199: deleteNode(h);
200: }
201:
202: public void print() throws IOException {
203: System.out.println("PRINTOUT of table, length=" + size());
204: kelondroRow.Entry row;
205: for (int i = 0; i < (super .free() + super .size()); i++) {
206: System.out.print("row " + i + ": ");
207: row = get(i);
208: for (int j = 0; j < row.columns(); j++)
209: System.out.print(((row.empty(j)) ? "NULL" : row
210: .getColString(j, "UTF-8"))
211: + ", ");
212: System.out.println();
213: }
214: System.out.println("EndOfTable");
215: }
216:
217: public static void main(String[] args) {
218: //File f = new File("d:\\\\mc\\privat\\fixtest.db");
219: File f = new File("/Users/admin/fixtest.db");
220: kelondroRow rowdef = new kelondroRow("byte[] a-12, byte[] b-4",
221: kelondroNaturalOrder.naturalOrder, 0);
222: try {
223: System.out.println("erster Test");
224: f.delete();
225: kelondroFixedWidthArray k = new kelondroFixedWidthArray(f,
226: rowdef, 6);
227: k.set(3, k.row().newEntry(
228: new byte[][] { "test123".getBytes(),
229: "abcd".getBytes() }));
230: k.add(k.row().newEntry(
231: new byte[][] { "test456".getBytes(),
232: "efgh".getBytes() }));
233: k.close();
234:
235: k = new kelondroFixedWidthArray(f, rowdef, 6);
236: System.out.println(k.get(2).toString());
237: System.out.println(k.get(3).toString());
238: k.close();
239:
240: System.out.println("zweiter Test");
241: f.delete();
242: k = new kelondroFixedWidthArray(f, rowdef, 6);
243: k
244: .add(k.row().newEntry(
245: new byte[][] { "a".getBytes(),
246: "xxxx".getBytes() }));
247: k
248: .add(k.row().newEntry(
249: new byte[][] { "b".getBytes(),
250: "xxxx".getBytes() }));
251: k.remove(0);
252:
253: k
254: .add(k.row().newEntry(
255: new byte[][] { "c".getBytes(),
256: "xxxx".getBytes() }));
257: k
258: .add(k.row().newEntry(
259: new byte[][] { "d".getBytes(),
260: "xxxx".getBytes() }));
261: k
262: .add(k.row().newEntry(
263: new byte[][] { "e".getBytes(),
264: "xxxx".getBytes() }));
265: k
266: .add(k.row().newEntry(
267: new byte[][] { "f".getBytes(),
268: "xxxx".getBytes() }));
269: k.remove(0);
270: k.remove(1);
271:
272: k.print();
273: k.print();
274: k.close();
275:
276: System.out.println("dritter Test");
277: f.delete();
278: k = new kelondroFixedWidthArray(f, rowdef, 6);
279: for (int i = 1; i <= 200; i = i * 2) {
280: for (int j = 0; j < i * 2; j++) {
281: k
282: .add(k
283: .row()
284: .newEntry(
285: new byte[][] {
286: (Integer
287: .toString(i)
288: + "-" + Integer
289: .toString(j))
290: .getBytes(),
291: "xxxx".getBytes() }));
292: }
293: for (int j = 0; j < i; j++) {
294: k.remove(j);
295: }
296: }
297: k.print();
298: k.print();
299: k.close();
300:
301: } catch (IOException e) {
302: e.printStackTrace();
303: }
304: }
305:
306: }
|