mirror of https://github.com/kiwix/libkiwix.git
Enter Library::removeBooksNotUpdatedSince()
This commit is contained in:
parent
1d5383435d
commit
262e13845c
|
@ -147,8 +147,20 @@ private: // functions
|
|||
*/
|
||||
class LibraryBase
|
||||
{
|
||||
protected: // types
|
||||
typedef uint64_t LibraryRevision;
|
||||
|
||||
struct Entry : Book
|
||||
{
|
||||
LibraryRevision lastUpdatedRevision = 0;
|
||||
|
||||
// May also keep the Archive and Reader pointers here and get
|
||||
// rid of the m_readers and m_archives data members in Library
|
||||
};
|
||||
|
||||
protected: // data
|
||||
std::map<std::string, kiwix::Book> m_books;
|
||||
LibraryRevision m_revision;
|
||||
std::map<std::string, Entry> m_books;
|
||||
std::map<std::string, std::shared_ptr<Reader>> m_readers;
|
||||
std::map<std::string, std::shared_ptr<zim::Archive>> m_archives;
|
||||
std::vector<kiwix::Bookmark> m_bookmarks;
|
||||
|
@ -172,6 +184,7 @@ class Library : private LibraryBase
|
|||
mutable std::mutex m_mutex;
|
||||
|
||||
public:
|
||||
typedef LibraryRevision Revision;
|
||||
typedef std::vector<std::string> BookIdCollection;
|
||||
typedef std::map<std::string, int> AttributeCounts;
|
||||
|
||||
|
@ -368,6 +381,24 @@ class Library : private LibraryBase
|
|||
const std::vector<std::string>& tags = {},
|
||||
size_t maxSize = 0) const;
|
||||
|
||||
/**
|
||||
* Return the current revision of the library.
|
||||
*
|
||||
* The revision of the library is updated (incremented by one) only by
|
||||
* the addBook() operation.
|
||||
*
|
||||
* @return Current revision of the library.
|
||||
*/
|
||||
LibraryRevision getRevision() const;
|
||||
|
||||
/**
|
||||
* Remove books that have not been updated since the specified revision.
|
||||
*
|
||||
* @param rev the library revision to use
|
||||
* @return Count of books that were removed by this operation.
|
||||
*/
|
||||
uint32_t removeBooksNotUpdatedSince(LibraryRevision rev);
|
||||
|
||||
friend class OPDSDumper;
|
||||
friend class libXMLDumper;
|
||||
|
||||
|
|
|
@ -101,6 +101,7 @@ Library::~Library()
|
|||
bool Library::addBook(const Book& book)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
++m_revision;
|
||||
/* Try to find it */
|
||||
updateBookDB(book);
|
||||
try {
|
||||
|
@ -111,9 +112,12 @@ bool Library::addBook(const Book& book)
|
|||
oldbook.update(book); // XXX: This may have no effect if oldbook is readonly
|
||||
// XXX: Then m_bookDB will become out-of-sync with
|
||||
// XXX: the real contents of the library.
|
||||
oldbook.lastUpdatedRevision = m_revision;
|
||||
return false;
|
||||
} catch (std::out_of_range&) {
|
||||
m_books[book.getId()] = book;
|
||||
Entry& newEntry = m_books[book.getId()];
|
||||
static_cast<Book&>(newEntry) = book;
|
||||
newEntry.lastUpdatedRevision = m_revision;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -151,6 +155,32 @@ bool Library::removeBookById(const std::string& id)
|
|||
return m_books.erase(id) == 1;
|
||||
}
|
||||
|
||||
Library::Revision Library::getRevision() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
return m_revision;
|
||||
}
|
||||
|
||||
uint32_t Library::removeBooksNotUpdatedSince(LibraryRevision libraryRevision)
|
||||
{
|
||||
BookIdCollection booksToRemove;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
for ( const auto& entry : m_books) {
|
||||
if ( entry.second.lastUpdatedRevision <= libraryRevision ) {
|
||||
booksToRemove.push_back(entry.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t countOfRemovedBooks = 0;
|
||||
for ( const auto& id : booksToRemove ) {
|
||||
if ( removeBookById(id) )
|
||||
++countOfRemovedBooks;
|
||||
}
|
||||
return countOfRemovedBooks;
|
||||
}
|
||||
|
||||
const Book& Library::getBookById(const std::string& id) const
|
||||
{
|
||||
// XXX: Doesn't make sense to lock this operation since it cannot
|
||||
|
|
|
@ -707,4 +707,35 @@ TEST_F(LibraryTest, removeBookByIdUpdatesTheSearchDB)
|
|||
EXPECT_THROW(lib.getBookById("raycharles"), std::out_of_range);
|
||||
};
|
||||
|
||||
TEST_F(LibraryTest, removeBooksNotUpdatedSince)
|
||||
{
|
||||
EXPECT_FILTER_RESULTS(kiwix::Filter(),
|
||||
"An example ZIM archive",
|
||||
"Encyclopédie de la Tunisie",
|
||||
"Granblue Fantasy Wiki",
|
||||
"Géographie par Wikipédia",
|
||||
"Islam Stack Exchange",
|
||||
"Mathématiques",
|
||||
"Movies & TV Stack Exchange",
|
||||
"Mythology & Folklore Stack Exchange",
|
||||
"Ray Charles",
|
||||
"TED talks - Business",
|
||||
"Tania Louis",
|
||||
"Wikiquote"
|
||||
);
|
||||
|
||||
const uint64_t rev = lib.getRevision();
|
||||
for ( const auto& id : lib.filter(kiwix::Filter().query("exchange")) ) {
|
||||
lib.addBook(lib.getBookByIdThreadSafe(id));
|
||||
}
|
||||
|
||||
EXPECT_EQ(9u, lib.removeBooksNotUpdatedSince(rev));
|
||||
|
||||
EXPECT_FILTER_RESULTS(kiwix::Filter(),
|
||||
"Islam Stack Exchange",
|
||||
"Movies & TV Stack Exchange",
|
||||
"Mythology & Folklore Stack Exchange",
|
||||
);
|
||||
};
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue