com.aerospike.client.blob.BlobFinder Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2012-2023 Aerospike, Inc.
*
* Portions may be licensed to Aerospike, Inc. under one or more contributor
* license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0.
*
* 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.
*/
package com.aerospike.client.blob;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.aerospike.client.AerospikeClient;
import com.aerospike.client.AerospikeException;
import com.aerospike.client.Host;
import com.aerospike.client.IAerospikeClient;
import com.aerospike.client.Key;
import com.aerospike.client.Record;
import com.aerospike.client.ScanCallback;
import com.aerospike.client.cluster.Cluster;
import com.aerospike.client.cluster.Partitions;
import com.aerospike.client.command.Buffer;
import com.aerospike.client.command.ParticleType;
import com.aerospike.client.policy.ClientPolicy;
import com.aerospike.client.policy.ScanPolicy;
/**
* Find language specific blobs and display counts to the console.
* Optionally, write each bin that contains a language specific blob.
*/
public final class BlobFinder implements ScanCallback {
public static BlobFinder INSTANCE;
/**
* Find language specific blobs and display counts to the console.
* If path is not null, write each bin that contains a language specific blob(s) to that
* file path.
*
* File format:
* {@code
* Blob bins:
* ,,,,
*
* List/Map bins (list and map entries can contain blobs):
* ,,,,,,,
*
* bin type: jblob | cblob | pblob | list | map
*
* jblobs: count of java blobs in the list or map entries
* cblobs: count of C# blobs in the list or map entries
* pblobs: count of python blobs in the list or map entries
* }
*
* @param bfp BlobFinder configuration variables.
*/
public static void run(BlobFinderPolicy bfp) {
ClientPolicy cp = new ClientPolicy();
cp.user = bfp.user;
cp.password = bfp.password;
cp.authMode = bfp.authMode;
cp.tlsPolicy = bfp.tlsPolicy;
Host[] hosts = Host.parseHosts(bfp.host, bfp.port);
AerospikeClient client = new AerospikeClient(cp, hosts);
try {
INSTANCE = new BlobFinder(client, bfp);
INSTANCE.run();
}
finally {
client.close();
}
}
private final BlobFinderPolicy bfp;
private final IAerospikeClient client;
private final StringBuilder sb;
private final FileWriter writer;
private String namespace;
private long recCount;
private long javaBlobs;
private long csharpBlobs;
private long pythonBlobs;
public BlobFinder(IAerospikeClient client, BlobFinderPolicy bfp) {
this.client = client;
this.bfp = bfp;
if (bfp.outputFile != null) {
this.sb = new StringBuilder(8192);
try {
this.writer = new FileWriter(bfp.outputFile, false);
}
catch (IOException ioe) {
throw new AerospikeException(ioe);
}
}
else {
this.sb = null;
this.writer = null;
}
}
public void run() {
List namespaces;
if (bfp.namespace != null) {
namespaces = new ArrayList<>(1);
namespaces.add(bfp.namespace);
}
else {
Cluster cluster = client.getCluster();
HashMap pmap = cluster.partitionMap;
namespaces = new ArrayList<>(pmap.size());
for (String ns : pmap.keySet()) {
namespaces.add(ns);
}
}
// Set concurrentNodes to false, so atomics are not required in the scan callback.
ScanPolicy policy = new ScanPolicy();
policy.concurrentNodes = false;
policy.recordsPerSecond = bfp.recordsPerSecond;
policy.socketTimeout = bfp.socketTimeout;
for (String ns : namespaces) {
this.namespace = ns;
System.out.println("Scan " + ns);
client.scanAll(policy, ns, null, this);
}
displayRunningTotal();
if (sb != null) {
try {
writer.close();
}
catch (IOException ioe) {
throw new AerospikeException(ioe);
}
}
}
@Override
public void scanCallback(Key key, Record record) {
recCount++;
if (recCount % bfp.displayAfterRecs == 0) {
displayRunningTotal();
}
}
private void displayRunningTotal() {
System.out.println("recs=" + recCount +
" jblobs=" + javaBlobs +
" cblobs=" + csharpBlobs +
" pblobs=" + pythonBlobs
);
}
/**
* Write language specific blob bin.
*
* @param digest key digest
* @param binName bin name
* @param type particle type integer
* 7: Java blob
* 8: C# blob
* 9: Python blob
*/
public void writeBin(Key key, String binName, int type) {
String btype = null;
switch (type) {
case ParticleType.JBLOB:
btype = "jblob";
this.javaBlobs++;
break;
case ParticleType.CSHARP_BLOB:
btype = "cblob";
this.csharpBlobs++;
break;
case ParticleType.PYTHON_BLOB:
btype = "pblob";
this.pythonBlobs++;
break;
}
if (sb == null) {
return;
}
sb.setLength(0);
sb.append(namespace);
sb.append(',');
sb.append(key.setName);
sb.append(',');
sb.append(Buffer.bytesToHexString(key.digest));
sb.append(',');
sb.append(binName);
sb.append(',');
sb.append(btype);
writeLine();
}
/**
* Write blob counts that occurred in a list or map bin.
*
* @param digest key digest
* @param binName bin name
* @param type "list" or "map"
* @param javaCount count of java blobs in list or map bin.
* @param csharpCount count of csharp blobs in list or map bin.
* @param pythonCount count of python blobs in list or map bin.
*/
public void writeListMap (
Key key,
String binName,
String type,
int javaBlobs,
int csharpBlobs,
int pythonBlobs
) {
this.javaBlobs += javaBlobs;
this.csharpBlobs += csharpBlobs;
this.pythonBlobs += pythonBlobs;
if (sb == null) {
return;
}
sb.setLength(0);
sb.append(namespace);
sb.append(',');
sb.append(key.setName);
sb.append(',');
sb.append(Buffer.bytesToHexString(key.digest));
sb.append(',');
sb.append(binName);
sb.append(',');
sb.append(type);
sb.append(',');
sb.append(javaBlobs);
sb.append(',');
sb.append(csharpBlobs);
sb.append(',');
sb.append(pythonBlobs);
writeLine();
}
private void writeLine() {
try {
sb.append(System.lineSeparator());
writer.write(sb.toString());
writer.flush();
}
catch (IOException ioe) {
try {
writer.close();
}
catch (Throwable t) {
}
throw new AerospikeException(ioe);
}
}
}