/** * Copyright 2013-2015 Seagate Technology LLC. * * This Source Code Form is subject to the terms of the Mozilla * Public License, v. 2.0. If a copy of the MPL was not * distributed with this file, You can obtain one at * https://mozilla.org/MP:/2.0/. * * This program is distributed in the hope that it will be useful, * but is provided AS-IS, WITHOUT ANY WARRANTY; including without * the implied warranty of MERCHANTABILITY, NON-INFRINGEMENT or * FITNESS FOR A PARTICULAR PURPOSE. See the Mozilla Public * License for more details. * * See www.openkinetic.org for more project information */ package com.seagate.kinetic.batchOp; import java.util.Random; import java.util.concurrent.atomic.AtomicLong; import kinetic.client.AsyncKineticException; import kinetic.client.BatchOperation; import kinetic.client.CallbackHandler; import kinetic.client.CallbackResult; import kinetic.client.Entry; import kinetic.client.KineticException; import kinetic.client.advanced.AdvancedKineticClient; import kinetic.client.advanced.PersistOption; abstract class BatchTestThread extends Thread { protected static final int MAX_VALUE_SIZE_IN_KB = 1024; protected static final int MAX_BATCH_COUNT_MINUS_ONE = 14; protected static final int DEFAULT_ROUNDS = 1; protected final AdvancedKineticClient kineticClient; protected boolean stop = false; protected Random random = new Random(); protected BatchTestThread(String name, AdvancedKineticClient kineticClient) { super(name); this.kineticClient = kineticClient; } @Override public void run() { while (!stop) { loopTask(); } } public void shutdown() { stop = true; } abstract void loopTask(); } class BatchPutDeleteThread extends BatchTestThread { public BatchPutDeleteThread(String name, AdvancedKineticClient kineticClient) { super(name, kineticClient); } @Override void loopTask() { try { BatchOperation batch = null; Entry entry = null; byte[] key = null; byte[] value = null; int rounds = random.nextInt(DEFAULT_ROUNDS) + 1; int operations = random.nextInt(MAX_BATCH_COUNT_MINUS_ONE) + 1; for (int i = 0; i < rounds; i++) { batch = kineticClient.createBatchOperation(); for (int j = 0; j < operations; j++) { key = (this.getName() + i + "_" + j).getBytes(); value = new byte[(random.nextInt(MAX_VALUE_SIZE_IN_KB) + 1) << 10]; entry = new Entry(key, value); batch.putForced(entry); } batch.commit(); batch = kineticClient.createBatchOperation(); for (int j = 0; j < operations; j++) { key = (this.getName() + i + "_" + j).getBytes(); batch.deleteForced(key); } batch.commit(); } } catch (KineticException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } class PureBatchPutThread extends BatchTestThread { private static final int ONE_MEGA = 1048576; private static AtomicLong totalPutInBytes = new AtomicLong(0); private byte[] ONE_MEGA_VALUE = new byte[ONE_MEGA]; // Once enabling stat, data size will be set as 1M. private boolean enableStat = false; public PureBatchPutThread(String name, AdvancedKineticClient kineticClient) { super(name, kineticClient); } public PureBatchPutThread(String name, AdvancedKineticClient kineticClient, boolean enableStat) { super(name, kineticClient); this.enableStat = enableStat; } public static long totalPutBytes() { return totalPutInBytes.get(); } @Override void loopTask() { try { BatchOperation batch = null; Entry entry = null; byte[] key = null; byte[] value = null; int rounds = random.nextInt(DEFAULT_ROUNDS) + 1; int operations = enableStat ? (MAX_BATCH_COUNT_MINUS_ONE + 1) : random.nextInt(MAX_BATCH_COUNT_MINUS_ONE) + 1; for (int i = 0; i < rounds; i++) { batch = kineticClient.createBatchOperation(); for (int j = 0; j < operations; j++) { key = (this.getName() + i + "_" + j).getBytes(); if (enableStat) { value = ONE_MEGA_VALUE; } else { value = new byte[((random.nextInt(MAX_VALUE_SIZE_IN_KB) + 1) << 10)]; } entry = new Entry(key, value); batch.putForced(entry); } batch.commit(); if (enableStat) totalPutInBytes.getAndAdd(operations * ONE_MEGA); } } catch (KineticException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } class BatchPutGetThread extends BatchTestThread { public BatchPutGetThread(String name, AdvancedKineticClient kineticClient) { super(name, kineticClient); } @Override void loopTask() { try { BatchOperation batch = null; Entry entry = null; byte[] key = null; byte[] value = null; int rounds = random.nextInt(DEFAULT_ROUNDS) + 1; int operations = random.nextInt(MAX_BATCH_COUNT_MINUS_ONE) + 1; int values_size[] = new int[operations]; for (int i = 0; i < rounds; i++) { batch = kineticClient.createBatchOperation(); for (int j = 0; j < operations; j++) { key = (this.getName() + i + "_" + j).getBytes(); value = new byte[(random.nextInt(MAX_VALUE_SIZE_IN_KB) + 1) << 10]; values_size[j] = value.length; entry = new Entry(key, value); batch.putForced(entry); } batch.commit(); for (int j = 0; j < operations; j++) { key = (this.getName() + i + "_" + j).getBytes(); entry = kineticClient.get(key); if (values_size[j] != entry.getValue().length) { throw new KineticException("wrong value size"); } } } } catch (KineticException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } class PurePutThread extends BatchTestThread { private static final int ONE_MEGA = 1048576; private static AtomicLong totalPutInBytes = new AtomicLong(0); // Once enabling stat, data size will be set as 1M. private boolean enableStat = false; private byte[] ONE_MEGA_VALUE = new byte[ONE_MEGA]; public PurePutThread(String name, AdvancedKineticClient kineticClient) { super(name, kineticClient); } public PurePutThread(String name, AdvancedKineticClient kineticClient, boolean enableStat) { super(name, kineticClient); this.enableStat = enableStat; } public static long totalPutBytes() { return totalPutInBytes.get(); } @Override void loopTask() { Entry entry = null; byte[] key = null; byte[] value = null; int rounds = random.nextInt(DEFAULT_ROUNDS) + 1; int operations = enableStat ? (MAX_BATCH_COUNT_MINUS_ONE + 1) : random .nextInt(MAX_BATCH_COUNT_MINUS_ONE) + 1; for (int i = 0; i < rounds; i++) { for (int j = 0; j < operations; j++) { key = (this.getName() + i + "_" + j).getBytes(); if (enableStat) { value = ONE_MEGA_VALUE; } else { value = new byte[((random.nextInt(MAX_VALUE_SIZE_IN_KB) + 1) << 10)]; } entry = new Entry(key, value); try { if (enableStat) { kineticClient.putForced(entry, PersistOption.ASYNC); // kineticClient.putForcedAsync(entry, handler); } else { kineticClient.putForced(entry); } } catch (KineticException e) { e.printStackTrace(); } finally { if (enableStat) totalPutInBytes.getAndAdd(ONE_MEGA); } } } } class MyPutCallbackHandler implements CallbackHandler<Entry> { @Override public void onSuccess(CallbackResult<Entry> result) { totalPutInBytes.getAndAdd(ONE_MEGA); } @Override public void onError(AsyncKineticException exception) { totalPutInBytes.getAndAdd(ONE_MEGA); } } } class PutBatchDeleteThread extends BatchTestThread { public PutBatchDeleteThread(String name, AdvancedKineticClient kineticClient) { super(name, kineticClient); } @Override void loopTask() { BatchOperation batch = null; Entry entry = null; byte[] key = null; byte[] value = null; int rounds = random.nextInt(DEFAULT_ROUNDS) + 1; int operations = random.nextInt(MAX_BATCH_COUNT_MINUS_ONE) + 1; for (int i = 0; i < rounds; i++) { for (int j = 0; j < operations; j++) { key = (this.getName() + i + "_" + j).getBytes(); value = new byte[(random.nextInt(MAX_VALUE_SIZE_IN_KB) + 1) << 10]; entry = new Entry(key, value); try { kineticClient.putForced(entry); } catch (KineticException e) { e.printStackTrace(); } } try { batch = kineticClient.createBatchOperation(); for (int j = 0; j < operations; j++) { key = (this.getName() + i + "_" + j).getBytes(); batch.deleteForced(key); } batch.commit(); } catch (KineticException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }