
com.arcadedb.server.ha.message.FileContentResponse Maven / Gradle / Ivy
The newest version!
/*
* Copyright © 2021-present Arcade Data Ltd ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-FileCopyrightText: 2021-present Arcade Data Ltd ([email protected])
* SPDX-License-Identifier: Apache-2.0
*/
package com.arcadedb.server.ha.message;
import com.arcadedb.database.Binary;
import com.arcadedb.database.DatabaseInternal;
import com.arcadedb.engine.ComponentFile;
import com.arcadedb.engine.LocalBucket;
import com.arcadedb.engine.MutablePage;
import com.arcadedb.engine.PageId;
import com.arcadedb.engine.PageManager;
import com.arcadedb.engine.PaginatedComponent;
import com.arcadedb.engine.PaginatedComponentFile;
import com.arcadedb.log.LogManager;
import com.arcadedb.server.ArcadeDBServer;
import com.arcadedb.server.ha.HAServer;
import com.arcadedb.server.ha.ReplicationException;
import com.arcadedb.utility.FileUtils;
import java.io.*;
import java.util.logging.*;
public class FileContentResponse extends HAAbstractCommand {
private String databaseName;
private int fileId;
private String fileName;
private int pageFromInclusive;
private Binary pagesContent;
private int totalPages;
private boolean last;
public FileContentResponse() {
}
public FileContentResponse(final String databaseName, final int fileId, final String fileName, final int pageFromInclusive,
final Binary pagesContent, final int totalPages, final boolean last) {
this.databaseName = databaseName;
this.fileId = fileId;
this.fileName = fileName;
this.pageFromInclusive = pageFromInclusive;
this.pagesContent = pagesContent;
this.totalPages = totalPages;
this.last = last;
}
public Binary getPagesContent() {
return pagesContent;
}
public int getPages() {
return totalPages;
}
public boolean isLast() {
return last;
}
@Override
public HACommand execute(final HAServer server, final String remoteServerName, final long messageNumber) {
final DatabaseInternal database = server.getServer().getDatabase(databaseName);
final PageManager pageManager = database.getPageManager();
try {
final ComponentFile file = database.getFileManager()
.getOrCreateFile(fileId, database.getDatabasePath() + File.separator + fileName);
if (totalPages == 0)
return null;
if (file instanceof PaginatedComponentFile) {
final PaginatedComponentFile pFile = (PaginatedComponentFile) file;
final int pageSize = pFile.getPageSize();
if (pagesContent.size() != totalPages * pageSize) {
LogManager.instance()
.log(this, Level.SEVERE, "Error on received chunk for file '%s': size=%s, expected=%s (totalPages=%d)",
file.getFileName(), FileUtils.getSizeAsString(pagesContent.size()),
FileUtils.getSizeAsString((long) totalPages * pageSize), totalPages);
throw new ReplicationException("Invalid file chunk");
}
for (int i = 0; i < totalPages; ++i) {
final PageId pageId = new PageId(database, file.getFileId(), pageFromInclusive + i);
final MutablePage page = new MutablePage(pageId, pageSize);
System.arraycopy(pagesContent.getContent(), i * pageSize, page.getTrackable().getContent(), 0, pageSize);
page.loadMetadata();
pageManager.overwritePage(page);
LogManager.instance().log(this, Level.FINE, "Overwritten page %s v%d from the leader", null,//
pageId, page.getVersion());
}
final PaginatedComponent component = (PaginatedComponent) database.getSchema().getFileByIdIfExists(file.getFileId());
if (component != null) {
final int lastPageNumber = pageFromInclusive + totalPages;
if (lastPageNumber > component.getTotalPages()) {
component.setPageCount(lastPageNumber);
database.getFileManager().setVirtualFileSize(file.getFileId(),
(long) component.getTotalPages() * ((PaginatedComponentFile) database.getFileManager()
.getFile(file.getFileId())).getPageSize());
}
if (component instanceof LocalBucket)
// RESET CACHED RECORD COUNT
((LocalBucket) component).setCachedRecordCount(-1);
}
} else
LogManager.instance().log(this, Level.SEVERE, "Cannot write not paginated file %s from the leader", fileName);
} catch (final IOException e) {
LogManager.instance().log(this, Level.SEVERE, "Error on installing file content from leader server", e);
throw new ReplicationException("Error on installing file content from leader server", e);
}
return null;
}
@Override
public void toStream(final Binary stream) {
stream.putString(databaseName);
stream.putInt(fileId);
stream.putString(fileName);
stream.putInt(pageFromInclusive);
stream.putUnsignedNumber(totalPages);
stream.putBytes(pagesContent.getContent(), pagesContent.size());
stream.putByte((byte) (last ? 1 : 0));
}
@Override
public void fromStream(final ArcadeDBServer server, final Binary stream) {
databaseName = stream.getString();
fileId = stream.getInt();
fileName = stream.getString();
pageFromInclusive = stream.getInt();
totalPages = (int) stream.getUnsignedNumber();
pagesContent = new Binary(stream.getBytes());
last = stream.getByte() == 1;
}
@Override
public String toString() {
return "file=" + totalPages + " pages (" + pagesContent.size() + " bytes)";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy