hlsf wrong slicing solving
This commit is contained in:
@@ -80,100 +80,151 @@ namespace StgSharp.HighPerformance.Memory
|
||||
private void SliceMemory(Entry* e, int offset)
|
||||
{
|
||||
Entry* current = e;
|
||||
Entry* n = e->NextNear;
|
||||
Entry* next = e;
|
||||
|
||||
Entry* next = e->NextNear;
|
||||
ulong originOffset = e->Position - (ulong)m_Buffer;
|
||||
ulong finalOffset = originOffset + (ulong)offset;
|
||||
ulong end = e->Position + e->Size;
|
||||
ulong endOffset = end - (ulong)m_Buffer;
|
||||
int remainSize = (int)(e->Size - offset);
|
||||
ulong remainSize = (ulong)e->Size - (ulong)offset;
|
||||
|
||||
// get level of left edge
|
||||
int minLevel = int.Max((BitOperations.TrailingZeroCount(finalOffset) - 6) / 2, 0);
|
||||
int i = minLevel >= levelSizeArray.Length ? levelSizeArray.Length - 1 : minLevel;
|
||||
|
||||
for (; i < levelSizeArray.Length; i++)
|
||||
try
|
||||
{
|
||||
int levelSize = levelSizeArray[i];
|
||||
ulong levelLong = (ulong)levelSize;
|
||||
ulong levelUpper = levelLong * 4;
|
||||
ulong board = (finalOffset + levelUpper - 1) / levelUpper * levelUpper;
|
||||
int blockCount = (int)((board - ulong.Min(finalOffset, endOffset)) / levelLong);
|
||||
if (blockCount == 0)
|
||||
for (; i < levelSizeArray.Length; i++)
|
||||
{
|
||||
continue;
|
||||
int levelSize = levelSizeArray[i];
|
||||
ulong levelLong = (ulong)levelSize;
|
||||
ulong levelUpper = levelLong * 4;
|
||||
|
||||
// smallest board that is larger than finalOffset
|
||||
ulong board = (finalOffset + levelUpper - 1) / levelUpper * levelUpper;
|
||||
int blockCount = (int)((long)ulong.Min(board, endOffset) - (long)finalOffset) / (int)levelLong;
|
||||
if (blockCount == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int s = blockCount * levelSize;
|
||||
|
||||
// create and init new entry
|
||||
Entry* newEntry = (Entry*)_entries.Allocate();
|
||||
newEntry->State = EntryState.Empty;
|
||||
newEntry->Position = (nuint)m_Buffer + (nuint)finalOffset;
|
||||
newEntry->Size = (uint)s;
|
||||
BucketNode* bucket = (BucketNode*)newEntry->Position;
|
||||
bucket->EntryRef = newEntry;
|
||||
|
||||
// link new entry
|
||||
newEntry->PreviousNear = current;
|
||||
newEntry->NextNear = next;
|
||||
current->NextNear = newEntry;
|
||||
next->PreviousNear = newEntry;
|
||||
|
||||
newEntry->Level = i;
|
||||
PushLevel(i, Math.Min(blockCount - 1, 2), bucket);
|
||||
|
||||
// set new entry
|
||||
// Entry* old = current;
|
||||
current = newEntry;
|
||||
|
||||
finalOffset += (ulong)s;
|
||||
remainSize -= (ulong)s;
|
||||
if (remainSize <= (ulong)levelSize)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (remainSize <= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
int s = blockCount * levelSize;
|
||||
|
||||
// create and init new entry
|
||||
Entry* newEntry = (Entry*)_entries.Allocate();
|
||||
newEntry->Position = (nuint)((ulong)m_Buffer + finalOffset);
|
||||
newEntry->Size = (uint)s;
|
||||
BucketNode* bucket = (BucketNode*)newEntry->Position;
|
||||
bucket->EntryRef = newEntry;
|
||||
if (i >= 10)
|
||||
{
|
||||
int levelSize = levelSizeArray[^1] * 4;
|
||||
ulong levelLong = (ulong)levelSize;
|
||||
ulong board = endOffset / levelLong * levelLong;
|
||||
int blockCount = (int)((board - finalOffset) / (ulong)levelSize);
|
||||
if (blockCount > 0)
|
||||
{
|
||||
int s = blockCount * levelSize;
|
||||
Entry* newEntry = (Entry*)_entries.Allocate();
|
||||
newEntry->State = EntryState.Empty;
|
||||
newEntry->Position = (nuint)((ulong)m_Buffer + finalOffset);
|
||||
newEntry->Size = (uint)s;
|
||||
BucketNode* bucket = (BucketNode*)newEntry->Position;
|
||||
bucket->EntryRef = newEntry;
|
||||
|
||||
// link new entry
|
||||
newEntry->PreviousNear = current;
|
||||
newEntry->NextNear = n;
|
||||
current->NextNear = newEntry;
|
||||
next->PreviousNear = newEntry;
|
||||
|
||||
newEntry->Level = i;
|
||||
PushLevel(i, blockCount - 1, bucket);
|
||||
// link new entry
|
||||
newEntry->PreviousNear = current;
|
||||
newEntry->NextNear = next;
|
||||
current->NextNear = newEntry;
|
||||
if (next != null) {
|
||||
next->PreviousNear = newEntry;
|
||||
}
|
||||
|
||||
// set new entry
|
||||
Entry* old = current;
|
||||
current = newEntry;
|
||||
newEntry->Level = i;
|
||||
PushLevel(i, Math.Min(blockCount - 1, 2), bucket);
|
||||
|
||||
finalOffset += (ulong)s;
|
||||
remainSize -= s;
|
||||
if (remainSize <= 0) {
|
||||
return;
|
||||
// update lock and data
|
||||
finalOffset += (ulong)s;
|
||||
remainSize -= (ulong)s;
|
||||
}
|
||||
if (remainSize <= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (i -= 1; i >= 0; i--)
|
||||
{
|
||||
int levelSize = levelSizeArray[i];
|
||||
ulong levelLong = (ulong)levelSize;
|
||||
ulong board = endOffset / levelLong * levelLong;
|
||||
int blockCount = (int)(board - finalOffset) / levelSize;
|
||||
if (blockCount <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int s = blockCount * levelSize;
|
||||
System.Diagnostics.Debug.Assert(finalOffset + (ulong)s <= endOffset);
|
||||
|
||||
// create and init new entry
|
||||
Entry* newEntry = (Entry*)_entries.Allocate();
|
||||
newEntry->State = EntryState.Empty;
|
||||
newEntry->Position = (nuint)((ulong)m_Buffer + finalOffset);
|
||||
newEntry->Size = (uint)s;
|
||||
BucketNode* bucket = (BucketNode*)newEntry->Position;
|
||||
bucket->EntryRef = newEntry;
|
||||
|
||||
// link new entry
|
||||
newEntry->PreviousNear = current;
|
||||
newEntry->NextNear = next;
|
||||
current->NextNear = newEntry;
|
||||
if (next != null) {
|
||||
next->PreviousNear = newEntry;
|
||||
}
|
||||
|
||||
newEntry->Level = i;
|
||||
PushLevel(i, Math.Min(blockCount - 1, 2), bucket);
|
||||
|
||||
// set new entry
|
||||
// Entry* old = current;
|
||||
current = newEntry;
|
||||
|
||||
// update lock and data
|
||||
finalOffset += (ulong)s;
|
||||
remainSize -= (ulong)s;
|
||||
if (remainSize <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i -= 1; i >= 0; i--)
|
||||
finally
|
||||
{
|
||||
int levelSize = levelSizeArray[i];
|
||||
ulong levelLong = (ulong)levelSize;
|
||||
ulong board = endOffset / levelLong * levelLong;
|
||||
int blockCount = (int)((board - finalOffset) / (ulong)levelSize);
|
||||
if (blockCount == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int s = blockCount * levelSize;
|
||||
|
||||
// create and init new entry
|
||||
Entry* newEntry = (Entry*)_entries.Allocate();
|
||||
newEntry->Position = (nuint)((ulong)m_Buffer + finalOffset);
|
||||
newEntry->Size = (uint)s;
|
||||
BucketNode* bucket = (BucketNode*)newEntry->Position;
|
||||
bucket->EntryRef = newEntry;
|
||||
|
||||
// link new entry
|
||||
newEntry->PreviousNear = current;
|
||||
newEntry->NextNear = n;
|
||||
current->NextNear = newEntry;
|
||||
if (next != null) {
|
||||
next->PreviousNear = newEntry;
|
||||
}
|
||||
|
||||
newEntry->Level = i;
|
||||
PushLevel(i, blockCount - 1, bucket);
|
||||
|
||||
// set new entry
|
||||
Entry* old = current;
|
||||
current = newEntry;
|
||||
|
||||
// update lock and data
|
||||
finalOffset += (ulong)s;
|
||||
remainSize -= s;
|
||||
if (remainSize <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
e->Size = (uint)(offset);
|
||||
e->Level = GetLevelFromSize((uint)offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user