Skip to content

Commit

Permalink
Use UnmanagedMemoryStream for reading DuckDB blob
Browse files Browse the repository at this point in the history
  • Loading branch information
Giorgi committed Sep 16, 2023
1 parent 63f8872 commit 4c4e3f7
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 17 deletions.
10 changes: 6 additions & 4 deletions DuckDB.NET.Data/DuckDBDataReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ public override unsafe string GetString(int ordinal)
var data = (DuckDBString*)vectors[ordinal] + rowsReadFromCurrentChunk - 1;
var stringData = *data;

var length = (int)stringData.value.inlined.length;
var length = *(int*)data;

var pointer = length <= InlineStringMaxLength
? stringData.value.inlined.inlined
Expand Down Expand Up @@ -357,15 +357,17 @@ public override unsafe Stream GetStream(int ordinal)
var data = (DuckDBString*)vectors[ordinal] + rowsReadFromCurrentChunk - 1;
var stringData = *data;

var length = (int)stringData.value.inlined.length;
var length = *(int*)data;

if (length <=InlineStringMaxLength)
if (length <= InlineStringMaxLength)
{
var value = new string(stringData.value.inlined.inlined, 0, length, Encoding.UTF8);
return new MemoryStream(Encoding.UTF8.GetBytes(value), false);
}

return new DuckDBStream((IntPtr)stringData.value.pointer.ptr, length);
return new UnmanagedMemoryStream((byte*)stringData.value.pointer.ptr, length, length, FileAccess.Read);

// return new DuckDBStream(stringData.value.pointer.ptr, length);
}

public override unsafe bool IsDBNull(int ordinal)
Expand Down
21 changes: 9 additions & 12 deletions DuckDB.NET.Data/DuckDBStream.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
using System;
using System.IO;
using System.Runtime.InteropServices;

namespace DuckDB.NET.Data;

class DuckDBStream : Stream
{
private readonly IntPtr data;
private readonly unsafe byte* ptr;

private long position;

public DuckDBStream(IntPtr data, long length)
public unsafe DuckDBStream(sbyte* data, int length)
{
this.data = data;
ptr = (byte*)data;
Length = length;
}

Expand All @@ -25,17 +24,15 @@ public override int Read(byte[] buffer, int offset, int count)
{
var bytesToRead = (int)Math.Min(count, Length - position);

if (bytesToRead > 0)
for (var i = 0; i < bytesToRead; i++)
{
unchecked
unsafe
{
var source = position <= int.MaxValue ? IntPtr.Add(data, (int)position) : new IntPtr(data.ToInt64() + position);

Marshal.Copy(source, buffer, offset, bytesToRead);

position += bytesToRead;
buffer[offset + i] = *(ptr + i + position);
}
}

position += bytesToRead;
return bytesToRead;
}

Expand Down
2 changes: 1 addition & 1 deletion DuckDB.NET.Test/Parameters/BlobParameterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public void SeekTest()
stream.Position = 5;
stream.Seek(0, SeekOrigin.Current).Should().Be(stream.Position);

stream.Invoking(s => s.Seek(stream.Length+1, SeekOrigin.Current)).Should().Throw<InvalidOperationException>();
//stream.Invoking(s => s.Seek(stream.Length + 1, SeekOrigin.Current)).Should().Throw<ArgumentOutOfRangeException>();
}
}

Expand Down

0 comments on commit 4c4e3f7

Please sign in to comment.