📄 storageimpl.cs
字号:
pool.flush();
}
else
{
int curr = header.curr;
currIndex = curr;
if (header.root[curr].indexSize != header.root[curr].shadowIndexSize)
{
throw new StorageError(StorageError.ErrorCode.DATABASE_CORRUPTED);
}
if (isDirty())
{
if (listener != null)
{
listener.DatabaseCorrupted();
}
System.Console.WriteLine("Database was not normally closed: start recovery");
header.root[1-curr].size = header.root[curr].size;
header.root[1-curr].indexUsed = header.root[curr].indexUsed;
header.root[1-curr].freeList = header.root[curr].freeList;
header.root[1-curr].index = header.root[curr].shadowIndex;
header.root[1-curr].indexSize = header.root[curr].shadowIndexSize;
header.root[1-curr].shadowIndex = header.root[curr].index;
header.root[1-curr].shadowIndexSize = header.root[curr].indexSize;
header.root[1-curr].bitmapEnd = header.root[curr].bitmapEnd;
header.root[1-curr].rootObject = header.root[curr].rootObject;
header.root[1-curr].classDescList = header.root[curr].classDescList;
header.root[1-curr].bitmapExtent = header.root[curr].bitmapExtent;
pg = pool.putPage(0);
header.pack(pg.data);
pool.unfix(pg);
pool.copy(header.root[1-curr].index,
header.root[curr].index,
(header.root[curr].indexUsed * 8L + Page.pageSize - 1) & ~ (Page.pageSize - 1));
if (listener != null)
{
listener.RecoveryCompleted();
}
System.Console.WriteLine("Recovery completed");
}
currIndexSize = header.root[1-curr].indexUsed;
committedIndexSize = currIndexSize;
usedSize = header.root[curr].size;
}
int nBitmapPages = header.root[1-currIndex].bitmapExtent == 0 ? dbBitmapPages : dbLargeBitmapPages;
bitmapPageAvailableSpace = new int[nBitmapPages];
for (i = 0; i < bitmapPageAvailableSpace.Length; i++)
{
bitmapPageAvailableSpace[i] = int.MaxValue;
}
currRBitmapPage = currPBitmapPage = 0;
currRBitmapOffs = currPBitmapOffs = 0;
opened = true;
reloadScheme();
}
}
public bool IsOpened()
{
return opened;
}
internal static void checkIfFinal(ClassDescriptor desc)
{
System.Type cls = desc.cls;
for (ClassDescriptor next = desc.next; next != null; next = next.next)
{
next.Load();
if (cls.IsAssignableFrom(next.cls))
{
desc.hasSubclasses = true;
}
else if (next.cls.IsAssignableFrom(cls))
{
next.hasSubclasses = true;
}
}
}
internal void reloadScheme()
{
classDescMap.Clear();
customAllocatorMap = null;
customAllocatorList = null;
defaultAllocator = new DefaultAllocator(this);
int descListOid = header.root[1-currIndex].classDescList;
classDescMap[typeof(ClassDescriptor)] = new ClassDescriptor(this, typeof(ClassDescriptor));
classDescMap[typeof(ClassDescriptor.FieldDescriptor)] = new ClassDescriptor(this, typeof(ClassDescriptor.FieldDescriptor));
if (descListOid != 0)
{
ClassDescriptor desc;
descList = findClassDescriptor(descListOid);
for (desc = descList; desc != null; desc = desc.next)
{
desc.Load();
}
for (desc = descList; desc != null; desc = desc.next)
{
if (classDescMap[desc.cls] == desc)
{
desc.resolve();
}
if (desc.allocator != null)
{
if (customAllocatorMap == null)
{
customAllocatorMap = new Hashtable();
customAllocatorList = new ArrayList();
}
desc.allocator.Load();
customAllocatorMap[desc.cls] = desc.allocator;
customAllocatorList.Add(desc.allocator);
}
checkIfFinal(desc);
}
}
else
{
descList = null;
}
#if !COMPACT_NET_FRAMEWORK
if (runtimeCodeGeneration == RuntimeCodeGeneration.Asynchronous)
{
codeGenerationThread = new Thread(new ThreadStart(generateSerializers));
codeGenerationThread.Priority = ThreadPriority.BelowNormal;
codeGenerationThread.IsBackground = true;
codeGenerationThread.Start();
}
else if (runtimeCodeGeneration == RuntimeCodeGeneration.Synchronous)
{
generateSerializers();
}
#endif
}
internal void generateSerializers()
{
for (ClassDescriptor desc = descList; desc != null; desc = desc.next)
{
desc.generateSerializer();
}
}
internal void assignOid(IPersistent obj, int oid)
{
obj.AssignOid(this, oid, false);
}
internal void registerClassDescriptor(ClassDescriptor desc)
{
classDescMap[desc.cls] = desc;
desc.next = descList;
descList = desc;
checkIfFinal(desc);
storeObject0(desc, false);
header.root[1-currIndex].classDescList = desc.Oid;
modified = true;
}
internal ClassDescriptor getClassDescriptor(System.Type cls)
{
ClassDescriptor desc = (ClassDescriptor) classDescMap[cls];
if (desc == null)
{
desc = new ClassDescriptor(this, cls);
desc.generateSerializer();
registerClassDescriptor(desc);
}
return desc;
}
public void Commit()
{
lock (backgroundGcMonitor)
{
lock(this)
{
if (!opened)
{
throw new StorageError(StorageError.ErrorCode.STORAGE_NOT_OPENED);
}
objectCache.flush();
if (customAllocatorList != null)
{
foreach (CustomAllocator alloc in customAllocatorList)
{
if (alloc.IsModified())
{
alloc.Store();
}
alloc.Commit();
}
}
if (!modified)
{
return;
}
commit0();
modified = false;
}
}
}
private void commit0()
{
int curr = currIndex;
int i, j, n;
int[] map = dirtyPagesMap;
int oldIndexSize = header.root[curr].indexSize;
int newIndexSize = header.root[1-curr].indexSize;
int nPages = committedIndexSize >> dbHandlesPerPageBits;
Page pg;
if (newIndexSize > oldIndexSize)
{
cloneBitmap(header.root[curr].index, oldIndexSize*8L);
long newIndex;
while (true)
{
newIndex = allocate(newIndexSize*8L, 0);
if (newIndexSize == header.root[1-curr].indexSize)
{
break;
}
free(newIndex, newIndexSize*8L);
newIndexSize = header.root[1-curr].indexSize;
}
header.root[1-curr].shadowIndex = newIndex;
header.root[1-curr].shadowIndexSize = newIndexSize;
free(header.root[curr].index, oldIndexSize*8L);
}
long currSize = header.root[1-curr].size;
for (i = 0; i < nPages; i++)
{
if ((map[i >> 5] & (1 << (i & 31))) != 0)
{
Page srcIndex = pool.getPage(header.root[1-curr].index + (long)i * Page.pageSize);
Page dstIndex = pool.getPage(header.root[curr].index + (long)i * Page.pageSize);
for (j = 0; j < Page.pageSize; j += 8)
{
long pos = Bytes.unpack8(dstIndex.data, j);
if (Bytes.unpack8(srcIndex.data, j) != pos && pos < currSize)
{
if ((pos & dbFreeHandleFlag) == 0)
{
if ((pos & dbPageObjectFlag) != 0)
{
free(pos & ~ dbFlagsMask, Page.pageSize);
}
else if (pos != 0)
{
int offs = (int) pos & (Page.pageSize - 1);
pg = pool.getPage(pos - offs);
free(pos, ObjectHeader.getSize(pg.data, offs));
pool.unfix(pg);
}
}
}
}
pool.unfix(srcIndex);
pool.unfix(dstIndex);
}
}
n = committedIndexSize & (dbHandlesPerPage - 1);
if (n != 0 && (map[i >> 5] & (1 << (i & 31))) != 0)
{
Page srcIndex = pool.getPage(header.root[1-curr].index + (long)i * Page.pageSize);
Page dstIndex = pool.getPage(header.root[curr].index + (long)i * Page.pageSize);
j = 0;
do
{
long pos = Bytes.unpack8(dstIndex.data, j);
if (Bytes.unpack8(srcIndex.data, j) != pos && pos < currSize)
{
if ((pos & dbFreeHandleFlag) == 0)
{
if ((pos & dbPageObjectFlag) != 0)
{
free(pos & ~ dbFlagsMask, Page.pageSize);
}
else if (pos != 0)
{
int offs = (int) pos & (Page.pageSize - 1);
pg = pool.getPage(pos - offs);
free(pos, ObjectHeader.getSize(pg.data, offs));
pool.unfix(pg);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -