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); }