Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Microsoft.Data.Sqlite: Make GetBytes, GetChars, and GetTextReader more efficient #13987

Closed
bricelam opened this issue Nov 20, 2018 · 12 comments · Fixed by #18438 or #20092
Closed

Microsoft.Data.Sqlite: Make GetBytes, GetChars, and GetTextReader more efficient #13987

bricelam opened this issue Nov 20, 2018 · 12 comments · Fixed by #18438 or #20092
Assignees
Labels
area-adonet-sqlite closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. good first issue This issue should be relatively straightforward to fix. type-enhancement
Milestone

Comments

@bricelam
Copy link
Contributor

bricelam commented Nov 20, 2018

SqliteDataReader.GetBytes(), GetChars(), and GetTextReader() should leverage SqliteBlob. We should also update GetStream() to cache the rowid ordinal and value as part of this change. (Don't forget to invalidate them in Read and NextResult.)

@bricelam bricelam added type-enhancement help wanted This issue involves technologies where we are not experts. Expert help would be appreciated. area-adonet-sqlite labels Nov 20, 2018
@bricelam
Copy link
Contributor Author

bricelam commented Nov 20, 2018

Also look into using sqlite3_blob_reopen if it gets added to SQLitePCL.raw ericsink/SQLitePCL.raw#240

@bricelam bricelam changed the title Microsoft.Data.Sqlite: Make GetBytes and GetChars more efficient Microsoft.Data.Sqlite: Make GetBytes, GetChars, and GetTextReader more efficient Nov 27, 2018
@bricelam
Copy link
Contributor Author

Note, SQLitePCL.raw assumes strings are always encoded using UTF-8. We can too.

@ajcvickers ajcvickers added this to the Backlog milestone Nov 28, 2018
@divega divega added good first issue This issue should be relatively straightforward to fix. help wanted This issue involves technologies where we are not experts. Expert help would be appreciated. and removed help wanted This issue involves technologies where we are not experts. Expert help would be appreciated. good first issue This issue should be relatively straightforward to fix. labels May 31, 2019
@bricelam bricelam added the good first issue This issue should be relatively straightforward to fix. label May 31, 2019
@MhdTlb
Copy link

MhdTlb commented Jun 17, 2019

I would like to work on this task. any guide PLZ

@bricelam
Copy link
Contributor Author

Work is described above:

  • Update SqliteDataReader.GetBytes() to use GetStream()
  • Update GetChars() to use GetStream(); Text is encoded as UTF-8
  • Update GetTextReader() to use GetStream(). Again, UTF-8
  • Update GetStream() to cache rowidOrdinal

@ajcvickers ajcvickers removed the help wanted This issue involves technologies where we are not experts. Expert help would be appreciated. label Aug 5, 2019
@nmichels
Copy link
Contributor

Hi @bricelam
I'm trying to implement the changes above, but I'm not sure if I'm doing that in the most efficient way, it looks like I'm doing a lot of copies/casts that may not be necessary. Here it goes what I have so far:

convert_get_stream

convert_get_stream2

@bricelam
Copy link
Contributor Author

The MemoryStreams look unnecessary. Also, use StreamReader instead of Encoding.GetString(). Feel free to send a PR. We can iterate on the implementation there.

@nmichels
Copy link
Contributor

nmichels commented Oct 18, 2019

Hi @bricelam
As you have suggested, I've sent a PR, also removed the memory streams and fixed some regressions that I've caught with the previous changes. The last two steps are missing: Update GetTextReader() - I didn't find this method - to use GetStream(). Again, UTF-8; And Update GetStream() to cache rowidOrdinal.

@nmichels
Copy link
Contributor

Hi @bricelam
It looks like caching is already implemented at GetStream

if (rowidOrdinal < 0)
{
    return new MemoryStream(GetCachedBlob(ordinal), false);
}

Unless we should apply something similar at this line:
return new SqliteBlob(_connection, blobTableName, blobColumnName, rowid, readOnly: true);

Also _blob_cache is being cleared at Read method:
Array.Clear(_blobCache, 0, _blobCache.Length);

And the whole reader is disposed at SqliteDataReader.cs:NextResult

if (_record != null)
{
    _record.Dispose();
    _record = null;
}

Is the method sqlite3_blob_reopen related to the caching strategy? It is already implemented at SQLitePCL.raw

@ajcvickers ajcvickers modified the milestones: Backlog, 5.0.0 Nov 20, 2019
@bricelam bricelam added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Feb 20, 2020
@smitpatel smitpatel reopened this Feb 27, 2020
@smitpatel smitpatel removed the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Feb 27, 2020
@smitpatel
Copy link
Member

I reverted the fix for this since it is causing intermittent seg fault on Linux in Microsoft.Data.Sqlite.Tests.

@bricelam
Copy link
Contributor Author

I’ll dig into these. May have exposed an existing issue with SqliteBlob.

@bricelam
Copy link
Contributor Author

AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at SQLitePCL.SQLite3Provider_dynamic_cdecl.SQLitePCL.ISQLite3Provider.sqlite3_blob_close(IntPtr)
   at SQLitePCL.raw.internal_sqlite3_blob_close(IntPtr)
   at SQLitePCL.sqlite3_blob.ReleaseHandle()
   at System.Runtime.InteropServices.SafeHandle.InternalRelease(Boolean)
   at System.Runtime.InteropServices.SafeHandle.Dispose(Boolean)
   at System.Runtime.InteropServices.SafeHandle.Finalize()

@bricelam
Copy link
Contributor Author

bricelam commented Feb 27, 2020

We're probably leaking sqlite_blob objects and the SQLite GC ends up freeing them before the .NET GC. 💥

@bricelam bricelam added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Feb 28, 2020
@ajcvickers ajcvickers modified the milestones: 5.0.0, 5.0.0-preview2 Mar 13, 2020
@ajcvickers ajcvickers modified the milestones: 5.0.0-preview2, 5.0.0 Nov 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-adonet-sqlite closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. good first issue This issue should be relatively straightforward to fix. type-enhancement
Projects
None yet
6 participants