001: /* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com
002:
003: This file is part of the db4o open source object database.
004:
005: db4o is free software; you can redistribute it and/or modify it under
006: the terms of version 2 of the GNU General Public License as published
007: by the Free Software Foundation and as clarified by db4objects' GPL
008: interpretation policy, available at
009: http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
010: Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
011: Suite 350, San Mateo, CA 94403, USA.
012:
013: db4o is distributed in the hope that it will be useful, but WITHOUT ANY
014: WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: for more details.
017:
018: You should have received a copy of the GNU General Public License along
019: with this program; if not, write to the Free Software Foundation, Inc.,
020: 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
021: package com.db4o.internal;
022:
023: import java.io.IOException;
024:
025: import com.db4o.*;
026: import com.db4o.foundation.*;
027: import com.db4o.internal.mapping.*;
028: import com.db4o.internal.slots.*;
029:
030: /**
031: * @exclude
032: */
033: public final class BufferPair implements SlotBuffer {
034: private Buffer _source;
035: private Buffer _target;
036: private DefragContext _mapping;
037: private Transaction _systemTrans;
038:
039: public BufferPair(Buffer source, DefragContext mapping,
040: Transaction systemTrans) {
041: _source = source;
042: _mapping = mapping;
043: _target = new Buffer(source.length());
044: _source.copyTo(_target, 0, 0, _source.length());
045: _systemTrans = systemTrans;
046: }
047:
048: public int offset() {
049: return _source.offset();
050: }
051:
052: public void offset(int offset) {
053: _source.offset(offset);
054: _target.offset(offset);
055: }
056:
057: public void incrementOffset(int numBytes) {
058: _source.incrementOffset(numBytes);
059: _target.incrementOffset(numBytes);
060: }
061:
062: public void incrementIntSize() {
063: incrementOffset(Const4.INT_LENGTH);
064: }
065:
066: public int copyUnindexedID() {
067: int orig = _source.readInt();
068: int mapped = -1;
069: try {
070: mapped = _mapping.mappedID(orig);
071: } catch (MappingNotFoundException exc) {
072: mapped = _mapping.allocateTargetSlot(Const4.POINTER_LENGTH)
073: .address();
074: _mapping.mapIDs(orig, mapped, false);
075: _mapping.registerUnindexed(orig);
076: }
077: _target.writeInt(mapped);
078: return mapped;
079: }
080:
081: public int copyID() {
082: // This code is slightly redundant.
083: // The profiler shows it's a hotspot.
084: // The following would be non-redudant.
085: // return copy(false, false);
086:
087: int mapped = _mapping.mappedID(_source.readInt(), false);
088: _target.writeInt(mapped);
089: return mapped;
090: }
091:
092: public int copyID(boolean flipNegative, boolean lenient) {
093: int id = _source.readInt();
094: return internalCopyID(flipNegative, lenient, id);
095: }
096:
097: public MappedIDPair copyIDAndRetrieveMapping() {
098: int id = _source.readInt();
099: return new MappedIDPair(id, internalCopyID(false, false, id));
100: }
101:
102: private int internalCopyID(boolean flipNegative, boolean lenient,
103: int id) {
104: if (flipNegative && id < 0) {
105: id = -id;
106: }
107: int mapped = _mapping.mappedID(id, lenient);
108: if (flipNegative && id < 0) {
109: mapped = -mapped;
110: }
111: _target.writeInt(mapped);
112: return mapped;
113: }
114:
115: public void readBegin(byte identifier) {
116: _source.readBegin(identifier);
117: _target.readBegin(identifier);
118: }
119:
120: public byte readByte() {
121: byte value = _source.readByte();
122: _target.incrementOffset(1);
123: return value;
124: }
125:
126: public int readInt() {
127: int value = _source.readInt();
128: _target.incrementOffset(Const4.INT_LENGTH);
129: return value;
130: }
131:
132: public void writeInt(int value) {
133: _source.incrementOffset(Const4.INT_LENGTH);
134: _target.writeInt(value);
135: }
136:
137: public void write(LocalObjectContainer file, int address) {
138: file.writeBytes(_target, address, 0);
139: }
140:
141: public void incrementStringOffset(LatinStringIO sio) {
142: incrementStringOffset(sio, _source);
143: incrementStringOffset(sio, _target);
144: }
145:
146: private void incrementStringOffset(LatinStringIO sio, Buffer buffer) {
147: int length = buffer.readInt();
148: if (length > 0) {
149: sio.read(buffer, length);
150: }
151: }
152:
153: public Buffer source() {
154: return _source;
155: }
156:
157: public Buffer target() {
158: return _target;
159: }
160:
161: public IDMapping mapping() {
162: return _mapping;
163: }
164:
165: public Transaction systemTrans() {
166: return _systemTrans;
167: }
168:
169: public DefragContext context() {
170: return _mapping;
171: }
172:
173: public static void processCopy(DefragContext context, int sourceID,
174: SlotCopyHandler command) throws CorruptionException,
175: IOException {
176: processCopy(context, sourceID, command, false);
177: }
178:
179: public static void processCopy(DefragContext context, int sourceID,
180: SlotCopyHandler command, boolean registerAddressMapping)
181: throws CorruptionException, IOException {
182: Buffer sourceReader = context.sourceBufferByID(sourceID);
183: processCopy(context, sourceID, command, registerAddressMapping,
184: sourceReader);
185: }
186:
187: public static void processCopy(DefragContext context, int sourceID,
188: SlotCopyHandler command, boolean registerAddressMapping,
189: Buffer sourceReader) throws CorruptionException,
190: IOException {
191: int targetID = context.mappedID(sourceID);
192:
193: Slot targetSlot = context.allocateTargetSlot(sourceReader
194: .length());
195:
196: if (registerAddressMapping) {
197: int sourceAddress = context.sourceAddressByID(sourceID);
198: context.mapIDs(sourceAddress, targetSlot.address(), false);
199: }
200:
201: Buffer targetPointerReader = new Buffer(Const4.POINTER_LENGTH);
202: if (Deploy.debug) {
203: targetPointerReader.writeBegin(Const4.YAPPOINTER);
204: }
205: targetPointerReader.writeInt(targetSlot.address());
206: targetPointerReader.writeInt(targetSlot.length());
207: if (Deploy.debug) {
208: targetPointerReader.writeEnd();
209: }
210: context.targetWriteBytes(targetPointerReader, targetID);
211:
212: BufferPair readers = new BufferPair(sourceReader, context,
213: context.systemTrans());
214: command.processCopy(readers);
215: context.targetWriteBytes(readers, targetSlot.address());
216: }
217:
218: public void writeByte(byte value) {
219: _source.incrementOffset(1);
220: _target.writeByte(value);
221: }
222:
223: public long readLong() {
224: long value = _source.readLong();
225: _target.incrementOffset(Const4.LONG_LENGTH);
226: return value;
227: }
228:
229: public void writeLong(long value) {
230: _source.incrementOffset(Const4.LONG_LENGTH);
231: _target.writeLong(value);
232: }
233:
234: public BitMap4 readBitMap(int bitCount) {
235: BitMap4 value = _source.readBitMap(bitCount);
236: _target.incrementOffset(value.marshalledLength());
237: return value;
238: }
239:
240: public void copyBytes(byte[] target, int sourceOffset,
241: int targetOffset, int length) {
242: _source.copyBytes(target, sourceOffset, targetOffset, length);
243: }
244:
245: public void readEnd() {
246: _source.readEnd();
247: _target.readEnd();
248: }
249:
250: public int preparePayloadRead() {
251: int newPayLoadOffset = readInt();
252: readInt();
253: int linkOffSet = offset();
254: offset(newPayLoadOffset);
255: return linkOffSet;
256: }
257: }
|