📄 storageimpl.cs
字号:
int bitOffs = (int) quantNo & 7;
allocatedDelta -= (long)objBitSize << dbAllocationQuantumBits;
usedSize -= (long)objBitSize << dbAllocationQuantumBits;
if ((pos & (Page.pageSize - 1)) == 0 && size >= Page.pageSize)
{
if (pageId == currPBitmapPage && offs < currPBitmapOffs)
{
currPBitmapOffs = offs;
}
}
if (pageId == currRBitmapPage && offs < currRBitmapOffs)
{
currRBitmapOffs = offs;
}
bitmapPageAvailableSpace[pageId] = System.Int32.MaxValue;
if (objBitSize > 8 - bitOffs)
{
objBitSize -= 8 - bitOffs;
pg.data[offs++] &= (byte)((1 << bitOffs) - 1);
while (objBitSize + offs * 8 > Page.pageSize * 8)
{
memset(pg, offs, 0, Page.pageSize - offs);
pool.unfix(pg);
pg = putBitmapPage(++pageId);
bitmapPageAvailableSpace[pageId] = System.Int32.MaxValue;
objBitSize -= (Page.pageSize - offs) * 8;
offs = 0;
}
while ((objBitSize -= 8) > 0)
{
pg.data[offs++] = (byte) 0;
}
pg.data[offs] &= (byte) (~ ((1 << (objBitSize + 8)) - 1));
}
else
{
pg.data[offs] &= (byte) (~ (((1 << objBitSize) - 1) << bitOffs));
}
pool.unfix(pg);
}
}
internal void cloneBitmap(long pos, long size)
{
lock (objectCache)
{
long quantNo = pos >> dbAllocationQuantumBits;
int objBitSize = (int)((size + dbAllocationQuantum - 1) >> dbAllocationQuantumBits);
int pageId = (int)(quantNo >> (Page.pageSizeLog + 3));
int offs = (int) (quantNo & (Page.pageSize * 8 - 1)) >> 3;
int bitOffs = (int) quantNo & 7;
int oid = getBitmapPageId(pageId);
pos = getPos(oid);
if ((pos & dbModifiedFlag) == 0)
{
dirtyPagesMap[oid >> (dbHandlesPerPageBits + 5)]
|= 1 << ((oid >> dbHandlesPerPageBits) & 31);
allocate(Page.pageSize, oid);
cloneBitmap(pos & ~ dbFlagsMask, Page.pageSize);
}
if (objBitSize > 8 - bitOffs)
{
objBitSize -= 8 - bitOffs;
offs += 1;
while (objBitSize + offs * 8 > Page.pageSize * 8)
{
oid = getBitmapPageId(++pageId);
pos = getPos(oid);
if ((pos & dbModifiedFlag) == 0)
{
dirtyPagesMap[oid >> (dbHandlesPerPageBits + 5)]
|= 1 << ((oid >> dbHandlesPerPageBits) & 31);
allocate(Page.pageSize, oid);
cloneBitmap(pos & ~ dbFlagsMask, Page.pageSize);
}
objBitSize -= (Page.pageSize - offs) * 8;
offs = 0;
}
}
}
}
public void Open(String filePath)
{
Open(filePath, DEFAULT_PAGE_POOL_SIZE);
}
public void Open(IFile file)
{
Open(file, DEFAULT_PAGE_POOL_SIZE);
}
public void Open(String filePath, int pagePoolSize)
{
IFile file = filePath.StartsWith("@")
? (IFile)new MultiFile(filePath.Substring(1), readOnly, noFlush)
: (IFile)new OSFile(filePath, readOnly, noFlush);
try
{
Open(file, pagePoolSize);
}
catch (StorageError ex)
{
file.Close();
throw ex;
}
}
public void ClearObjectCache()
{
objectCache.clear();
}
protected virtual OidHashTable createObjectCache(string kind, int pagePoolSize, int objectCacheSize)
{
if (pagePoolSize == 0 || "strong".Equals(kind))
{
return new StrongHashTable(objectCacheSize);
}
if ("weak".Equals(kind))
{
return new WeakHashTable(objectCacheSize);
}
if ("pinned".Equals(kind))
{
return new PinWeakHashTable(objectCacheSize);
}
return new LruObjectCache(objectCacheSize);
}
public void Open(String filePath, int pagePoolSize, String cipherKey)
{
Rc4File file = new Rc4File(filePath, readOnly, noFlush, cipherKey);
try
{
Open(file, pagePoolSize);
}
catch (StorageError ex)
{
file.Close();
throw ex;
}
}
protected void initialize(IFile file, int pagePoolSize)
{
if (lockFile)
{
file.Lock();
}
dirtyPagesMap = new int[dbDirtyPageBitmapSize/4+1];
gcThreshold = Int64.MaxValue;
backgroundGcMonitor = new object();
backgroundGcStartMonitor = new object();
gcGo = false;
gcThread = null;
gcActive = false;
gcDone = false;
allocatedDelta = 0;
resolvedTypes = new Hashtable();
nNestedTransactions = 0;
nBlockedTransactions = 0;
nCommittedTransactions = 0;
scheduledCommitTime = Int64.MaxValue;
#if COMPACT_NET_FRAMEWORK
transactionMonitor = new CNetMonitor();
#else
transactionMonitor = new object();
#endif
transactionLock = new PersistentResource();
modified = false;
objectCache = createObjectCache(cacheKind, pagePoolSize, objectCacheInitSize);
classDescMap = new Hashtable();
descList = null;
#if SUPPORT_RAW_TYPE
objectFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
#endif
header = new Header();
pool = new PagePool(pagePoolSize/Page.pageSize, pagePoolLruLimit);
pool.open(file);
}
public virtual void Open(IFile file, int pagePoolSize)
{
lock(this)
{
Page pg;
int i;
if (opened)
{
throw new StorageError(StorageError.ErrorCode.STORAGE_ALREADY_OPENED);
}
initialize(file, pagePoolSize);
scheduledCommitTime = Int64.MaxValue;
byte[] buf = new byte[Header.Sizeof];
int rc = file.Read(0, buf);
if (rc > 0 && rc < Header.Sizeof)
{
throw new StorageError(StorageError.ErrorCode.DATABASE_CORRUPTED);
}
header.unpack(buf);
if (header.curr < 0 || header.curr > 1)
{
throw new StorageError(StorageError.ErrorCode.DATABASE_CORRUPTED);
}
if (!header.initialized)
{
int indexSize = initIndexSize;
if (indexSize < dbFirstUserId)
{
indexSize = dbFirstUserId;
}
indexSize = (indexSize + dbHandlesPerPage - 1) & ~ (dbHandlesPerPage - 1);
header.curr = currIndex = 0;
long used = Page.pageSize;
header.root[0].index = used;
header.root[0].indexSize = indexSize;
header.root[0].indexUsed = dbFirstUserId;
header.root[0].freeList = 0;
used += indexSize * 8L;
header.root[1].index = used;
header.root[1].indexSize = indexSize;
header.root[1].indexUsed = dbFirstUserId;
header.root[1].freeList = 0;
used += indexSize * 8L;
header.root[0].shadowIndex = header.root[1].index;
header.root[1].shadowIndex = header.root[0].index;
header.root[0].shadowIndexSize = indexSize;
header.root[1].shadowIndexSize = indexSize;
int bitmapPages = (int) ((used + Page.pageSize * (dbAllocationQuantum * 8 - 1) - 1) / (Page.pageSize * (dbAllocationQuantum * 8 - 1)));
long bitmapSize = (long)bitmapPages * Page.pageSize;
int usedBitmapSize = (int) ((used + bitmapSize) >> (dbAllocationQuantumBits + 3));
for (i = 0; i < bitmapPages; i++)
{
pg = pool.putPage(used + (long)i*Page.pageSize);
byte[] bitmap = pg.data;
int n = usedBitmapSize > Page.pageSize ? Page.pageSize : usedBitmapSize;
for (int j = 0; j < n; j++)
{
bitmap[j] = (byte)0xFF;
}
pool.unfix(pg);
}
int bitmapIndexSize = ((dbBitmapId + dbBitmapPages) * 8 + Page.pageSize - 1) & ~ (Page.pageSize - 1);
byte[] index = new byte[bitmapIndexSize];
Bytes.pack8(index, dbInvalidId * 8, dbFreeHandleFlag);
for (i = 0; i < bitmapPages; i++)
{
Bytes.pack8(index, (dbBitmapId + i) * 8, used | dbPageObjectFlag);
used += Page.pageSize;
}
header.root[0].bitmapEnd = dbBitmapId + i;
header.root[1].bitmapEnd = dbBitmapId + i;
while (i < dbBitmapPages)
{
Bytes.pack8(index, (dbBitmapId + i) * 8, dbFreeHandleFlag);
i += 1;
}
header.root[0].size = used;
header.root[1].size = used;
usedSize = used;
committedIndexSize = currIndexSize = dbFirstUserId;
pool.write(header.root[1].index, index);
pool.write(header.root[0].index, index);
header.dirty = true;
header.root[0].size = header.root[1].size;
pg = pool.putPage(0);
header.pack(pg.data);
pool.flush();
pool.modify(pg);
header.initialized = true;
header.pack(pg.data);
pool.unfix(pg);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -