mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-24 12:44:07 +00:00
Merge pull request #100 from xiaoyifang/feature/concurrent-fseek
feat:mdx lock free when loadArticle
This commit is contained in:
commit
5fa479b127
|
@ -4,6 +4,7 @@
|
||||||
#include "chunkedstorage.hh"
|
#include "chunkedstorage.hh"
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <QDataStream>
|
||||||
|
|
||||||
namespace ChunkedStorage {
|
namespace ChunkedStorage {
|
||||||
|
|
||||||
|
@ -134,25 +135,34 @@ char * Reader::getBlock( uint32_t address, vector< char > & chunk )
|
||||||
|
|
||||||
// Read and decompress the chunk
|
// Read and decompress the chunk
|
||||||
{
|
{
|
||||||
file.seek( offsets[ chunkIdx ] );
|
// file.seek( offsets[ chunkIdx ] );
|
||||||
|
|
||||||
uint32_t uncompressedSize = file.read< uint32_t >();
|
auto bytes = file.map( offsets[ chunkIdx ], 8 );
|
||||||
uint32_t compressedSize = file.read< uint32_t >();
|
auto qBytes = QByteArray::fromRawData( reinterpret_cast< char * >(bytes), 8 );
|
||||||
|
QDataStream in( qBytes );
|
||||||
|
in.setByteOrder( QDataStream::LittleEndian );
|
||||||
|
|
||||||
|
uint32_t uncompressedSize;
|
||||||
|
uint32_t compressedSize;
|
||||||
|
// = file.read< uint32_t >();
|
||||||
|
|
||||||
|
in >> uncompressedSize >> compressedSize;
|
||||||
|
|
||||||
|
file.unmap( bytes );
|
||||||
chunk.resize( uncompressedSize );
|
chunk.resize( uncompressedSize );
|
||||||
|
|
||||||
vector< unsigned char > compressedData( compressedSize );
|
// vector< unsigned char > compressedData( compressedSize );
|
||||||
|
auto chunkDataBytes = file.map( offsets[ chunkIdx ] + 8, compressedSize );
|
||||||
|
|
||||||
file.read( &compressedData.front(), compressedData.size() );
|
// file.read( &compressedData.front(), compressedData.size() );
|
||||||
|
|
||||||
unsigned long decompressedLength = chunk.size();
|
unsigned long decompressedLength = chunk.size();
|
||||||
|
|
||||||
if ( uncompress( (unsigned char *)&chunk.front(),
|
if( uncompress( (unsigned char *)&chunk.front(), &decompressedLength, chunkDataBytes, compressedSize ) != Z_OK
|
||||||
&decompressedLength,
|
|| decompressedLength != chunk.size() )
|
||||||
&compressedData.front(),
|
|
||||||
compressedData.size() ) != Z_OK ||
|
|
||||||
decompressedLength != chunk.size() )
|
|
||||||
throw exFailedToDecompressChunk();
|
throw exFailedToDecompressChunk();
|
||||||
|
|
||||||
|
file.unmap( chunkDataBytes );
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t offsetInChunk = address & 0xffFF;
|
size_t offsetInChunk = address & 0xffFF;
|
||||||
|
|
14
file.cc
14
file.cc
|
@ -256,6 +256,20 @@ void Class::seek( qint64 offset )
|
||||||
throw exSeekError();
|
throw exSeekError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uchar * Class::map( qint64 offset, qint64 size )
|
||||||
|
{
|
||||||
|
if( writeBuffer )
|
||||||
|
flushWriteBuffer();
|
||||||
|
|
||||||
|
return f.map( offset, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Class::unmap( uchar * address )
|
||||||
|
{
|
||||||
|
return f.unmap( address );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Class::seekCur( qint64 offset )
|
void Class::seekCur( qint64 offset )
|
||||||
{
|
{
|
||||||
if ( writeBuffer )
|
if ( writeBuffer )
|
||||||
|
|
2
file.hh
2
file.hh
|
@ -95,6 +95,7 @@ public:
|
||||||
|
|
||||||
/// Seeks in the file, relative to its beginning.
|
/// Seeks in the file, relative to its beginning.
|
||||||
void seek( qint64 offset ) ;
|
void seek( qint64 offset ) ;
|
||||||
|
uchar * map( qint64 offset, qint64 size );
|
||||||
/// Seeks in the file, relative to the current position.
|
/// Seeks in the file, relative to the current position.
|
||||||
void seekCur( qint64 offset ) ;
|
void seekCur( qint64 offset ) ;
|
||||||
/// Seeks in the file, relative to the end of file.
|
/// Seeks in the file, relative to the end of file.
|
||||||
|
@ -117,6 +118,7 @@ public:
|
||||||
void close() ;
|
void close() ;
|
||||||
|
|
||||||
~Class() noexcept;
|
~Class() noexcept;
|
||||||
|
bool unmap( uchar * address );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -679,7 +679,7 @@ void FTSResultsRequest::indexSearch( BtreeIndexing::BtreeIndex & ftsIndex,
|
||||||
vector< char > chunk;
|
vector< char > chunk;
|
||||||
char * linksPtr;
|
char * linksPtr;
|
||||||
{
|
{
|
||||||
Mutex::Lock _( dict.getFtsMutex() );
|
// Mutex::Lock _( dict.getFtsMutex() );
|
||||||
linksPtr = chunks->getBlock( links[ x ].articleOffset, chunk );
|
linksPtr = chunks->getBlock( links[ x ].articleOffset, chunk );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -785,7 +785,7 @@ void FTSResultsRequest::combinedIndexSearch( BtreeIndexing::BtreeIndex & ftsInde
|
||||||
vector< char > chunk;
|
vector< char > chunk;
|
||||||
char * linksPtr;
|
char * linksPtr;
|
||||||
{
|
{
|
||||||
Mutex::Lock _( dict.getFtsMutex() );
|
// Mutex::Lock _( dict.getFtsMutex() );
|
||||||
linksPtr = chunks->getBlock( links[ x ].articleOffset, chunk );
|
linksPtr = chunks->getBlock( links[ x ].articleOffset, chunk );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -844,7 +844,7 @@ void FTSResultsRequest::combinedIndexSearch( BtreeIndexing::BtreeIndex & ftsInde
|
||||||
vector< char > chunk;
|
vector< char > chunk;
|
||||||
char * linksPtr;
|
char * linksPtr;
|
||||||
{
|
{
|
||||||
Mutex::Lock _( dict.getFtsMutex() );
|
// Mutex::Lock _( dict.getFtsMutex() );
|
||||||
linksPtr = chunks->getBlock( links[ x ].articleOffset, chunk );
|
linksPtr = chunks->getBlock( links[ x ].articleOffset, chunk );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -935,7 +935,7 @@ void FTSResultsRequest::fullIndexSearch( BtreeIndexing::BtreeIndex & ftsIndex,
|
||||||
vector< char > chunk;
|
vector< char > chunk;
|
||||||
char * linksPtr;
|
char * linksPtr;
|
||||||
{
|
{
|
||||||
Mutex::Lock _( dict.getFtsMutex() );
|
// Mutex::Lock _( dict.getFtsMutex() );
|
||||||
linksPtr = chunks->getBlock( links[ x ].articleOffset, chunk );
|
linksPtr = chunks->getBlock( links[ x ].articleOffset, chunk );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
6
mdx.cc
6
mdx.cc
|
@ -163,7 +163,7 @@ public:
|
||||||
|
|
||||||
MdictParser::RecordInfo indexEntry;
|
MdictParser::RecordInfo indexEntry;
|
||||||
vector< char > chunk;
|
vector< char > chunk;
|
||||||
Mutex::Lock _( idxMutex );
|
// Mutex::Lock _( idxMutex );
|
||||||
const char * indexEntryPtr = chunks.getBlock( links[ 0 ].articleOffset, chunk );
|
const char * indexEntryPtr = chunks.getBlock( links[ 0 ].articleOffset, chunk );
|
||||||
memcpy( &indexEntry, indexEntryPtr, sizeof( indexEntry ) );
|
memcpy( &indexEntry, indexEntryPtr, sizeof( indexEntry ) );
|
||||||
|
|
||||||
|
@ -867,7 +867,7 @@ const QString & MdxDictionary::getDescription()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Mutex::Lock _( idxMutex );
|
// Mutex::Lock _( idxMutex );
|
||||||
vector< char > chunk;
|
vector< char > chunk;
|
||||||
char * dictDescription = chunks.getBlock( idxHeader.descriptionAddress, chunk );
|
char * dictDescription = chunks.getBlock( idxHeader.descriptionAddress, chunk );
|
||||||
string str( dictDescription );
|
string str( dictDescription );
|
||||||
|
@ -900,7 +900,7 @@ void MdxDictionary::loadIcon() noexcept
|
||||||
void MdxDictionary::loadArticle( uint32_t offset, string & articleText, bool noFilter )
|
void MdxDictionary::loadArticle( uint32_t offset, string & articleText, bool noFilter )
|
||||||
{
|
{
|
||||||
vector< char > chunk;
|
vector< char > chunk;
|
||||||
Mutex::Lock _( idxMutex );
|
// Mutex::Lock _( idxMutex );
|
||||||
|
|
||||||
// Load record info from index
|
// Load record info from index
|
||||||
MdictParser::RecordInfo recordInfo;
|
MdictParser::RecordInfo recordInfo;
|
||||||
|
|
Loading…
Reference in a new issue