hlsf wrong slicing solving

This commit is contained in:
Youmu Liu
2025-11-25 20:39:18 +08:00
parent 7ef57d8f33
commit 5b09160049
16 changed files with 256 additions and 149 deletions
@@ -80,61 +80,26 @@ namespace StgSharp.HighPerformance.Memory
private void SliceMemory(Entry* e, int offset)
{
Entry* current = e;
ulong n = e->NextNear;
Entry* n = e->NextNear;
Entry* next = e;
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);
// 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++)
{
int levelSize = levelSizeArray[i];
ulong board = (finalOffset + (ulong)levelSize - 1) & ~((ulong)levelSize - 1);
int blockCount = (int)((ulong.Min(board, end) - board) / (ulong)levelSize);
if (blockCount == 0)
{
break;
}
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 = (ulong)current;
newEntry->NextNear = n;
current->NextNear = (ulong)newEntry;
next->PreviousNear = (ulong)newEntry;
newEntry->Level = i;
PushLevel(i, blockCount - 1, bucket);
// set new entry
Entry* old = current;
current = newEntry;
finalOffset += (ulong)s;
remainSize -= s;
}
if (remainSize <= 0) {
return;
}
for (i -= 1; i >= 0; i--)
{
int levelSize = levelSizeArray[i];
ulong board = (finalOffset + (ulong)levelSize - 1) & ~((ulong)levelSize - 1);
int blockCount = (int)((ulong.Min(board, end) - finalOffset) / (ulong)levelSize);
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)
{
continue;
@@ -149,11 +114,50 @@ namespace StgSharp.HighPerformance.Memory
bucket->EntryRef = newEntry;
// link new entry
newEntry->PreviousNear = (ulong)current;
newEntry->PreviousNear = current;
newEntry->NextNear = n;
current->NextNear = (ulong)newEntry;
current->NextNear = newEntry;
next->PreviousNear = newEntry;
newEntry->Level = i;
PushLevel(i, blockCount - 1, bucket);
// set new entry
Entry* old = current;
current = newEntry;
finalOffset += (ulong)s;
remainSize -= 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) / (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 = (ulong)newEntry;
next->PreviousNear = newEntry;
}
newEntry->Level = i;
@@ -166,6 +170,10 @@ namespace StgSharp.HighPerformance.Memory
// update lock and data
finalOffset += (ulong)s;
remainSize -= s;
if (remainSize <= 0)
{
break;
}
}
}
@@ -184,10 +192,8 @@ namespace StgSharp.HighPerformance.Memory
nuint blockSize = (nuint)levelSizeArray[^1] * 2; // Use last level size (16MB)
nuint newPos = pos + blockSize;
ulong p;
Entry* previous;
p = _spareMemory->PreviousNear;
previous = (Entry*)p;
previous = _spareMemory->PreviousNear;
if (_spareMemory->Size <= 0)
{
handle = null;
@@ -199,7 +205,7 @@ namespace StgSharp.HighPerformance.Memory
{
newPos = (nuint)m_Buffer + _size; // Clamp to maximum buffer size
blockSize = _spareMemory->Size;
p = 0;
previous = null;
}
// Try to allocate new Entry from slab allocator
@@ -216,11 +222,11 @@ namespace StgSharp.HighPerformance.Memory
// PushLevel(handle->Level, DetermineSegmentIndex((uint)blockSize, handle->Level), b);
// update position linked list
handle->NextNear = (ulong)_spareMemory;
handle->PreviousNear = p;
_spareMemory->PreviousNear = (ulong)handle; // Replace Volatile.Write with direct access
handle->NextNear = _spareMemory;
handle->PreviousNear = previous;
_spareMemory->PreviousNear = handle; // Replace Volatile.Write with direct access
if (previous != null) {
previous->NextNear = (ulong)handle;
previous->NextNear = handle;
}
return true;