use of com.orientechnologies.orient.core.storage.ORawBuffer in project orientdb by orientechnologies.
the class LocalPaginatedClusterTest method testHideHalfRecords.
public void testHideHalfRecords() throws IOException {
final int records = 10000;
long seed = System.currentTimeMillis();
Random mersenneTwisterFast = new Random(seed);
System.out.println("testHideHalfRecords seed : " + seed);
Map<Long, byte[]> positionRecordMap = new HashMap<Long, byte[]>();
int recordVersion = 0;
recordVersion++;
recordVersion++;
for (int i = 0; i < records; i++) {
int recordSize = mersenneTwisterFast.nextInt(3 * OClusterPage.MAX_RECORD_SIZE) + 1;
byte[] bigRecord = new byte[recordSize];
mersenneTwisterFast.nextBytes(bigRecord);
final OPhysicalPosition physicalPosition = paginatedCluster.createRecord(bigRecord, recordVersion, (byte) 2, null);
positionRecordMap.put(physicalPosition.clusterPosition, bigRecord);
}
int hiddenRecords = 0;
Assert.assertEquals(records, paginatedCluster.getEntries());
Set<Long> hiddenPositions = new HashSet<Long>();
Iterator<Long> positionIterator = positionRecordMap.keySet().iterator();
while (positionIterator.hasNext()) {
long clusterPosition = positionIterator.next();
if (mersenneTwisterFast.nextBoolean()) {
hiddenPositions.add(clusterPosition);
Assert.assertTrue(paginatedCluster.hideRecord(clusterPosition));
hiddenRecords++;
Assert.assertEquals(records - hiddenRecords, paginatedCluster.getEntries());
positionIterator.remove();
}
}
Assert.assertEquals(paginatedCluster.getEntries(), records - hiddenRecords);
for (long deletedPosition : hiddenPositions) {
Assert.assertNull(paginatedCluster.readRecord(deletedPosition, false));
Assert.assertFalse(paginatedCluster.hideRecord(deletedPosition));
}
for (Map.Entry<Long, byte[]> entry : positionRecordMap.entrySet()) {
ORawBuffer rawBuffer = paginatedCluster.readRecord(entry.getKey(), false);
Assert.assertNotNull(rawBuffer);
Assert.assertEquals(rawBuffer.version, recordVersion);
Assert.assertEquals(rawBuffer.buffer, entry.getValue());
Assert.assertEquals(rawBuffer.recordType, 2);
}
}
use of com.orientechnologies.orient.core.storage.ORawBuffer in project orientdb by orientechnologies.
the class LocalPaginatedClusterTest method testUpdateOneSmallRecord.
public void testUpdateOneSmallRecord() throws IOException {
byte[] smallRecord = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
int recordVersion = 0;
recordVersion++;
recordVersion++;
OPhysicalPosition physicalPosition = paginatedCluster.createRecord(smallRecord, recordVersion, (byte) 1, null);
Assert.assertEquals(physicalPosition.clusterPosition, 0);
recordVersion++;
smallRecord = new byte[] { 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3 };
paginatedCluster.updateRecord(physicalPosition.clusterPosition, smallRecord, recordVersion, (byte) 2);
ORawBuffer rawBuffer = paginatedCluster.readRecord(physicalPosition.clusterPosition, false);
Assert.assertNotNull(rawBuffer);
Assert.assertEquals(rawBuffer.version, recordVersion);
Assert.assertEquals(rawBuffer.buffer, smallRecord);
Assert.assertEquals(rawBuffer.recordType, 2);
}
use of com.orientechnologies.orient.core.storage.ORawBuffer in project orientdb by orientechnologies.
the class LocalPaginatedClusterTest method testAddOneBigRecord.
public void testAddOneBigRecord() throws IOException {
byte[] bigRecord = new byte[2 * 65536 + 100];
Random mersenneTwisterFast = new Random();
mersenneTwisterFast.nextBytes(bigRecord);
int recordVersion = 0;
recordVersion++;
recordVersion++;
OPhysicalPosition physicalPosition = paginatedCluster.createRecord(bigRecord, recordVersion, (byte) 1, null);
Assert.assertEquals(physicalPosition.clusterPosition, 0);
ORawBuffer rawBuffer = paginatedCluster.readRecord(physicalPosition.clusterPosition, false);
Assert.assertNotNull(rawBuffer);
Assert.assertEquals(rawBuffer.version, recordVersion);
Assert.assertEquals(rawBuffer.buffer, bigRecord);
Assert.assertEquals(rawBuffer.recordType, 1);
}
use of com.orientechnologies.orient.core.storage.ORawBuffer in project orientdb by orientechnologies.
the class OConflictResolverDatabaseRepairer method repairRecords.
private boolean repairRecords(final ODatabaseDocumentInternal db, final List<ORecordId> rids) {
final ODistributedConfiguration dCfg = dManager.getDatabaseConfiguration(databaseName);
final int maxAutoRetry = OGlobalConfiguration.DISTRIBUTED_CONCURRENT_TX_MAX_AUTORETRY.getValueAsInteger();
final int autoRetryDelay = OGlobalConfiguration.DISTRIBUTED_CONCURRENT_TX_AUTORETRY_DELAY.getValueAsInteger();
final ODistributedRequestId requestId = new ODistributedRequestId(dManager.getLocalNodeId(), dManager.getNextMessageIdCounter());
final ODistributedDatabase localDistributedDatabase = dManager.getMessageService().getDatabase(databaseName);
final ODistributedTxContext ctx = localDistributedDatabase.registerTxContext(requestId);
try {
// ACQUIRE LOCKS WITH A LARGER TIMEOUT
ODistributedTransactionManager.acquireMultipleRecordLocks(this, dManager, localDistributedDatabase, rids, maxAutoRetry, autoRetryDelay, null, ctx, 2000);
try {
final Set<String> clusterNames = new HashSet();
for (ORecordId rid : rids) clusterNames.add(db.getClusterNameById(rid.getClusterId()));
final Collection<String> involvedServers = dCfg.getServers(clusterNames);
final Set<String> nonLocalServers = new HashSet<String>(involvedServers);
nonLocalServers.remove(dManager.getLocalNodeName());
if (nonLocalServers.isEmpty())
return true;
// CREATE LOCAL RESULT
final OTxTaskResult localResult = new OTxTaskResult();
for (ORecordId rid : rids) {
final OStorageOperationResult<ORawBuffer> res;
if (rid.getClusterPosition() > -1)
res = db.getStorage().readRecord(rid, null, true, false, null);
else
res = null;
if (res != null)
localResult.results.add(res.getResult());
else
localResult.results.add(null);
}
ODistributedServerLog.debug(this, dManager.getLocalNodeName(), involvedServers.toString(), ODistributedServerLog.DIRECTION.OUT, "Auto repairing records %s on servers %s (reqId=%s)...", rids, involvedServers, requestId);
// CREATE TX TASK
final ORepairRecordsTask tx = new ORepairRecordsTask();
for (ORecordId rid : rids) tx.add(new OReadRecordTask(rid));
ODistributedResponse response = dManager.sendRequest(databaseName, clusterNames, nonLocalServers, tx, requestId.getMessageId(), ODistributedRequest.EXECUTION_MODE.RESPONSE, localResult, null);
// MAP OF OCompletedTxTask SERVER/RECORDS. RECORD == NULL MEANS DELETE
final Map<String, OCompleted2pcTask> repairMap = new HashMap<String, OCompleted2pcTask>(rids.size());
for (String server : involvedServers) {
final OCompleted2pcTask completedTask = new OCompleted2pcTask(requestId, false, tx.getPartitionKey());
repairMap.put(server, completedTask);
}
try {
if (response != null) {
final Object payload = response.getPayload();
if (payload instanceof Map) {
final Map<String, Object> map = (Map<String, Object>) payload;
// BROWSE FROM LOCAL RESULT
for (int i = 0; i < localResult.results.size(); ++i) {
final Map<Object, List<String>> groupedResult = new HashMap<Object, List<String>>();
final ORecordId rid = rids.get(i);
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (entry.getValue() instanceof Throwable) {
// ABORT IT
ODistributedServerLog.info(this, dManager.getLocalNodeName(), entry.getKey(), ODistributedServerLog.DIRECTION.IN, "Error on auto repairing record %s on servers %s (error=%s)", rid, entry.getKey(), entry.getValue());
return false;
}
final OTxTaskResult v = (OTxTaskResult) entry.getValue();
final Object remoteValue = v.results.get(i);
List<String> group = groupedResult.get(remoteValue);
if (group == null) {
group = new ArrayList<String>();
groupedResult.put(remoteValue, group);
}
group.add(entry.getKey());
}
if (groupedResult.size() == 1)
// NO CONFLICT, SKIP IT
continue;
ODocument config = null;
// EXECUTE THE CONFLICT RESOLVE PIPELINE: CONTINUE UNTIL THE WINNER IS NOT NULL (=RESOLVED)
Object winner = null;
Map<Object, List<String>> candidates = groupedResult;
for (ODistributedConflictResolver conflictResolver : conflictResolvers) {
final ODistributedConflictResolver.OConflictResult conflictResult = conflictResolver.onConflict(databaseName, db.getClusterNameById(rid.getClusterId()), rid, dManager, candidates, config);
winner = conflictResult.winner;
if (winner != null)
// FOUND WINNER
break;
candidates = conflictResult.candidates;
}
if (winner == null)
// NO WINNER, SKIP IT
continue;
for (Map.Entry<Object, List<String>> entry : groupedResult.entrySet()) {
final Object value = entry.getKey();
final List<String> servers = entry.getValue();
for (String server : servers) {
ODistributedServerLog.debug(this, dManager.getLocalNodeName(), server, ODistributedServerLog.DIRECTION.OUT, "Preparing fix for record %s on servers %s, value=%s...", rid, server, winner);
if (!winner.equals(value)) {
final OCompleted2pcTask completedTask = repairMap.get(server);
if (winner instanceof ORawBuffer && value instanceof ORawBuffer) {
// UPDATE THE RECORD
final ORawBuffer winnerRecord = (ORawBuffer) winner;
completedTask.addFixTask(new OFixUpdateRecordTask(rid, winnerRecord.buffer, ORecordVersionHelper.setRollbackMode(winnerRecord.version), winnerRecord.recordType));
} else if (winner instanceof ORecordNotFoundException && value instanceof ORawBuffer) {
// DELETE THE RECORD
completedTask.addFixTask(new OFixCreateRecordTask(rid, -1));
} else if (value instanceof Throwable) {
// MANAGE EXCEPTION
}
}
}
}
}
}
}
} finally {
int repaired = 0;
for (Map.Entry<String, OCompleted2pcTask> entry : repairMap.entrySet()) {
final String server = entry.getKey();
final OCompleted2pcTask task = entry.getValue();
repaired += task.getFixTasks().size();
if (dManager.getLocalNodeName().equals(server))
// EXECUTE IT LOCALLY
dManager.executeOnLocalNode(requestId, task, db);
else {
// EXECUTE REMOTELY
final List<String> servers = new ArrayList<String>();
servers.add(server);
// FILTER ONLY THE SERVER ONLINE
dManager.getAvailableNodes(servers, databaseName);
if (!servers.isEmpty()) {
response = dManager.sendRequest(databaseName, clusterNames, servers, task, dManager.getNextMessageIdCounter(), ODistributedRequest.EXECUTION_MODE.RESPONSE, null, null);
}
}
}
if (repaired == 0)
ODistributedServerLog.debug(this, dManager.getLocalNodeName(), involvedServers.toString(), ODistributedServerLog.DIRECTION.OUT, "Auto repairing completed. No fix is needed (reqId=%s)", repaired, requestId);
else
ODistributedServerLog.info(this, dManager.getLocalNodeName(), involvedServers.toString(), ODistributedServerLog.DIRECTION.OUT, "Auto repairing completed. Sent %d fix messages for %d records (reqId=%s)", repaired, rids.size(), requestId);
}
} finally {
// RELEASE LOCKS AND REMOVE TX CONTEXT
localDistributedDatabase.popTxContext(requestId);
ctx.destroy();
}
} catch (Throwable e) {
ODistributedServerLog.debug(this, dManager.getLocalNodeName(), null, ODistributedServerLog.DIRECTION.NONE, "Error executing auto repairing (error=%s, reqId=%s)", e.toString(), requestId);
return false;
}
return true;
}
use of com.orientechnologies.orient.core.storage.ORawBuffer in project orientdb by orientechnologies.
the class AbstractServerClusterTest method readRemoteRecord.
protected ODocument readRemoteRecord(final int serverId, final ORecordId rid, final String[] servers) {
final ODistributedServerManager dManager = serverInstance.get(serverId).getServerInstance().getDistributedManager();
final Collection<String> clusterNames = new ArrayList<String>(1);
clusterNames.add(ODatabaseRecordThreadLocal.INSTANCE.get().getClusterNameById(rid.getClusterId()));
ODistributedResponse response = dManager.sendRequest(getDatabaseName(), clusterNames, Arrays.asList(servers), new OReadRecordTask(rid), dManager.getNextMessageIdCounter(), ODistributedRequest.EXECUTION_MODE.RESPONSE, null, null);
if (response != null) {
final ORawBuffer buffer = (ORawBuffer) response.getPayload();
return new ODocument().fromStream(buffer.getBuffer());
}
return null;
}
Aggregations