1 21 package com.db4o; 22 23 import com.db4o.ext.*; 24 import com.db4o.foundation.*; 25 import com.db4o.inside.*; 26 import com.db4o.inside.btree.*; 27 import com.db4o.inside.marshall.*; 28 import com.db4o.inside.slots.*; 29 30 33 public class YapFieldUUID extends YapFieldVirtual { 34 35 private static final int LINK_LENGTH = YapConst.LONG_LENGTH + YapConst.ID_LENGTH; 36 37 YapFieldUUID(YapStream stream) { 38 super(); 39 i_name = YapConst.VIRTUAL_FIELD_PREFIX + "uuid"; 40 i_handler = new YLong(stream); 41 } 42 43 public void addFieldIndex(MarshallerFamily mf, YapClass yapClass, YapWriter writer, Slot oldSlot) { 44 45 boolean isnew = (oldSlot == null); 46 47 int offset = writer._offset; 48 int db4oDatabaseIdentityID = writer.readInt(); 49 long uuid = writer.readLong(); 50 writer._offset = offset; 51 52 YapFile yf = (YapFile)writer.getStream(); 53 54 if( (uuid == 0 || db4oDatabaseIdentityID == 0) && writer.getID() > 0 && ! isnew){ 55 DatabaseIdentityIDAndUUID identityAndUUID = readDatabaseIdentityIDAndUUID(yf, yapClass, oldSlot, false); 56 db4oDatabaseIdentityID = identityAndUUID.databaseIdentityID; 57 uuid = identityAndUUID.uuid; 58 } 59 60 if(db4oDatabaseIdentityID == 0){ 61 db4oDatabaseIdentityID = yf.identity().getID(writer.getTransaction()); 62 } 63 64 if(uuid == 0){ 65 uuid = yf.generateTimeStampId(); 66 } 67 68 writer.writeInt(db4oDatabaseIdentityID); 69 writer.writeLong(uuid); 70 71 if(isnew){ 72 addIndexEntry(writer, new Long (uuid)); 73 } 74 } 75 76 static class DatabaseIdentityIDAndUUID { 77 public int databaseIdentityID; 78 public long uuid; 79 public DatabaseIdentityIDAndUUID(int databaseIdentityID_, long uuid_) { 80 databaseIdentityID = databaseIdentityID_; 81 uuid = uuid_; 82 } 83 } 84 85 private DatabaseIdentityIDAndUUID readDatabaseIdentityIDAndUUID(YapStream stream, YapClass yapClass, Slot oldSlot, boolean checkClass) { 86 if(DTrace.enabled){ 87 DTrace.REREAD_OLD_UUID.logLength(oldSlot.getAddress(), oldSlot.getLength()); 88 } 89 YapReader reader = stream.readReaderByAddress(oldSlot.getAddress(), oldSlot.getLength()); 90 if(checkClass){ 91 YapClass realClass = YapClass.readClass(stream,reader); 92 if(realClass != yapClass){ 93 return null; 94 } 95 } 96 if (null == yapClass.findOffset(reader, this)) { 97 return null; 98 } 99 return new DatabaseIdentityIDAndUUID(reader.readInt(), reader.readLong()); 100 } 101 102 public void delete(MarshallerFamily mf, YapWriter a_bytes, boolean isUpdate) { 103 if(isUpdate){ 104 a_bytes.incrementOffset(linkLength()); 105 return; 106 } 107 a_bytes.incrementOffset(YapConst.INT_LENGTH); 108 long longPart = a_bytes.readLong(); 109 if(longPart > 0){ 110 YapStream stream = a_bytes.getStream(); 111 if (stream.maintainsIndices()){ 112 removeIndexEntry(a_bytes.getTransaction(), a_bytes.getID(), new Long (longPart)); 113 } 114 } 115 } 116 117 public boolean hasIndex() { 118 return true; 119 } 120 121 public BTree getIndex(Transaction transaction) { 122 ensureIndex(transaction); 123 return super.getIndex(transaction); 124 } 125 126 protected void rebuildIndexForObject(YapFile stream, YapClass yapClass, int objectId) { 127 DatabaseIdentityIDAndUUID data = readDatabaseIdentityIDAndUUID(stream, yapClass, ((YapFileTransaction)stream.getSystemTransaction()).getCurrentSlotOfID(objectId), true); 128 if (null == data) { 129 return; 130 } 131 addIndexEntry(stream.getSystemTransaction(), objectId, new Long (data.uuid)); 132 } 133 134 private void ensureIndex(Transaction transaction) { 135 if (null == transaction) { 136 throw new ArgumentNullException(); 137 } 138 if (null != super.getIndex(transaction)) { 139 return; 140 } 141 YapFile file = ((YapFile)transaction.stream()); 142 SystemData sd = file.systemData(); 143 if(sd == null){ 144 return; 146 } 147 initIndex(transaction, sd.uuidIndexId()); 148 if (sd.uuidIndexId() == 0) { 149 sd.uuidIndexId(super.getIndex(transaction).getID()); 150 file.getFileHeader().writeVariablePart(file, 1); 151 } 152 } 153 154 void instantiate1(Transaction a_trans, YapObject a_yapObject, YapReader a_bytes) { 155 int dbID = a_bytes.readInt(); 156 YapStream stream = a_trans.stream(); 157 stream.showInternalClasses(true); 158 Db4oDatabase db = (Db4oDatabase)stream.getByID2(a_trans, dbID); 159 if(db != null && db.i_signature == null){ 160 stream.activate2(a_trans, db, 2); 161 } 162 VirtualAttributes va = a_yapObject.virtualAttributes(); 163 va.i_database = db; 164 va.i_uuid = a_bytes.readLong(); 165 stream.showInternalClasses(false); 166 } 167 168 public int linkLength() { 169 return LINK_LENGTH; 170 } 171 172 void marshall1(YapObject a_yapObject, YapWriter a_bytes, boolean a_migrating, boolean a_new) { 173 YapStream stream = a_bytes.getStream(); 174 Transaction trans = a_bytes.getTransaction(); 175 boolean indexEntry = a_new && stream.maintainsIndices(); 176 int dbID = 0; 177 VirtualAttributes attr = a_yapObject.virtualAttributes(); 178 179 boolean linkToDatabase = ! a_migrating; 180 if(attr != null && attr.i_database == null) { 181 linkToDatabase = true; 182 } 183 if(linkToDatabase){ 184 Db4oDatabase db = stream.identity(); 185 if(db == null){ 186 attr = null; 188 }else{ 189 if (attr.i_database == null) { 190 attr.i_database = db; 191 192 if (stream instanceof YapFile){ 194 attr.i_uuid = stream.generateTimeStampId(); 195 indexEntry = true; 196 } 197 } 198 db = attr.i_database; 199 if(db != null) { 200 dbID = db.getID(trans); 201 } 202 } 203 }else{ 204 if(attr != null){ 205 dbID = attr.i_database.getID(trans); 206 } 207 } 208 a_bytes.writeInt(dbID); 209 if(attr != null){ 210 a_bytes.writeLong(attr.i_uuid); 211 if(indexEntry){ 212 addIndexEntry(a_bytes, new Long (attr.i_uuid)); 213 } 214 }else{ 215 a_bytes.writeLong(0); 216 } 217 } 218 219 void marshallIgnore(YapReader writer) { 220 writer.writeInt(0); 221 writer.writeLong(0); 222 } 223 224 public Object [] objectAndYapObjectBySignature(final Transaction transaction, final long longPart, final byte[] signature) { 225 final BTreeRange range = search(transaction, new Long (longPart)); 226 final Iterator4 keys = range.keys(); 227 while (keys.moveNext()) { 228 final FieldIndexKey current = (FieldIndexKey) keys.current(); 229 final Object [] objectAndYapObject = getObjectAndYapObjectByID(transaction, current.parentID(), signature); 230 if (null != objectAndYapObject) { 231 return objectAndYapObject; 232 } 233 } 234 return new Object [2]; 235 } 236 237 protected Object [] getObjectAndYapObjectByID(Transaction transaction, int parentId, byte[] signature) { 238 Object [] arr = transaction.stream().getObjectAndYapObjectByID( 239 transaction, parentId); 240 if (arr[1] == null) { 241 return null; 242 } 243 YapObject yod = (YapObject) arr[1]; 244 VirtualAttributes vad = yod.virtualAttributes(transaction); 245 if (!Arrays4.areEqual(signature, vad.i_database.i_signature)) { 246 return null; 247 } 248 return arr; 249 } 250 251 public void defragField(MarshallerFamily mf, ReaderPair readers) { 252 readers.copyID(); 254 readers.incrementOffset(YapConst.LONG_LENGTH); 256 } 257 } | Popular Tags |