public static void assertDatabaseEquals( MemoryDatabase expectedDatabase, MemoryDatabase actualDatabase) { logger.log(Level.INFO, "--"); logger.log(Level.INFO, "Now comparing two databases."); logger.log( Level.INFO, "DON'T WORRY. This can take a long time or even overload the heap space."); List<DatabaseVersion> writtenDatabaseVersions = expectedDatabase.getDatabaseVersions(); List<DatabaseVersion> readDatabaseVersions = actualDatabase.getDatabaseVersions(); assertEquals( "Different number of database versions.", writtenDatabaseVersions.size(), readDatabaseVersions.size()); for (DatabaseVersion writtenDatabaseVersion : writtenDatabaseVersions) { DatabaseVersion readDatabaseVersion = null; for (DatabaseVersion aReadDatabaseVersion : readDatabaseVersions) { if (aReadDatabaseVersion.equals(writtenDatabaseVersion)) { readDatabaseVersion = aReadDatabaseVersion; break; } } assertNotNull( "Database version " + writtenDatabaseVersion + " does not exist in read database.", readDatabaseVersion); assertDatabaseVersionEquals(writtenDatabaseVersion, readDatabaseVersion); } logger.log(Level.INFO, "End of comparing databases"); logger.log(Level.INFO, "--"); }
/** * Finds the multichunks that need to be downloaded for the given file version -- using the local * database and given winners database. Returns a set of multichunk identifiers. */ private Collection<MultiChunkId> determineMultiChunksToDownload( FileVersion fileVersion, MemoryDatabase winnersDatabase) { Set<MultiChunkId> multiChunksToDownload = new HashSet<MultiChunkId>(); // First: Check if we know this file locally! List<MultiChunkId> multiChunkIds = localDatabase.getMultiChunkIds(fileVersion.getChecksum()); if (multiChunkIds.size() > 0) { multiChunksToDownload.addAll(multiChunkIds); } else { // Second: We don't know it locally; must be from the winners database FileContent winningFileContent = winnersDatabase.getContent(fileVersion.getChecksum()); boolean winningFileHasContent = winningFileContent != null; if (winningFileHasContent) { // File can be empty! List<ChunkChecksum> fileChunks = winningFileContent.getChunks(); // TODO [medium] Instead of just looking for multichunks to download here, we should look // for chunks in local files as well // and return the chunk positions in the local files ChunkPosition (chunk123 at file12, // offset 200, size 250) Map<ChunkChecksum, MultiChunkId> checksumsWithMultiChunkIds = localDatabase.getMultiChunkIdsByChecksums(fileChunks); for (ChunkChecksum chunkChecksum : fileChunks) { MultiChunkId multiChunkIdForChunk = checksumsWithMultiChunkIds.get(chunkChecksum); if (multiChunkIdForChunk == null) { multiChunkIdForChunk = winnersDatabase.getMultiChunkIdForChunk(chunkChecksum); if (multiChunkIdForChunk == null) { throw new RuntimeException("Cannot find multichunk for chunk " + chunkChecksum); } } if (!multiChunksToDownload.contains(multiChunkIdForChunk)) { logger.log( Level.INFO, " + Adding multichunk " + multiChunkIdForChunk + " to download list ..."); multiChunksToDownload.add(multiChunkIdForChunk); } } } } return multiChunksToDownload; }
public static void writeDatabaseFileToDisk( MemoryDatabase db, File writtenDatabaseFile, Transformer transformer) throws IOException { DatabaseXmlSerializer dao = new DatabaseXmlSerializer(transformer); dao.save(db.getDatabaseVersions(), writtenDatabaseFile); }