mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Do a binary search in ConcatenationStorage when finding a source
This commit is contained in:
parent
53851ab897
commit
1c918f705b
1 changed files with 39 additions and 14 deletions
|
@ -29,18 +29,21 @@ namespace LibHac.IO
|
||||||
long inPos = offset;
|
long inPos = offset;
|
||||||
int outPos = 0;
|
int outPos = 0;
|
||||||
int remaining = destination.Length;
|
int remaining = destination.Length;
|
||||||
|
int sourceIndex = FindSource(inPos);
|
||||||
|
|
||||||
while (remaining > 0)
|
while (remaining > 0)
|
||||||
{
|
{
|
||||||
ConcatSource entry = FindSource(inPos);
|
ConcatSource entry = Sources[sourceIndex];
|
||||||
long sourcePos = inPos - entry.StartOffset;
|
long entryPos = inPos - entry.StartOffset;
|
||||||
|
long entryRemain = entry.StartOffset + entry.Size - inPos;
|
||||||
|
|
||||||
int bytesToRead = (int)Math.Min(entry.EndOffset - inPos, remaining);
|
int bytesToRead = (int)Math.Min(entryRemain, remaining);
|
||||||
entry.Storage.Read(destination.Slice(outPos, bytesToRead), sourcePos);
|
entry.Storage.Read(destination.Slice(outPos, bytesToRead), entryPos);
|
||||||
|
|
||||||
outPos += bytesToRead;
|
outPos += bytesToRead;
|
||||||
inPos += bytesToRead;
|
inPos += bytesToRead;
|
||||||
remaining -= bytesToRead;
|
remaining -= bytesToRead;
|
||||||
|
sourceIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,18 +52,21 @@ namespace LibHac.IO
|
||||||
long inPos = offset;
|
long inPos = offset;
|
||||||
int outPos = 0;
|
int outPos = 0;
|
||||||
int remaining = source.Length;
|
int remaining = source.Length;
|
||||||
|
int sourceIndex = FindSource(inPos);
|
||||||
|
|
||||||
while (remaining > 0)
|
while (remaining > 0)
|
||||||
{
|
{
|
||||||
ConcatSource storage = FindSource(inPos);
|
ConcatSource entry = Sources[sourceIndex];
|
||||||
long sourcePos = inPos - storage.StartOffset;
|
long entryPos = inPos - entry.StartOffset;
|
||||||
|
long entryRemain = entry.StartOffset + entry.Size - inPos;
|
||||||
|
|
||||||
int bytesToWrite = (int)Math.Min(storage.EndOffset - inPos, remaining);
|
int bytesToWrite = (int)Math.Min(entryRemain, remaining);
|
||||||
storage.Storage.Write(source.Slice(outPos, bytesToWrite), sourcePos);
|
entry.Storage.Write(source.Slice(outPos, bytesToWrite), entryPos);
|
||||||
|
|
||||||
outPos += bytesToWrite;
|
outPos += bytesToWrite;
|
||||||
inPos += bytesToWrite;
|
inPos += bytesToWrite;
|
||||||
remaining -= bytesToWrite;
|
remaining -= bytesToWrite;
|
||||||
|
sourceIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,27 +78,46 @@ namespace LibHac.IO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConcatSource FindSource(long offset)
|
private int FindSource(long offset)
|
||||||
{
|
{
|
||||||
foreach (ConcatSource info in Sources)
|
if (offset < 0 || offset >= Length)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(offset), offset, "The Storage does not contain this offset.");
|
||||||
|
|
||||||
|
int lo = 0;
|
||||||
|
int hi = Sources.Length - 1;
|
||||||
|
|
||||||
|
while (lo <= hi)
|
||||||
{
|
{
|
||||||
if (info.EndOffset > offset) return info;
|
int mid = lo + ((hi - lo) >> 1);
|
||||||
|
|
||||||
|
long val = Sources[mid].StartOffset;
|
||||||
|
|
||||||
|
if (val == offset) return mid;
|
||||||
|
|
||||||
|
if (val < offset)
|
||||||
|
{
|
||||||
|
lo = mid + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hi = mid - 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(offset), offset, "The Storage does not contain this offset.");
|
return lo - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ConcatSource
|
private class ConcatSource
|
||||||
{
|
{
|
||||||
public IStorage Storage { get; }
|
public IStorage Storage { get; }
|
||||||
public long StartOffset { get; }
|
public long StartOffset { get; }
|
||||||
public long EndOffset { get; }
|
public long Size { get; }
|
||||||
|
|
||||||
public ConcatSource(IStorage storage, long startOffset, long length)
|
public ConcatSource(IStorage storage, long startOffset, long length)
|
||||||
{
|
{
|
||||||
Storage = storage;
|
Storage = storage;
|
||||||
StartOffset = startOffset;
|
StartOffset = startOffset;
|
||||||
EndOffset = startOffset + length;
|
Size = length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue