use of org.syncany.database.MemoryDatabase in project syncany by syncany.
the class DownOperation method readUnknownDatabaseVersionHeaders.
/**
* Read the given database files into individual per-user {@link DatabaseBranch}es. This method only
* reads the headers from the local database files, and not the entire databases into memory.
*
* <p>The returned database branches contain only the per-client {@link DatabaseVersionHeader}s, and not
* the entire stitched branches, i.e. A's database branch will only contain database version headers from A.
*/
private SortedMap<DatabaseRemoteFile, List<DatabaseVersion>> readUnknownDatabaseVersionHeaders(SortedMap<File, DatabaseRemoteFile> remoteDatabases) throws IOException, StorageException {
logger.log(Level.INFO, "Loading database headers, creating branches ...");
// Read database files
SortedMap<DatabaseRemoteFile, List<DatabaseVersion>> remoteDatabaseHeaders = new TreeMap<DatabaseRemoteFile, List<DatabaseVersion>>();
for (Map.Entry<File, DatabaseRemoteFile> remoteDatabaseFileEntry : remoteDatabases.entrySet()) {
// Database cannot be reused, since these might be different clients
MemoryDatabase remoteDatabase = new MemoryDatabase();
File remoteDatabaseFileInCache = remoteDatabaseFileEntry.getKey();
DatabaseRemoteFile remoteDatabaseFile = remoteDatabaseFileEntry.getValue();
// only load headers!
databaseSerializer.load(remoteDatabase, remoteDatabaseFileInCache, null, null, DatabaseReadType.HEADER_ONLY);
remoteDatabaseHeaders.put(remoteDatabaseFile, remoteDatabase.getDatabaseVersions());
}
return remoteDatabaseHeaders;
}
use of org.syncany.database.MemoryDatabase in project syncany by syncany.
the class DownOperation method applyWinnersBranch.
/**
* Applies the winner's branch locally in the local database as well as on the local file system. To
* do so, it reads the winner's database, downloads newly required multichunks, determines file system actions
* and applies these actions locally.
* @param cleanupOccurred
* @param preDeleteFileHistoriesWithLastVersion
*/
private void applyWinnersBranch(DatabaseBranch localBranch, Entry<String, DatabaseBranch> winnersBranch, Map<DatabaseVersionHeader, File> databaseVersionLocations, boolean cleanupOccurred, List<PartialFileHistory> preDeleteFileHistoriesWithLastVersion) throws Exception {
DatabaseBranch winnersApplyBranch = databaseReconciliator.findWinnersApplyBranch(localBranch, winnersBranch.getValue());
logger.log(Level.INFO, "- Cleanup occurred: " + cleanupOccurred);
logger.log(Level.INFO, "- Database versions to APPLY locally: " + winnersApplyBranch);
boolean remoteChangesOccurred = winnersApplyBranch.size() > 0 || cleanupOccurred;
if (!remoteChangesOccurred) {
logger.log(Level.WARNING, " + Nothing to update. Nice!");
result.setResultCode(DownResultCode.OK_NO_REMOTE_CHANGES);
} else {
logger.log(Level.INFO, "Loading winners database (DEFAULT) ...");
DatabaseFileReader databaseFileReader = new DatabaseFileReader(databaseSerializer, winnersApplyBranch, databaseVersionLocations);
boolean noDatabaseVersions = !databaseFileReader.hasNext();
if (noDatabaseVersions) {
applyChangesAndPersistDatabase(new MemoryDatabase(), cleanupOccurred, preDeleteFileHistoriesWithLastVersion);
} else {
while (databaseFileReader.hasNext()) {
MemoryDatabase winnersDatabase = databaseFileReader.next();
applyChangesAndPersistDatabase(winnersDatabase, cleanupOccurred, preDeleteFileHistoriesWithLastVersion);
}
}
result.setResultCode(DownResultCode.OK_WITH_REMOTE_CHANGES);
}
}
use of org.syncany.database.MemoryDatabase in project syncany by syncany.
the class XmlDatabaseDaoTest method testWritePartialDatabaseOneToFive.
@Test
public void testWritePartialDatabaseOneToFive() throws IOException {
MemoryDatabase writtenDatabase = new MemoryDatabase();
List<DatabaseVersion> writtenDatabaseVersions = new ArrayList<DatabaseVersion>();
for (int i = 0; i < 10; i++) {
DatabaseVersion basedOnDatabaseVersion = (i > 0) ? writtenDatabaseVersions.get(i - 1) : null;
DatabaseVersion newDatabaseVersion = createDatabaseVersion(basedOnDatabaseVersion);
// Some random chunks
newDatabaseVersion.addChunk(new ChunkEntry(new ChunkChecksum(TestFileUtil.createRandomArray(20)), 32 * 1024));
newDatabaseVersion.addChunk(new ChunkEntry(new ChunkChecksum(TestFileUtil.createRandomArray(20)), 32 * 1024));
newDatabaseVersion.addChunk(new ChunkEntry(new ChunkChecksum(TestFileUtil.createRandomArray(20)), 32 * 1024));
// Add to database
writtenDatabase.addDatabaseVersion(newDatabaseVersion);
// Add to test array
writtenDatabaseVersions.add(newDatabaseVersion);
}
// Write database to disk, read it again, and compare them
File writtenDatabaseFile = new File(tempDir + "/db-" + Math.random() + "-" + Math.abs(new Random().nextInt(Integer.MAX_VALUE)));
DatabaseXmlSerializer writeDAO = new DatabaseXmlSerializer();
writeDAO.save(writtenDatabase.getDatabaseVersions(), writtenDatabaseFile);
// Read again
MemoryDatabase readDatabase = new MemoryDatabase();
DatabaseXmlSerializer readDAO = new DatabaseXmlSerializer();
readDAO.load(readDatabase, writtenDatabaseFile, null, null, DatabaseReadType.FULL);
for (int i = 0; i < 10; i++) {
DatabaseVersion writtenDatabaseVersion = writtenDatabaseVersions.get(i);
DatabaseVersion readDatabaseVersion = readDatabase.getDatabaseVersion(writtenDatabaseVersion.getVectorClock());
assertNotNull(readDatabaseVersion);
assertDatabaseVersionEquals(writtenDatabaseVersion, readDatabaseVersion);
}
assertEquals(10, readDatabase.getDatabaseVersions().size());
}
use of org.syncany.database.MemoryDatabase in project syncany by syncany.
the class XmlDatabaseDaoTest method testWriteAndReadVectorClock.
@Test
public void testWriteAndReadVectorClock() throws IOException {
// Prepare
MemoryDatabase newDatabase = new MemoryDatabase();
DatabaseVersion newDatabaseVersion = createDatabaseVersion();
// Create new vector clock
VectorClock vc = new VectorClock();
vc.setClock("UserA", 14234234L);
vc.setClock("UserB", 9433431232432L);
vc.setClock("UserC", 1926402374L);
newDatabaseVersion.setVectorClock(vc);
// Add database version
newDatabase.addDatabaseVersion(newDatabaseVersion);
// Write database to disk, read it again, and compare them
MemoryDatabase loadedDatabase = writeReadAndCompareDatabase(newDatabase);
// Check VC
DatabaseVersion loadedDatabaseVersionSelectedByVectorClock = loadedDatabase.getDatabaseVersion(vc);
DatabaseVersion loadedDatabaseVersionSelectedFirst = loadedDatabase.getDatabaseVersions().get(0);
assertEquals("Vector clocks do not match (selected by vector clock)", vc, loadedDatabaseVersionSelectedByVectorClock.getVectorClock());
assertEquals("Vector clocks do not match (selected first)", vc, loadedDatabaseVersionSelectedFirst.getVectorClock());
assertEquals("Database versions do not match.", loadedDatabaseVersionSelectedByVectorClock, loadedDatabaseVersionSelectedFirst);
}
use of org.syncany.database.MemoryDatabase in project syncany by syncany.
the class XmlDatabaseDaoTest method testWriteAndReadChunksWithFileContents.
@Test
public void testWriteAndReadChunksWithFileContents() throws IOException {
// Prepare
MemoryDatabase newDatabase = new MemoryDatabase();
DatabaseVersion newDatabaseVersion = createDatabaseVersion();
// Create chunks
ChunkEntry chunkA1 = new ChunkEntry(new ChunkChecksum(new byte[] { 1, 2, 3, 4, 5, 7, 8, 9, 0 }), 12);
ChunkEntry chunkA2 = new ChunkEntry(new ChunkChecksum(new byte[] { 9, 8, 7, 6, 5, 4, 3, 2, 1 }), 34);
ChunkEntry chunkA3 = new ChunkEntry(new ChunkChecksum(new byte[] { 1, 1, 1, 1, 1, 1, 1, 1, 1 }), 56);
ChunkEntry chunkA4 = new ChunkEntry(new ChunkChecksum(new byte[] { 2, 2, 2, 2, 2, 2, 2, 2, 2 }), 78);
ChunkEntry chunkB1 = new ChunkEntry(new ChunkChecksum(new byte[] { 3, 3, 3, 3, 3, 3, 3, 3, 3 }), 910);
ChunkEntry chunkB2 = new ChunkEntry(new ChunkChecksum(new byte[] { 4, 4, 4, 4, 4, 4, 4, 4, 4 }), 1112);
newDatabaseVersion.addChunk(chunkA1);
newDatabaseVersion.addChunk(chunkA2);
newDatabaseVersion.addChunk(chunkA3);
newDatabaseVersion.addChunk(chunkA4);
newDatabaseVersion.addChunk(chunkB1);
newDatabaseVersion.addChunk(chunkB2);
// Distribute chunks to file contents
FileContent contentA = new FileContent();
contentA.addChunk(chunkA1.getChecksum());
contentA.addChunk(chunkA2.getChecksum());
contentA.addChunk(chunkA3.getChecksum());
contentA.addChunk(chunkA4.getChecksum());
contentA.setChecksum(new FileChecksum(new byte[] { 5, 5, 5, 4, 4, 5, 5, 5, 5 }));
newDatabaseVersion.addFileContent(contentA);
FileContent contentB = new FileContent();
contentB.addChunk(chunkB1.getChecksum());
contentB.addChunk(chunkB2.getChecksum());
contentB.setChecksum(new FileChecksum(new byte[] { 1, 1, 1, 3, 3, 5, 5, 5, 5 }));
newDatabaseVersion.addFileContent(contentB);
// Add database version
newDatabase.addDatabaseVersion(newDatabaseVersion);
// Write database to disk, read it again, and compare them
MemoryDatabase loadedDatabase = writeReadAndCompareDatabase(newDatabase);
// Check chunks
assertEquals("Chunk not found in database loaded.", chunkA1, loadedDatabase.getChunk(chunkA1.getChecksum()));
assertEquals("Chunk not found in database loaded.", chunkA2, loadedDatabase.getChunk(chunkA2.getChecksum()));
assertEquals("Chunk not found in database loaded.", chunkA3, loadedDatabase.getChunk(chunkA3.getChecksum()));
assertEquals("Chunk not found in database loaded.", chunkA4, loadedDatabase.getChunk(chunkA4.getChecksum()));
assertEquals("Chunk not found in database loaded.", chunkB1, loadedDatabase.getChunk(chunkB1.getChecksum()));
assertEquals("Chunk not found in database loaded.", chunkB2, loadedDatabase.getChunk(chunkB2.getChecksum()));
// Check file contents
FileContent loadedContentA = loadedDatabase.getContent(contentA.getChecksum());
FileContent loadedContentB = loadedDatabase.getContent(contentB.getChecksum());
assertEquals("File content not found in database loaded.", contentA, loadedContentA);
assertEquals("File content not found in database loaded.", contentB, loadedContentB);
assertArrayEquals("Chunks in file content expected to be different.", contentA.getChunks().toArray(), loadedContentA.getChunks().toArray());
assertArrayEquals("Chunks in file content expected to be different.", contentB.getChunks().toArray(), loadedContentB.getChunks().toArray());
}
Aggregations