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
|
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
|
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<Reader>> m_readers;
|
||||||
std::map<std::string, std::shared_ptr<zim::Archive>> m_archives;
|
std::map<std::string, std::shared_ptr<zim::Archive>> m_archives;
|
||||||
std::vector<kiwix::Bookmark> m_bookmarks;
|
std::vector<kiwix::Bookmark> m_bookmarks;
|
||||||
|
@ -172,6 +184,7 @@ class Library : private LibraryBase
|
||||||
mutable std::mutex m_mutex;
|
mutable std::mutex m_mutex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
typedef LibraryRevision Revision;
|
||||||
typedef std::vector<std::string> BookIdCollection;
|
typedef std::vector<std::string> BookIdCollection;
|
||||||
typedef std::map<std::string, int> AttributeCounts;
|
typedef std::map<std::string, int> AttributeCounts;
|
||||||
|
|
||||||
|
@ -368,6 +381,24 @@ class Library : private LibraryBase
|
||||||
const std::vector<std::string>& tags = {},
|
const std::vector<std::string>& tags = {},
|
||||||
size_t maxSize = 0) const;
|
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 OPDSDumper;
|
||||||
friend class libXMLDumper;
|
friend class libXMLDumper;
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,7 @@ Library::~Library()
|
||||||
bool Library::addBook(const Book& book)
|
bool Library::addBook(const Book& book)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(m_mutex);
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
++m_revision;
|
||||||
/* Try to find it */
|
/* Try to find it */
|
||||||
updateBookDB(book);
|
updateBookDB(book);
|
||||||
try {
|
try {
|
||||||
|
@ -111,9 +112,12 @@ bool Library::addBook(const Book& book)
|
||||||
oldbook.update(book); // XXX: This may have no effect if oldbook is readonly
|
oldbook.update(book); // XXX: This may have no effect if oldbook is readonly
|
||||||
// XXX: Then m_bookDB will become out-of-sync with
|
// XXX: Then m_bookDB will become out-of-sync with
|
||||||
// XXX: the real contents of the library.
|
// XXX: the real contents of the library.
|
||||||
|
oldbook.lastUpdatedRevision = m_revision;
|
||||||
return false;
|
return false;
|
||||||
} catch (std::out_of_range&) {
|
} 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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,6 +155,32 @@ bool Library::removeBookById(const std::string& id)
|
||||||
return m_books.erase(id) == 1;
|
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
|
const Book& Library::getBookById(const std::string& id) const
|
||||||
{
|
{
|
||||||
// XXX: Doesn't make sense to lock this operation since it cannot
|
// 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);
|
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