KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > db4o > YapWriter


1 /* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com
2
3 This file is part of the db4o open source object database.
4
5 db4o is free software; you can redistribute it and/or modify it under
6 the terms of version 2 of the GNU General Public License as published
7 by the Free Software Foundation and as clarified by db4objects' GPL
8 interpretation policy, available at
9 http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
10 Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
11 Suite 350, San Mateo, CA 94403, USA.
12
13 db4o is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */

21 package com.db4o;
22
23 import java.io.*;
24
25 import com.db4o.foundation.*;
26 import com.db4o.foundation.network.*;
27
28 /**
29  * public for .NET conversion reasons
30  *
31  * TODO: Split this class for individual usecases. Only use the member
32  * variables needed for the respective usecase.
33  *
34  * @exclude
35  */

36 public final class YapWriter extends YapReader {
37     
38
39     private int i_address;
40     private int _addressOffset;
41
42     private int i_cascadeDelete;
43
44     private Tree i_embedded;
45     private int i_id;
46
47     // carries instantiation depth through the reading process
48
private int i_instantionDepth;
49     private int i_length;
50
51     Transaction i_trans;
52
53     // carries updatedepth depth through the update process
54
// and carries instantiation information through the reading process
55
private int i_updateDepth = 1;
56     
57     public int _payloadOffset;
58     
59
60     public YapWriter(Transaction a_trans, int a_initialBufferSize) {
61         i_trans = a_trans;
62         i_length = a_initialBufferSize;
63         _buffer = new byte[i_length];
64     }
65
66     public YapWriter(Transaction a_trans, int a_address, int a_initialBufferSize) {
67         this(a_trans, a_initialBufferSize);
68         i_address = a_address;
69     }
70
71     public YapWriter(YapWriter parent, YapWriter[] previousRead, int previousCount) {
72         previousRead[previousCount++] = this;
73         int parentID = parent.readInt();
74         i_length = parent.readInt();
75         i_id = parent.readInt();
76         previousRead[parentID].addEmbedded(this);
77         i_address = parent.readInt();
78         i_trans = parent.getTransaction();
79         _buffer = new byte[i_length];
80         System.arraycopy(parent._buffer, parent._offset, _buffer, 0, i_length);
81         parent._offset += i_length;
82         if (previousCount < previousRead.length) {
83             new YapWriter(parent, previousRead, previousCount);
84         }
85     }
86
87     // void debug(){
88
// if(Debug.current){
89
// System.out.println("Address: " + i_address + " ID:" + i_id);
90
// if(i_embedded != null){
91
// System.out.println("Children:");
92
// Iterator i = i_embedded.iterator();
93
// while(i.hasNext()){
94
// ((YapBytes)(i.next())).debug();
95
// }
96
// }
97
// }
98
// }
99

100     public void addEmbedded(YapWriter a_bytes) {
101         i_embedded = Tree.add(i_embedded, new TreeIntObject(a_bytes.getID(), a_bytes));
102     }
103
104
105     public int appendTo(final YapReader a_bytes, int a_id) {
106         a_id++;
107         a_bytes.writeInt(i_length);
108         a_bytes.writeInt(i_id);
109         a_bytes.writeInt(i_address);
110         a_bytes.append(_buffer);
111         final int[] newID = { a_id };
112         final int myID = a_id;
113         forEachEmbedded(new VisitorYapBytes() {
114             public void visit(YapWriter a_embedded) {
115                 a_bytes.writeInt(myID);
116                 newID[0] = a_embedded.appendTo(a_bytes, newID[0]);
117             }
118         });
119         return newID[0];
120     }
121
122     public int cascadeDeletes() {
123         return i_cascadeDelete;
124     }
125
126     public void debugCheckBytes() {
127         if (Debug.xbytes) {
128             if (_offset != i_length) {
129                 // Db4o.log("!!! YapBytes.debugCheckBytes not all bytes used");
130
// This is normal for writing The FreeSlotArray, becauce one
131
// slot is possibly reserved by it's own pointer.
132
}
133         }
134     }
135
136     public int embeddedCount() {
137         final int[] count = { 0 };
138         forEachEmbedded(new VisitorYapBytes() {
139             public void visit(YapWriter a_bytes) {
140                 count[0] += 1 + a_bytes.embeddedCount();
141             }
142         });
143         return count[0];
144     }
145
146     public int embeddedLength() {
147         final int[] length = { 0 };
148         forEachEmbedded(new VisitorYapBytes() {
149             public void visit(YapWriter a_bytes) {
150                 length[0] += a_bytes.getLength() + a_bytes.embeddedLength();
151             }
152         });
153         return length[0];
154     }
155
156     void forEachEmbedded(final VisitorYapBytes a_visitor) {
157         if (i_embedded != null) {
158             i_embedded.traverse(new Visitor4() {
159                 public void visit(Object JavaDoc a_object) {
160                     a_visitor.visit((YapWriter) ((TreeIntObject)a_object)._object);
161                 }
162             });
163         }
164     }
165
166     public int getAddress() {
167         return i_address;
168     }
169     
170     public int addressOffset(){
171         return _addressOffset;
172     }
173
174     public int getID() {
175         return i_id;
176     }
177
178     public int getInstantiationDepth() {
179         return i_instantionDepth;
180     }
181
182     public int getLength() {
183         return i_length;
184     }
185
186     public YapStream getStream() {
187         return i_trans.stream();
188     }
189     
190     public YapStream stream(){
191         return i_trans.stream();
192     }
193     
194     public YapFile file(){
195         return i_trans.i_file;
196     }
197
198     public Transaction getTransaction() {
199         return i_trans;
200     }
201
202     public int getUpdateDepth() {
203         return i_updateDepth;
204     }
205     
206     byte[] getWrittenBytes(){
207         byte[] bytes = new byte[_offset];
208         System.arraycopy(_buffer, 0, bytes, 0, _offset);
209         return bytes;
210     }
211     
212     public int preparePayloadRead() {
213         int newPayLoadOffset = readInt();
214         int length = readInt();
215         int linkOffSet = _offset;
216         _offset = newPayLoadOffset;
217         _payloadOffset += length;
218         return linkOffSet;
219     }
220
221     public void read() {
222         stream().readBytes(_buffer, i_address,_addressOffset, i_length);
223     }
224
225     public final boolean read(YapSocket sock) throws IOException {
226         int offset = 0;
227         int length = i_length;
228         while (length > 0) {
229             int read = sock.read(_buffer, offset, length);
230             if(read<0) {
231                 return false;
232             }
233             offset += read;
234             length -= read;
235         }
236         return true;
237     }
238
239     public final YapWriter readEmbeddedObject() {
240         int id = readInt();
241         int length = readInt();
242         YapWriter bytes = null;
243         Tree tio = TreeInt.find(i_embedded, id);
244         if (tio != null) {
245             bytes = (YapWriter) ((TreeIntObject)tio)._object;
246         }else{
247             bytes = stream().readWriterByAddress(i_trans, id, length);
248             if (bytes != null) {
249                 bytes.setID(id);
250             }
251         }
252         if(bytes != null){
253             bytes.setUpdateDepth(getUpdateDepth());
254             bytes.setInstantiationDepth(getInstantiationDepth());
255         }
256         return bytes;
257     }
258
259     public final YapWriter readYapBytes() {
260         int length = readInt();
261         if (length == 0) {
262             return null;
263         }
264         YapWriter yb = new YapWriter(i_trans, length);
265         System.arraycopy(_buffer, _offset, yb._buffer, 0, length);
266         _offset += length;
267         return yb;
268     }
269
270     public void removeFirstBytes(int aLength) {
271         i_length -= aLength;
272         byte[] temp = new byte[i_length];
273         System.arraycopy(_buffer, aLength, temp, 0, i_length);
274         _buffer = temp;
275         _offset -= aLength;
276         if (_offset < 0) {
277             _offset = 0;
278         }
279     }
280
281     public void address(int a_address) {
282         i_address = a_address;
283     }
284
285     public void setCascadeDeletes(int depth) {
286         i_cascadeDelete = depth;
287     }
288
289     public void setID(int a_id) {
290         i_id = a_id;
291     }
292
293     public void setInstantiationDepth(int a_depth) {
294         i_instantionDepth = a_depth;
295     }
296
297     public void setTransaction(Transaction aTrans) {
298         i_trans = aTrans;
299     }
300
301     public void setUpdateDepth(int a_depth) {
302         i_updateDepth = a_depth;
303     }
304
305     public void slotDelete() {
306         i_trans.slotDelete(i_id, i_address, i_length);
307     }
308     
309     public void trim4(int a_offset, int a_length) {
310         byte[] temp = new byte[a_length];
311         System.arraycopy(_buffer, a_offset, temp, 0, a_length);
312         _buffer = temp;
313         i_length = a_length;
314     }
315
316     void useSlot(int a_adress) {
317         i_address = a_adress;
318         _offset = 0;
319     }
320
321     public void useSlot(int a_adress, int a_length) {
322         i_address = a_adress;
323         _offset = 0;
324         if (a_length > _buffer.length) {
325             _buffer = new byte[a_length];
326         }
327         i_length = a_length;
328     }
329
330     public void useSlot(int a_id, int a_adress, int a_length) {
331         i_id = a_id;
332         useSlot(a_adress, a_length);
333     }
334
335     public void write() {
336         if (Debug.xbytes) {
337             debugCheckBytes();
338         }
339         file().writeBytes(this, i_address, _addressOffset);
340     }
341
342     public void writeEmbedded() {
343         final YapWriter finalThis = this;
344         forEachEmbedded(new VisitorYapBytes() {
345             public void visit(YapWriter a_bytes) {
346                 a_bytes.writeEmbedded();
347                 stream().writeEmbedded(finalThis, a_bytes);
348             }
349         });
350         
351         // TODO: It may be possible to remove the following to
352
// allow indexes to be created from the bytes passed
353
// from the client without having to reread. Currently
354
// the bytes don't seem to be found and there is a
355
// problem with encryption during the write process.
356

357         i_embedded = null; // no reuse !!!
358
}
359
360     public void writeEmbeddedNull() {
361         writeInt(0);
362         writeInt(0);
363     }
364
365     public void writeEncrypt() {
366         if (Deploy.debug) {
367             debugCheckBytes();
368         }
369         writeEncrypt(file(),i_address, _addressOffset);
370     }
371     
372     /* Only used for Strings, topLevel therefore means aligning blocksize, so
373      * index will be possible.
374      */

375     public void writePayload(YapWriter payLoad, boolean topLevel){
376         checkMinimumPayLoadOffsetAndWritePointerAndLength(payLoad.getLength(), topLevel);
377         System.arraycopy(payLoad._buffer, 0, _buffer, _payloadOffset, payLoad._buffer.length);
378         transferPayLoadAddress(payLoad, _payloadOffset);
379         _payloadOffset += payLoad._buffer.length;
380     }
381     
382     private void checkMinimumPayLoadOffsetAndWritePointerAndLength(int length, boolean alignToBlockSize){
383         if(_payloadOffset <= _offset + (YapConst.INT_LENGTH * 2)){
384             _payloadOffset = _offset + (YapConst.INT_LENGTH * 2);
385         }
386         if(alignToBlockSize){
387             _payloadOffset = stream().alignToBlockSize(_payloadOffset);
388         }
389         writeInt(_payloadOffset);
390         
391         // TODO: This length is here for historical reasons.
392
// It's actually never really needed during reading.
393
// It's only necessary because array and string used
394
// to consist of a double pointer in marshaller family 0
395
// and it was not considered a good idea to change
396
// their linkLength() values for compatibility reasons
397
// with marshaller family 0.
398
writeInt(length);
399     }
400     
401     public int reserveAndPointToPayLoadSlot(int length){
402         checkMinimumPayLoadOffsetAndWritePointerAndLength(length, false);
403         int linkOffset = _offset;
404         _offset = _payloadOffset;
405         _payloadOffset += length;
406         return linkOffset;
407     }
408     
409     public YapReader readPayloadWriter(int offset, int length){
410         YapWriter payLoad = new YapWriter(i_trans, 0, length);
411         System.arraycopy(_buffer,offset, payLoad._buffer, 0, length);
412         transferPayLoadAddress(payLoad, offset);
413         return payLoad;
414     }
415
416     private void transferPayLoadAddress(YapWriter toWriter, int offset) {
417         int blockedOffset = offset / stream().blockSize();
418         toWriter.i_address = i_address + blockedOffset;
419         toWriter.i_id = toWriter.i_address;
420         toWriter._addressOffset = _addressOffset;
421     }
422
423     void writeShortString(String JavaDoc a_string) {
424         writeShortString(i_trans, a_string);
425     }
426
427     public void moveForward(int length) {
428         _addressOffset += length;
429     }
430     
431     public void writeForward() {
432         write();
433         _addressOffset += i_length;
434         _offset = 0;
435     }
436     
437     public String JavaDoc toString(){
438         if(! Debug4.prettyToStrings){
439             return super.toString();
440         }
441         return "id " + i_id + " adr " + i_address + " len " + i_length;
442     }
443     
444     public void noXByteCheck() {
445         if(Debug.xbytes && Deploy.overwrite){
446             setID(YapConst.IGNORE_ID);
447         }
448     }
449     
450     public void writeIDs(IntIterator4 idIterator, int maxCount ) {
451         int savedOffset = _offset;
452         writeInt(0);
453         int actualCount = 0;
454         while(idIterator.moveNext()){
455             writeInt(idIterator.currentInt());
456             actualCount ++;
457             if(actualCount >= maxCount){
458                 break;
459             }
460         }
461         int secondSavedOffset = _offset;
462         _offset = savedOffset;
463         writeInt(actualCount);
464         _offset = secondSavedOffset;
465     }
466     
467
468 }
469
Popular Tags