public virtual void DeallocateObject(IPersistent obj) { lock (this) { lock (objectCache) { int oid = obj.Oid; if (oid == 0) { return; } long pos = GetPos(oid); objectCache.Remove(oid); int offs = (int) pos & (Page.pageSize - 1); if ((offs & (dbFreeHandleFlag | dbPageObjectFlag)) != 0) { throw new StorageError(StorageError.DELETED_OBJECT); } Page pg = pool.GetPage(pos - offs); offs &= ~ dbFlagsMask; int size = ObjectHeader.GetSize(pg.data, offs); pool.Unfix(pg); FreeId(oid); if ((pos & dbModifiedFlag) != 0) { Free(pos & ~ dbFlagsMask, size); } else { CloneBitmap(pos, size); } obj.AssignOid(this, 0, false); } } }
private void StoreObject0(IPersistent obj) { obj.OnStore(); int oid = obj.Oid; bool newObject = false; if (oid == 0) { oid = AllocateId(); if (!obj.Deleted) { objectCache.Put(oid, obj); } obj.AssignOid(this, oid, false); newObject = true; } else if (obj.Modified) { objectCache.ClearDirty(oid); } byte[] data = PackObject(obj); long pos; int newSize = ObjectHeader.GetSize(data, 0); if (newObject || (pos = GetPos(oid)) == 0) { pos = Allocate(newSize, 0); SetPos(oid, pos | dbModifiedFlag); } else { int offs = (int) pos & (Page.pageSize - 1); if ((offs & (dbFreeHandleFlag | dbPageObjectFlag)) != 0) { throw new StorageError(StorageError.DELETED_OBJECT); } Page pg = pool.GetPage(pos - offs); offs &= ~ dbFlagsMask; int size = ObjectHeader.GetSize(pg.data, offs); pool.Unfix(pg); if ((pos & dbModifiedFlag) == 0) { CloneBitmap(pos & ~ dbFlagsMask, size); pos = Allocate(newSize, 0); SetPos(oid, pos | dbModifiedFlag); } else { if (((newSize + dbAllocationQuantum - 1) & ~ (dbAllocationQuantum - 1)) > ((size + dbAllocationQuantum - 1) & ~ (dbAllocationQuantum - 1))) { long newPos = Allocate(newSize, 0); CloneBitmap(pos & ~ dbFlagsMask, size); Free(pos & ~ dbFlagsMask, size); pos = newPos; SetPos(oid, pos | dbModifiedFlag); } else if (newSize < size) { ObjectHeader.SetSize(data, 0, size); } } } modified = true; pool.Put(pos & ~ dbFlagsMask, data, newSize); }
internal void AssignOid(IPersistent obj, int oid) { obj.AssignOid(this, oid, false); }
internal IPersistent LoadStub(int oid, IPersistent obj, Type cls) { long pos = GetPos(oid); if ((pos & (dbFreeHandleFlag | dbPageObjectFlag)) != 0) { throw new StorageError(StorageError.DELETED_OBJECT); } byte[] body = pool.Get(pos & ~ dbFlagsMask); ClassDescriptor desc; int typeOid = ObjectHeader.GetType(body, 0); if (typeOid == 0) { //UPGRADE_TODO: Method 'java.util.HashMap.get' was converted to 'System.Collections.Hashtable.Item' which has a different behavior. desc = (ClassDescriptor) classDescMap[cls]; } else { desc = FindClassDescriptor(typeOid); } if (obj == null) { obj = (IPersistent) desc.NewInstance(); objectCache.Put(oid, obj); } obj.AssignOid(this, oid, false); if (obj is FastSerializable) { ((FastSerializable) obj).Unpack(body, ObjectHeader.Sizeof, encoding); } else { try { UnpackObject(obj, desc, obj.RecursiveLoading, body, ObjectHeader.Sizeof, obj); } catch (System.Exception x) { throw new StorageError(StorageError.ACCESS_VIOLATION, x); } } obj.OnLoad(); return obj; }
public virtual int MakePersistent(IPersistent obj) { lock (this) { if (!opened) throw new StorageError(StorageError.STORAGE_NOT_OPENED); if (obj == null) return 0; int oid = obj.Oid; if (oid != 0) return oid; lock (objectCache) { oid = AllocateId(); obj.AssignOid(this, oid, false); SetPos(oid, 0); objectCache.Put(oid, obj); obj.Modify(); return oid; } } }