forked from organicmaps/organicmaps
Merge pull request #466 from ygorshenin/fix-indexes-removal
[platform, storage] Implemented cleanup of absent countries indexes.
This commit is contained in:
commit
80befbcb60
16 changed files with 254 additions and 138 deletions
|
@ -16,7 +16,8 @@ UNIT_TEST(CheckMWM_LoadAll)
|
|||
{
|
||||
Platform & platform = GetPlatform();
|
||||
vector<platform::LocalCountryFile> localFiles;
|
||||
platform::FindAllLocalMapsInDirectory(platform.WritableDir(), 0 /* version */, localFiles);
|
||||
platform::FindAllLocalMapsInDirectoryAndCleanup(platform.WritableDir(), 0 /* version */,
|
||||
-1 /* latestVersion */, localFiles);
|
||||
|
||||
model::FeaturesFetcher m;
|
||||
m.InitClassificator();
|
||||
|
|
|
@ -477,7 +477,6 @@ void Framework::RegisterAllMaps()
|
|||
("Registering maps while map downloading leads to removing downloading maps from "
|
||||
"ActiveMapsListener::m_items."));
|
||||
|
||||
platform::CleanupMapsDirectory(m_storage.GetCurrentDataVersion());
|
||||
m_storage.RegisterAllLocalMaps();
|
||||
|
||||
int minFormat = numeric_limits<int>::max();
|
||||
|
|
|
@ -81,7 +81,8 @@ public:
|
|||
private:
|
||||
friend string DebugPrint(LocalCountryFile const &);
|
||||
friend void UnitTest_LocalCountryFile_DirectoryLookup();
|
||||
friend void FindAllLocalMaps(vector<LocalCountryFile> & localFiles);
|
||||
friend void FindAllLocalMapsAndCleanup(int64_t latestVersion,
|
||||
vector<LocalCountryFile> & localFiles);
|
||||
|
||||
/// @note! If directory is empty, the file is stored in resources.
|
||||
/// In this case, the only valid params are m_countryFile and m_version.
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "local_country_file_utils.hpp"
|
||||
#include "mwm_version.hpp"
|
||||
#include "platform.hpp"
|
||||
#include "platform/local_country_file_utils.hpp"
|
||||
|
||||
#include "platform/country_file.hpp"
|
||||
#include "platform/mwm_version.hpp"
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include "coding/file_name_utils.hpp"
|
||||
#include "coding/internal/file_data.hpp"
|
||||
|
@ -15,6 +17,7 @@
|
|||
#include "std/cctype.hpp"
|
||||
#include "std/sstream.hpp"
|
||||
#include "std/unique_ptr.hpp"
|
||||
#include "std/unordered_set.hpp"
|
||||
|
||||
#include "defines.hpp"
|
||||
|
||||
|
@ -74,13 +77,44 @@ string GetSpecialFilesSearchScope()
|
|||
#endif // defined(OMIM_OS_ANDROID)
|
||||
}
|
||||
|
||||
void DeleteDownloaderFilesForAllCountries(string const & directory)
|
||||
class StringsRegexpFilter
|
||||
{
|
||||
static string const regexp = "\\.(downloading|resume|ready)[0-9]?$";
|
||||
Platform::FilesList files;
|
||||
Platform::GetFilesByRegExp(directory, regexp, files);
|
||||
for (auto const & file : files)
|
||||
my::DeleteFileX(my::JoinFoldersToPath(directory, file));
|
||||
public:
|
||||
StringsRegexpFilter(string const & regexp) { regexp::Create(regexp, m_regexp); }
|
||||
|
||||
bool Matches(string const & s) const { return regexp::Matches(s, m_regexp); }
|
||||
|
||||
private:
|
||||
regexp::RegExpT m_regexp;
|
||||
};
|
||||
|
||||
bool IsSpecialName(string const & name) { return name == "." || name == ".."; }
|
||||
|
||||
bool IsDownloaderFile(string const & name)
|
||||
{
|
||||
static StringsRegexpFilter const filter(".*\\.(downloading|resume|ready)[0-9]?$");
|
||||
return filter.Matches(name);
|
||||
}
|
||||
|
||||
bool DirectoryHasIndexesOnly(string const & directory)
|
||||
{
|
||||
Platform::TFilesWithType fwts;
|
||||
Platform::GetFilesByType(directory, Platform::FILE_TYPE_REGULAR | Platform::FILE_TYPE_DIRECTORY,
|
||||
fwts);
|
||||
for (auto const & fwt : fwts)
|
||||
{
|
||||
auto const & name = fwt.first;
|
||||
auto const & type = fwt.second;
|
||||
if (type == Platform::FILE_TYPE_DIRECTORY)
|
||||
{
|
||||
if (!IsSpecialName(name))
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
if (!CountryIndexes::IsIndexFile(name))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
@ -96,93 +130,93 @@ void DeleteDownloaderFilesForCountry(CountryFile const & countryFile, int64_t ve
|
|||
}
|
||||
}
|
||||
|
||||
void CleanupMapsDirectory(int64_t latestVersion)
|
||||
{
|
||||
Platform & platform = GetPlatform();
|
||||
|
||||
string const mapsDir = platform.WritableDir();
|
||||
|
||||
{
|
||||
// Delete Brazil.mwm and Japan.mwm maps, because they was replaces with
|
||||
// smaler regions after osrm routing implementation.
|
||||
vector<LocalCountryFile> localFiles;
|
||||
FindAllLocalMapsInDirectory(mapsDir, 0 /* version */, localFiles);
|
||||
for (LocalCountryFile & localFile : localFiles)
|
||||
{
|
||||
string const & countryName = localFile.GetCountryFile().GetNameWithoutExt();
|
||||
if (countryName == "Japan" || countryName == "Brazil")
|
||||
{
|
||||
localFile.SyncWithDisk();
|
||||
localFile.DeleteFromDisk(MapOptions::MapWithCarRouting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try to delete empty folders.
|
||||
Platform::FilesList subdirs;
|
||||
platform.GetFilesByType(mapsDir, Platform::FILE_TYPE_DIRECTORY, subdirs);
|
||||
for (string const & subdir : subdirs)
|
||||
{
|
||||
// No need to visit parent directory.
|
||||
if (subdir == "..")
|
||||
continue;
|
||||
|
||||
int64_t version = 0;
|
||||
if (subdir != "." && !ParseVersion(subdir, version))
|
||||
continue;
|
||||
|
||||
string const subdirPath = my::JoinFoldersToPath(mapsDir, subdir);
|
||||
|
||||
// It's OK to remove all temprorary files for maps older than app.
|
||||
if (version != latestVersion)
|
||||
DeleteDownloaderFilesForAllCountries(subdirPath);
|
||||
|
||||
// Remove subdirectory if it does not contain any files except "." and "..".
|
||||
if (subdir != "." && Platform::IsDirectoryEmpty(subdirPath))
|
||||
{
|
||||
Platform::EError const ret = Platform::RmDir(subdirPath);
|
||||
ASSERT_EQUAL(Platform::ERR_OK, ret,
|
||||
("Can't remove empty directory:", subdirPath, "error:", ret));
|
||||
UNUSED_VALUE(ret);
|
||||
}
|
||||
}
|
||||
|
||||
/// @todo Cleanup temporary index files for already absent mwm files.
|
||||
/// https://trello.com/c/PKiiOsB4/28--
|
||||
}
|
||||
|
||||
void FindAllLocalMapsInDirectory(string const & directory, int64_t version,
|
||||
vector<LocalCountryFile> & localFiles)
|
||||
void FindAllLocalMapsInDirectoryAndCleanup(string const & directory, int64_t version,
|
||||
int64_t latestVersion,
|
||||
vector<LocalCountryFile> & localFiles)
|
||||
{
|
||||
vector<string> files;
|
||||
Platform & platform = GetPlatform();
|
||||
|
||||
platform.GetFilesByRegExp(directory, ".*\\" DATA_FILE_EXTENSION "$", files);
|
||||
for (string const & file : files)
|
||||
Platform::TFilesWithType fwts;
|
||||
platform.GetFilesByType(directory, Platform::FILE_TYPE_REGULAR | Platform::FILE_TYPE_DIRECTORY,
|
||||
fwts);
|
||||
|
||||
unordered_set<string> names;
|
||||
for (auto const & fwt : fwts)
|
||||
{
|
||||
if (fwt.second != Platform::FILE_TYPE_REGULAR)
|
||||
continue;
|
||||
|
||||
string name = fwt.first;
|
||||
|
||||
// Remove downloader files for old version directories.
|
||||
if (IsDownloaderFile(name) && version < latestVersion)
|
||||
{
|
||||
my::DeleteFileX(my::JoinFoldersToPath(directory, name));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strings::EndsWith(name, DATA_FILE_EXTENSION))
|
||||
continue;
|
||||
|
||||
// Remove DATA_FILE_EXTENSION and use base name as a country file name.
|
||||
string name = file;
|
||||
my::GetNameWithoutExt(name);
|
||||
localFiles.emplace_back(directory, CountryFile(name), version);
|
||||
names.insert(name);
|
||||
LocalCountryFile localFile(directory, CountryFile(name), version);
|
||||
|
||||
// Delete Brazil.mwm and Japan.mwm maps, because they were
|
||||
// replaced with smaller regions after osrm routing
|
||||
// implementation.
|
||||
if (name == "Japan" || name == "Brazil")
|
||||
{
|
||||
localFile.SyncWithDisk();
|
||||
localFile.DeleteFromDisk(MapOptions::MapWithCarRouting);
|
||||
continue;
|
||||
}
|
||||
|
||||
localFiles.push_back(localFile);
|
||||
}
|
||||
|
||||
for (auto const & fwt : fwts)
|
||||
{
|
||||
if (fwt.second != Platform::FILE_TYPE_DIRECTORY)
|
||||
continue;
|
||||
|
||||
string name = fwt.first;
|
||||
if (IsSpecialName(name))
|
||||
continue;
|
||||
|
||||
if (names.count(name) == 0 && DirectoryHasIndexesOnly(my::JoinFoldersToPath(directory, name)))
|
||||
{
|
||||
// Directory which looks like a directory with indexes for absent country. It's OK to remove
|
||||
// it.
|
||||
LocalCountryFile absentCountry(directory, CountryFile(name), version);
|
||||
CountryIndexes::DeleteFromDisk(absentCountry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FindAllLocalMaps(vector<LocalCountryFile> & localFiles)
|
||||
void FindAllLocalMapsAndCleanup(int64_t latestVersion, vector<LocalCountryFile> & localFiles)
|
||||
{
|
||||
localFiles.clear();
|
||||
|
||||
Platform & platform = GetPlatform();
|
||||
|
||||
string const directory = platform.WritableDir();
|
||||
FindAllLocalMapsInDirectory(directory, 0 /* version */, localFiles);
|
||||
string const dir = platform.WritableDir();
|
||||
FindAllLocalMapsInDirectoryAndCleanup(dir, 0 /* version */, latestVersion, localFiles);
|
||||
|
||||
Platform::FilesList subdirs;
|
||||
Platform::GetFilesByType(directory, Platform::FILE_TYPE_DIRECTORY, subdirs);
|
||||
for (string const & subdir : subdirs)
|
||||
Platform::TFilesWithType fwts;
|
||||
Platform::GetFilesByType(dir, Platform::FILE_TYPE_DIRECTORY, fwts);
|
||||
for (auto const & fwt : fwts)
|
||||
{
|
||||
string const & subdir = fwt.first;
|
||||
int64_t version;
|
||||
if (ParseVersion(subdir, version))
|
||||
FindAllLocalMapsInDirectory(my::JoinFoldersToPath(directory, subdir), version, localFiles);
|
||||
if (!ParseVersion(subdir, version))
|
||||
continue;
|
||||
|
||||
string const fullPath = my::JoinFoldersToPath(dir, subdir);
|
||||
FindAllLocalMapsInDirectoryAndCleanup(fullPath, version, latestVersion, localFiles);
|
||||
Platform::EError err = Platform::RmDir(fullPath);
|
||||
if (err != Platform::ERR_OK && err != Platform::ERR_DIRECTORY_NOT_EMPTY)
|
||||
LOG(LWARNING, ("Can't remove directory:", fullPath, err));
|
||||
}
|
||||
|
||||
// World and WorldCoasts can be stored in app bundle or in resources
|
||||
|
@ -198,10 +232,12 @@ void FindAllLocalMaps(vector<LocalCountryFile> & localFiles)
|
|||
|
||||
try
|
||||
{
|
||||
ModelReaderPtr reader(platform.GetReader(file + DATA_FILE_EXTENSION, GetSpecialFilesSearchScope()));
|
||||
ModelReaderPtr reader(
|
||||
platform.GetReader(file + DATA_FILE_EXTENSION, GetSpecialFilesSearchScope()));
|
||||
|
||||
// Assume that empty path means the resource file.
|
||||
LocalCountryFile worldFile(string(), CountryFile(file), version::ReadVersionTimestamp(reader));
|
||||
LocalCountryFile worldFile(string(), CountryFile(file),
|
||||
version::ReadVersionTimestamp(reader));
|
||||
worldFile.m_files = MapOptions::Map;
|
||||
if (i != localFiles.end())
|
||||
{
|
||||
|
@ -222,6 +258,12 @@ void FindAllLocalMaps(vector<LocalCountryFile> & localFiles)
|
|||
}
|
||||
}
|
||||
|
||||
void CleanupMapsDirectory(int64_t latestVersion)
|
||||
{
|
||||
vector<LocalCountryFile> localFiles;
|
||||
FindAllLocalMapsAndCleanup(latestVersion, localFiles);
|
||||
}
|
||||
|
||||
bool ParseVersion(string const & s, int64_t & version)
|
||||
{
|
||||
if (s.empty() || s.size() > kMaxTimestampLength)
|
||||
|
@ -265,7 +307,10 @@ ModelReader * GetCountryReader(platform::LocalCountryFile const & file, MapOptio
|
|||
Platform & platform = GetPlatform();
|
||||
// See LocalCountryFile comment for explanation.
|
||||
if (file.GetDirectory().empty())
|
||||
return platform.GetReader(file.GetCountryName() + DATA_FILE_EXTENSION, GetSpecialFilesSearchScope());
|
||||
{
|
||||
return platform.GetReader(file.GetCountryName() + DATA_FILE_EXTENSION,
|
||||
GetSpecialFilesSearchScope());
|
||||
}
|
||||
return platform.GetReader(file.GetPath(options), "f");
|
||||
}
|
||||
|
||||
|
@ -329,6 +374,13 @@ void CountryIndexes::GetIndexesExts(vector<string> & exts)
|
|||
exts.push_back(kOffsetsExt);
|
||||
}
|
||||
|
||||
// static
|
||||
bool CountryIndexes::IsIndexFile(string const & file)
|
||||
{
|
||||
return strings::EndsWith(file, kBitsExt) || strings::EndsWith(file, kNodesExt) ||
|
||||
strings::EndsWith(file, kOffsetsExt);
|
||||
}
|
||||
|
||||
// static
|
||||
string CountryIndexes::IndexesDir(LocalCountryFile const & localFile)
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "platform/country_defines.hpp"
|
||||
#include "platform/local_country_file.hpp"
|
||||
|
||||
#include "std/function.hpp"
|
||||
#include "std/shared_ptr.hpp"
|
||||
#include "std/utility.hpp"
|
||||
#include "std/vector.hpp"
|
||||
|
@ -14,20 +15,16 @@ namespace platform
|
|||
// Removes all files downloader creates during downloading of a country.
|
||||
void DeleteDownloaderFilesForCountry(CountryFile const & countryFile, int64_t version);
|
||||
|
||||
// Removes partially downloaded maps, empty directories and old
|
||||
// (format v1) maps. Also, removes old (splitted) Japan and Brazil
|
||||
// maps. |version| must be set to the latest data version this app can
|
||||
// work with.
|
||||
void CleanupMapsDirectory(int64_t latestVersion);
|
||||
// Finds all local map files in |directory|. Version of these files is
|
||||
// passed as an argument. Also, performs cleanup described in comment
|
||||
// for FindAllLocalMapsAndCleanup().
|
||||
void FindAllLocalMapsInDirectoryAndCleanup(string const & directory, int64_t version,
|
||||
int64_t latestVersion,
|
||||
vector<LocalCountryFile> & localFiles);
|
||||
|
||||
// Finds all local map files in a directory. Version of these files is
|
||||
// passed as an argument.
|
||||
void FindAllLocalMapsInDirectory(string const & directory, int64_t version,
|
||||
vector<LocalCountryFile> & localFiles);
|
||||
|
||||
// Finds all local map files in resources and writable
|
||||
// directory. Also, for Android, checks /Android/obb directory.
|
||||
// Directories should have the following structure:
|
||||
// Finds all local map files in resources and writable directory. For
|
||||
// Android, checks /Android/obb directory. Subdirectories in the
|
||||
// writable directory should have the following structure:
|
||||
//
|
||||
// dir/*.mwm -- map files, base name should correspond to countries.txt,
|
||||
// -- version is assumed to be zero (unknown).
|
||||
|
@ -38,10 +35,17 @@ void FindAllLocalMapsInDirectory(string const & directory, int64_t version,
|
|||
// dir/[0-9]{1,18}/*.mwm.routing -- routing file for corresponding map files,
|
||||
// -- version is assumed to be the name of a directory.
|
||||
//
|
||||
// We can't derive version of a map file from its header because
|
||||
// currently header stores format version + individual mwm's file
|
||||
// generation timestamp, not timestamp mentioned in countries.txt.
|
||||
void FindAllLocalMaps(vector<LocalCountryFile> & localFiles);
|
||||
// Also, this method performs cleanup described in a comment for
|
||||
// CleanupMapsDirectory().
|
||||
void FindAllLocalMapsAndCleanup(int64_t latestVersion, vector<LocalCountryFile> & localFiles);
|
||||
|
||||
// This method removes:
|
||||
// * partially downloaded non-latest maps (with version less than |latestVersion|)
|
||||
// * empty directories
|
||||
// * old (format v1) maps
|
||||
// * old (split) Japan and Brazil maps
|
||||
// * indexes for absent countries
|
||||
void CleanupMapsDirectory(int64_t latestVersion);
|
||||
|
||||
// Tries to parse a version from a string of size not longer than 18
|
||||
// symbols and representing an unsigned decimal number. Leading zeroes
|
||||
|
@ -84,6 +88,9 @@ public:
|
|||
// Pushes to the exts's end possible index files extensions.
|
||||
static void GetIndexesExts(vector<string> & exts);
|
||||
|
||||
// Returns true if |file| corresponds to an index file.
|
||||
static bool IsIndexFile(string const & file);
|
||||
|
||||
private:
|
||||
friend void UnitTest_LocalCountryFile_CountryIndexes();
|
||||
friend void UnitTest_LocalCountryFile_DoNotDeleteUserFiles();
|
||||
|
|
|
@ -120,7 +120,8 @@ void Platform::GetFilesByExt(string const & directory, string const & ext, Files
|
|||
}
|
||||
|
||||
// static
|
||||
void Platform::GetFilesByType(string const & directory, unsigned typeMask, FilesList & outFiles)
|
||||
void Platform::GetFilesByType(string const & directory, unsigned typeMask,
|
||||
TFilesWithType & outFiles)
|
||||
{
|
||||
FilesList allFiles;
|
||||
GetFilesByRegExp(directory, ".*", allFiles);
|
||||
|
@ -130,7 +131,7 @@ void Platform::GetFilesByType(string const & directory, unsigned typeMask, Files
|
|||
if (GetFileType(my::JoinFoldersToPath(directory, file), type) != ERR_OK)
|
||||
continue;
|
||||
if (typeMask & type)
|
||||
outFiles.push_back(file);
|
||||
outFiles.emplace_back(file, type);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,8 @@ public:
|
|||
CONNECTION_WWAN
|
||||
};
|
||||
|
||||
using TFilesWithType = vector<pair<string, EFileType>>;
|
||||
|
||||
protected:
|
||||
/// Usually read-only directory for application resources
|
||||
string m_resourcesDir;
|
||||
|
@ -138,7 +140,8 @@ public:
|
|||
static void GetFilesByRegExp(string const & directory, string const & regexp, FilesList & outFiles);
|
||||
//@}
|
||||
|
||||
static void GetFilesByType(string const & directory, unsigned typeMask, FilesList & outFiles);
|
||||
static void GetFilesByType(string const & directory, unsigned typeMask,
|
||||
TFilesWithType & outFiles);
|
||||
|
||||
static bool IsDirectoryEmpty(string const & directory);
|
||||
|
||||
|
|
|
@ -137,6 +137,13 @@ UNIT_TEST(LocalCountryFile_CleanupMapFiles)
|
|||
Platform & platform = GetPlatform();
|
||||
string const mapsDir = platform.WritableDir();
|
||||
|
||||
// Two fake directories for test country files and indexes.
|
||||
ScopedDir dir3("3");
|
||||
ScopedDir dir4("4");
|
||||
|
||||
ScopedDir absentCountryIndexesDir(dir4, "Absent");
|
||||
ScopedDir irelandIndexesDir(dir4, "Ireland");
|
||||
|
||||
CountryFile japanFile("Japan");
|
||||
CountryFile brazilFile("Brazil");
|
||||
CountryFile irelandFile("Ireland");
|
||||
|
@ -147,27 +154,19 @@ UNIT_TEST(LocalCountryFile_CleanupMapFiles)
|
|||
LocalCountryFile brazilLocalFile(mapsDir, brazilFile, 0 /* version */);
|
||||
ScopedFile brazilMapFile("Brazil.mwm", "Brazil");
|
||||
|
||||
LocalCountryFile irelandLocalFile(mapsDir, irelandFile, 0 /* version */);
|
||||
ScopedFile irelandMapFile("Ireland.mwm", "Ireland");
|
||||
LocalCountryFile irelandLocalFile(dir4.GetFullPath(), irelandFile, 4 /* version */);
|
||||
ScopedFile irelandMapFile(dir4, irelandFile, MapOptions::Map, "Ireland");
|
||||
|
||||
ScopedDir emptyDir("3");
|
||||
|
||||
// Check that FindAllLocalMaps()
|
||||
// Check FindAllLocalMaps()
|
||||
vector<LocalCountryFile> localFiles;
|
||||
FindAllLocalMaps(localFiles);
|
||||
TEST(Contains(localFiles, japanLocalFile), (japanLocalFile, localFiles));
|
||||
TEST(Contains(localFiles, brazilLocalFile), (brazilLocalFile, localFiles));
|
||||
FindAllLocalMapsAndCleanup(-1 /* latestVersion */, localFiles);
|
||||
TEST(!Contains(localFiles, japanLocalFile), (japanLocalFile, localFiles));
|
||||
TEST(!Contains(localFiles, brazilLocalFile), (brazilLocalFile, localFiles));
|
||||
TEST(Contains(localFiles, irelandLocalFile), (irelandLocalFile, localFiles));
|
||||
|
||||
CleanupMapsDirectory(0 /* latestVersion */);
|
||||
|
||||
japanLocalFile.SyncWithDisk();
|
||||
TEST_EQUAL(MapOptions::Nothing, japanLocalFile.GetFiles(), ());
|
||||
TEST(!japanMapFile.Exists(), (japanMapFile));
|
||||
japanMapFile.Reset();
|
||||
|
||||
brazilLocalFile.SyncWithDisk();
|
||||
TEST_EQUAL(MapOptions::Nothing, brazilLocalFile.GetFiles(), ());
|
||||
TEST(!brazilMapFile.Exists(), (brazilMapFile));
|
||||
brazilMapFile.Reset();
|
||||
|
||||
|
@ -177,8 +176,15 @@ UNIT_TEST(LocalCountryFile_CleanupMapFiles)
|
|||
TEST(!irelandMapFile.Exists(), (irelandMapFile));
|
||||
irelandMapFile.Reset();
|
||||
|
||||
TEST(!emptyDir.Exists(), ("Empty directory", emptyDir, "wasn't removed."));
|
||||
emptyDir.Reset();
|
||||
TEST(!dir3.Exists(), ("Empty directory", dir3, "wasn't removed."));
|
||||
dir3.Reset();
|
||||
|
||||
TEST(dir4.Exists(), ());
|
||||
|
||||
TEST(!absentCountryIndexesDir.Exists(), ("Indexes for absent country weren't deleted."));
|
||||
absentCountryIndexesDir.Reset();
|
||||
|
||||
TEST(irelandIndexesDir.Exists(), ());
|
||||
}
|
||||
|
||||
UNIT_TEST(LocalCountryFile_CleanupPartiallyDownloadedFiles)
|
||||
|
@ -235,7 +241,8 @@ UNIT_TEST(LocalCountryFile_DirectoryLookup)
|
|||
"Netherlands-routing");
|
||||
|
||||
vector<LocalCountryFile> localFiles;
|
||||
FindAllLocalMapsInDirectory(testDir.GetFullPath(), 150309, localFiles);
|
||||
FindAllLocalMapsInDirectoryAndCleanup(testDir.GetFullPath(), 150309 /* version */,
|
||||
-1 /* latestVersion */, localFiles);
|
||||
sort(localFiles.begin(), localFiles.end());
|
||||
for (LocalCountryFile & localFile : localFiles)
|
||||
localFile.SyncWithDisk();
|
||||
|
@ -259,11 +266,11 @@ UNIT_TEST(LocalCountryFile_AllLocalFilesLookup)
|
|||
{
|
||||
CountryFile const italyFile("Italy");
|
||||
|
||||
ScopedDir testDir("010101");
|
||||
ScopedDir testDir("10101");
|
||||
ScopedFile testItalyMapFile(testDir, italyFile, MapOptions::Map, "Italy-map");
|
||||
|
||||
vector<LocalCountryFile> localFiles;
|
||||
FindAllLocalMaps(localFiles);
|
||||
FindAllLocalMapsAndCleanup(-1 /* latestVersion */, localFiles);
|
||||
multiset<LocalCountryFile> localFilesSet(localFiles.begin(), localFiles.end());
|
||||
|
||||
bool worldFound = false;
|
||||
|
|
|
@ -22,9 +22,13 @@ char const * TEST_FILE_NAME = "some_temporary_unit_test_file.tmp";
|
|||
void CheckFilesPresence(string const & baseDir, unsigned typeMask,
|
||||
initializer_list<pair<string, size_t>> const & files)
|
||||
{
|
||||
Platform::FilesList filesList;
|
||||
Platform::GetFilesByType(baseDir, typeMask, filesList);
|
||||
multiset<string> filesSet(filesList.begin(), filesList.end());
|
||||
Platform::TFilesWithType fwts;
|
||||
Platform::GetFilesByType(baseDir, typeMask, fwts);
|
||||
|
||||
multiset<string> filesSet;
|
||||
for (auto const & fwt : fwts)
|
||||
filesSet.insert(fwt.first);
|
||||
|
||||
for (auto const & file : files)
|
||||
TEST_EQUAL(filesSet.count(file.first), file.second, (file.first, file.second));
|
||||
}
|
||||
|
|
|
@ -34,6 +34,11 @@ ScopedDir::ScopedDir(string const & relativePath)
|
|||
}
|
||||
}
|
||||
|
||||
ScopedDir::ScopedDir(ScopedDir const & parent, string const & name)
|
||||
: ScopedDir(my::JoinFoldersToPath(parent.GetRelativePath(), name))
|
||||
{
|
||||
}
|
||||
|
||||
ScopedDir::~ScopedDir()
|
||||
{
|
||||
if (m_reset)
|
||||
|
|
|
@ -18,6 +18,8 @@ public:
|
|||
/// @param path Path for a testing directory, should be relative to writable-dir.
|
||||
ScopedDir(string const & relativePath);
|
||||
|
||||
ScopedDir(ScopedDir const & parent, string const & name);
|
||||
|
||||
~ScopedDir();
|
||||
|
||||
inline void Reset() { m_reset = true; }
|
||||
|
|
|
@ -18,7 +18,7 @@ UNIT_TEST(CheckCrossSections)
|
|||
{
|
||||
static double constexpr kPointEquality = 0.01;
|
||||
vector<platform::LocalCountryFile> localFiles;
|
||||
platform::FindAllLocalMaps(localFiles);
|
||||
platform::FindAllLocalMapsAndCleanup(-1 /* latestVersion */, localFiles);
|
||||
|
||||
size_t ingoingErrors = 0;
|
||||
size_t outgoingErrors = 0;
|
||||
|
|
|
@ -159,7 +159,7 @@ namespace integration
|
|||
pl.SetResourceDir(options.m_resourcePath);
|
||||
|
||||
vector<LocalCountryFile> localFiles;
|
||||
platform::FindAllLocalMaps(localFiles);
|
||||
platform::FindAllLocalMapsAndCleanup(-1, localFiles);
|
||||
for (auto & file : localFiles)
|
||||
file.SyncWithDisk();
|
||||
ASSERT(!localFiles.empty(), ());
|
||||
|
|
|
@ -66,6 +66,12 @@ void DeleteCountryIndexes(LocalCountryFile const & localFile)
|
|||
platform::CountryIndexes::DeleteFromDisk(localFile);
|
||||
}
|
||||
|
||||
void DeleteFromDiskWithIndexes(LocalCountryFile const & localFile, MapOptions options)
|
||||
{
|
||||
DeleteCountryIndexes(localFile);
|
||||
localFile.DeleteFromDisk(options);
|
||||
}
|
||||
|
||||
class EqualFileName
|
||||
{
|
||||
string const & m_name;
|
||||
|
@ -105,7 +111,7 @@ void Storage::RegisterAllLocalMaps()
|
|||
m_localFilesForFakeCountries.clear();
|
||||
|
||||
vector<LocalCountryFile> localFiles;
|
||||
FindAllLocalMaps(localFiles);
|
||||
FindAllLocalMapsAndCleanup(GetCurrentDataVersion(), localFiles);
|
||||
|
||||
auto compareByCountryAndVersion = [](LocalCountryFile const & lhs, LocalCountryFile const & rhs)
|
||||
{
|
||||
|
@ -130,7 +136,7 @@ void Storage::RegisterAllLocalMaps()
|
|||
LocalCountryFile & localFile = *j;
|
||||
LOG(LINFO, ("Removing obsolete", localFile));
|
||||
localFile.SyncWithDisk();
|
||||
localFile.DeleteFromDisk(MapOptions::MapWithCarRouting);
|
||||
DeleteFromDiskWithIndexes(localFile, MapOptions::MapWithCarRouting);
|
||||
++j;
|
||||
}
|
||||
|
||||
|
@ -340,8 +346,7 @@ void Storage::DeleteCountry(TIndex const & index, MapOptions opt)
|
|||
void Storage::DeleteCustomCountryVersion(LocalCountryFile const & localFile)
|
||||
{
|
||||
CountryFile const countryFile = localFile.GetCountryFile();
|
||||
localFile.DeleteFromDisk(MapOptions::MapWithCarRouting);
|
||||
CountryIndexes::DeleteFromDisk(localFile);
|
||||
DeleteFromDiskWithIndexes(localFile, MapOptions::MapWithCarRouting);
|
||||
|
||||
{
|
||||
auto it = m_localFilesForFakeCountries.find(countryFile);
|
||||
|
@ -844,9 +849,8 @@ void Storage::DeleteCountryFiles(TIndex const & index, MapOptions opt)
|
|||
auto & localFiles = it->second;
|
||||
for (auto & localFile : localFiles)
|
||||
{
|
||||
localFile->DeleteFromDisk(opt);
|
||||
DeleteFromDiskWithIndexes(*localFile, opt);
|
||||
localFile->SyncWithDisk();
|
||||
DeleteCountryIndexes(*localFile);
|
||||
if (localFile->GetFiles() == MapOptions::Nothing)
|
||||
localFile.reset();
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "storage/queued_country.hpp"
|
||||
#include "storage/storage_defines.hpp"
|
||||
|
||||
#include "platform/local_country_file.hpp"
|
||||
|
||||
#include "std/function.hpp"
|
||||
#include "std/list.hpp"
|
||||
#include "std/set.hpp"
|
||||
|
@ -14,7 +16,6 @@
|
|||
#include "std/unique_ptr.hpp"
|
||||
#include "std/vector.hpp"
|
||||
|
||||
|
||||
namespace storage
|
||||
{
|
||||
/// Can be used to store local maps and/or maps available for download
|
||||
|
@ -48,7 +49,9 @@ private:
|
|||
|
||||
using TLocalFilePtr = shared_ptr<platform::LocalCountryFile>;
|
||||
map<TIndex, list<TLocalFilePtr>> m_localFiles;
|
||||
// Our World.mwm and WorldCoasts.mwm are fake countries, together with any custom mwm in data folder.
|
||||
|
||||
// Our World.mwm and WorldCoasts.mwm are fake countries, together with any custom mwm in data
|
||||
// folder.
|
||||
map<platform::CountryFile, TLocalFilePtr> m_localFilesForFakeCountries;
|
||||
|
||||
/// used to correctly calculate total country download progress with more than 1 file
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "platform/local_country_file.hpp"
|
||||
#include "platform/local_country_file_utils.hpp"
|
||||
#include "platform/platform.hpp"
|
||||
#include "platform/platform_tests_support/scoped_dir.hpp"
|
||||
#include "platform/platform_tests_support/scoped_file.hpp"
|
||||
|
||||
#include "coding/file_name_utils.hpp"
|
||||
|
@ -732,4 +733,30 @@ UNIT_TEST(StorageTest_EmptyRoutingFile)
|
|||
checker->StartDownload();
|
||||
runner.Run();
|
||||
}
|
||||
|
||||
UNIT_TEST(StorageTest_ObsoleteMapsRemoval)
|
||||
{
|
||||
CountryFile country("Azerbaijan");
|
||||
|
||||
tests_support::ScopedDir dir1("1");
|
||||
tests_support::ScopedFile map1(dir1, country, MapOptions::Map, "map1");
|
||||
LocalCountryFile file1(dir1.GetFullPath(), country, 1 /* version */);
|
||||
CountryIndexes::PreparePlaceOnDisk(file1);
|
||||
|
||||
tests_support::ScopedDir dir2("2");
|
||||
tests_support::ScopedFile map2(dir2, country, MapOptions::Map, "map2");
|
||||
LocalCountryFile file2(dir2.GetFullPath(), country, 2 /* version */);
|
||||
CountryIndexes::PreparePlaceOnDisk(file2);
|
||||
|
||||
TEST(map1.Exists(), ());
|
||||
TEST(map2.Exists(), ());
|
||||
|
||||
Storage storage;
|
||||
storage.RegisterAllLocalMaps();
|
||||
|
||||
TEST(!map1.Exists(), ());
|
||||
map1.Reset();
|
||||
|
||||
TEST(map2.Exists(), ());
|
||||
}
|
||||
} // namespace storage
|
||||
|
|
Loading…
Add table
Reference in a new issue