@@ -248,30 +248,41 @@ class Grouping
248
248
const_cast <entry_index_t &>(m_endUserEntry) = getCountArticles ();
249
249
}
250
250
251
- auto result = tmpDirentLookup.find (' X' , " listing/titleOrdered/v1" );
252
- if (result.first ) {
253
- mp_titleDirentAccessor = getTitleAccessorV1 (result.second );
254
- }
251
+ // Following code will may create cluster and we want to remove them from cache
252
+ // if something goes wrong.
253
+ try {
254
+ auto result = tmpDirentLookup.find (' X' , " listing/titleOrdered/v1" );
255
+ if (result.first ) {
256
+ mp_titleDirentAccessor = getTitleAccessorV1 (result.second );
257
+ }
255
258
256
- if (!mp_titleDirentAccessor) {
257
- if (!header.hasTitleListingV0 ()) {
258
- throw ZimFileFormatError (" Zim file doesn't contain a title ordered index" );
259
+ if (!mp_titleDirentAccessor) {
260
+ if (!header.hasTitleListingV0 ()) {
261
+ throw ZimFileFormatError (" Zim file doesn't contain a title ordered index" );
262
+ }
263
+ offset_t titleOffset (header.getTitleIdxPos ());
264
+ zsize_t titleSize (sizeof (entry_index_type)*header.getArticleCount ());
265
+ mp_titleDirentAccessor = getTitleAccessor (titleOffset, titleSize, " Title index table" );
266
+ const_cast <bool &>(m_hasFrontArticlesIndex) = false ;
259
267
}
260
- offset_t titleOffset (header.getTitleIdxPos ());
261
- zsize_t titleSize (sizeof (entry_index_type)*header.getArticleCount ());
262
- mp_titleDirentAccessor = getTitleAccessor (titleOffset, titleSize, " Title index table" );
263
- const_cast <bool &>(m_hasFrontArticlesIndex) = false ;
264
- }
265
- m_byTitleDirentLookup.reset (new ByTitleDirentLookup (mp_titleDirentAccessor.get ()));
268
+ m_byTitleDirentLookup.reset (new ByTitleDirentLookup (mp_titleDirentAccessor.get ()));
266
269
267
- readMimeTypes ();
270
+ readMimeTypes ();
271
+ } catch (...) {
272
+ dropCachedClusters ();
273
+ throw ;
274
+ }
268
275
}
269
276
270
277
FileImpl::~FileImpl () {
271
- // We have to clean the global cache for our clusters.
278
+ dropCachedClusters ();
279
+ }
280
+
281
+ void FileImpl::dropCachedClusters () const {
272
282
getClusterCache ().dropAll ([=](const std::tuple<FileImpl*, cluster_index_type>& key) {return std::get<0 >(key) == this ;});
273
283
}
274
284
285
+
275
286
std::unique_ptr<IndirectDirentAccessor> FileImpl::getTitleAccessorV1 (const entry_index_t idx)
276
287
{
277
288
auto dirent = mp_pathDirentAccessor->getDirent (idx);
0 commit comments