Constructor and Description |
---|
FrameMetadata(DataCharacteristics dataCharacteristics)
Constructor to create a FrameMetadata object based on a
DataCharacteristics object.
|
MatrixMetadata(DataCharacteristics dataCharacteristics)
Constructor to create a MatrixMetadata object based on a
DataCharacteristics object.
|
Modifier and Type | Method and Description |
---|---|
DataCharacteristics[] |
MemoTable.getAllInputStats(ArrayList<Hop> inputs) |
DataCharacteristics |
MemoTable.getAllInputStats(Hop input) |
DataCharacteristics |
Hop.getDataCharacteristics() |
Modifier and Type | Method and Description |
---|---|
static boolean |
OptimizerUtils.checkSparkCollectMemoryBudget(DataCharacteristics dc,
long memPinned) |
static boolean |
OptimizerUtils.checkSparkCollectMemoryBudget(DataCharacteristics dc,
long memPinned,
boolean checkBP) |
static boolean |
OptimizerUtils.checkSparseBlockCSRConversion(DataCharacteristics dcIn) |
static long |
OptimizerUtils.estimatePartitionedSizeExactSparsity(DataCharacteristics dc)
Estimates the footprint (in bytes) for a partitioned in-memory representation of a
matrix with the given matrix characteristics
|
static long |
OptimizerUtils.estimateSize(DataCharacteristics dc) |
static long |
OptimizerUtils.estimateSizeExactSparsity(DataCharacteristics dc) |
static double |
OptimizerUtils.getSparsity(DataCharacteristics dc) |
static boolean |
OptimizerUtils.isIndexingRangeBlockAligned(IndexRange ixrange,
DataCharacteristics mc)
Indicates if the given indexing range is block aligned, i.e., it does not require
global aggregation of blocks.
|
static boolean |
OptimizerUtils.isValidCPDimensions(DataCharacteristics mc) |
void |
MemoTable.memoizeStatistics(long hopID,
DataCharacteristics dc) |
Modifier and Type | Method and Description |
---|---|
static DataCharacteristics |
EstimatorMatrixHistogram.MatrixHistogram.deriveOutputCharacteristics(EstimatorMatrixHistogram.MatrixHistogram h1,
EstimatorMatrixHistogram.MatrixHistogram h2,
double spOut,
SparsityEstimator.OpCode op,
long[] misc) |
DataCharacteristics |
EstimatorBitsetMM.estim(MMNode root) |
DataCharacteristics |
EstimatorMatrixHistogram.estim(MMNode root) |
DataCharacteristics |
EstimatorDensityMap.estim(MMNode root) |
DataCharacteristics |
EstimatorSample.estim(MMNode root) |
DataCharacteristics |
EstimatorBasicWorst.estim(MMNode root) |
DataCharacteristics |
EstimatorBasicAvg.estim(MMNode root) |
DataCharacteristics |
EstimatorLayeredGraph.estim(MMNode root) |
DataCharacteristics |
EstimatorSampleRa.estim(MMNode root) |
abstract DataCharacteristics |
SparsityEstimator.estim(MMNode root)
Estimates the output sparsity of a DAG of matrix multiplications
for the given operator graph of a single root node.
|
DataCharacteristics |
EstimatorMatrixHistogram.estim(MMNode root,
boolean topLevel) |
DataCharacteristics |
MMNode.getDataCharacteristics() |
DataCharacteristics |
MMNode.setDataCharacteristics(DataCharacteristics mc) |
Modifier and Type | Method and Description |
---|---|
DataCharacteristics |
MMNode.setDataCharacteristics(DataCharacteristics mc) |
Modifier and Type | Method and Description |
---|---|
HashMap<String,DataCharacteristics> |
RecompileStatus.getTWriteStats() |
Modifier and Type | Method and Description |
---|---|
static boolean |
Recompiler.checkCPCheckpoint(DataCharacteristics dc) |
Modifier and Type | Method and Description |
---|---|
static long |
HopRewriteUtils.getMaxInputDim(DataCharacteristics[] dc,
boolean dim1) |
static long |
HopRewriteUtils.getSumValidInputDims(DataCharacteristics[] mc,
boolean dim1) |
static long |
HopRewriteUtils.getSumValidInputNnz(DataCharacteristics[] mc,
boolean worstcase) |
static boolean |
HopRewriteUtils.hasValidInputDims(DataCharacteristics[] mc,
boolean dim1) |
static boolean |
HopRewriteUtils.hasValidInputNnz(DataCharacteristics[] mc,
boolean worstcase) |
Modifier and Type | Method and Description |
---|---|
void |
OutputParameters.setDimensions(DataCharacteristics dc) |
Modifier and Type | Method and Description |
---|---|
long |
ParForProgramBlock.PartitionFormat.getNumColumns(DataCharacteristics mc) |
long |
ParForProgramBlock.PartitionFormat.getNumParts(DataCharacteristics mc) |
long |
ParForProgramBlock.PartitionFormat.getNumRows(DataCharacteristics mc) |
Modifier and Type | Method and Description |
---|---|
DataCharacteristics |
CacheableData.getDataCharacteristics() |
Modifier and Type | Method and Description |
---|---|
void |
MatrixObject.updateDataCharacteristics(DataCharacteristics dc) |
Modifier and Type | Method and Description |
---|---|
DataCharacteristics |
ExecutionContext.getDataCharacteristics(String varname) |
Modifier and Type | Method and Description |
---|---|
static TensorBlock |
SparkExecutionContext.toTensorBlock(org.apache.spark.api.java.JavaPairRDD<TensorIndexes,TensorBlock> rdd,
DataCharacteristics dc) |
Constructor and Description |
---|
DataPartitionerRemoteSparkMapper(DataCharacteristics mc,
Types.FileFormat fmt,
ParForProgramBlock.PDataPartitionFormat dpf,
int n) |
RemoteDPParForSparkWorker(String program,
HashMap<String,byte[]> clsMap,
String inputVar,
String iterVar,
boolean cpCaching,
DataCharacteristics mc,
boolean tSparseCol,
ParForProgramBlock.PartitionFormat dpf,
Types.FileFormat fmt,
org.apache.spark.util.LongAccumulator atasks,
org.apache.spark.util.LongAccumulator aiters) |
Modifier and Type | Method and Description |
---|---|
static List<IndexedTensorBlock> |
LibTensorReorg.reshape(IndexedTensorBlock in,
DataCharacteristics mcIn,
DataCharacteristics mcOut,
boolean rowwise,
boolean outputEmptyBlocks)
MR/SPARK reshape interface - for reshape we cannot view blocks independently, and hence,
there are different CP and MR interfaces.
|
Modifier and Type | Method and Description |
---|---|
boolean |
ReduceAll.computeDimension(DataCharacteristics in,
DataCharacteristics out) |
boolean |
SortIndex.computeDimension(DataCharacteristics in,
DataCharacteristics out) |
boolean |
RevIndex.computeDimension(DataCharacteristics in,
DataCharacteristics out) |
boolean |
OffsetColumnIndex.computeDimension(DataCharacteristics in,
DataCharacteristics out) |
boolean |
DiagIndex.computeDimension(DataCharacteristics in,
DataCharacteristics out) |
boolean |
SwapIndex.computeDimension(DataCharacteristics in,
DataCharacteristics out) |
boolean |
ReduceRow.computeDimension(DataCharacteristics in,
DataCharacteristics out) |
abstract boolean |
IndexFunction.computeDimension(DataCharacteristics in,
DataCharacteristics out) |
boolean |
ReduceDiag.computeDimension(DataCharacteristics in,
DataCharacteristics out) |
boolean |
ReduceCol.computeDimension(DataCharacteristics in,
DataCharacteristics out) |
Modifier and Type | Method and Description |
---|---|
static Instruction |
VariableCPInstruction.prepCreatevarInstruction(String varName,
String fileName,
boolean fNameOverride,
Types.DataType dt,
String format,
DataCharacteristics mc,
MatrixObject.UpdateType update) |
static Instruction |
VariableCPInstruction.prepCreatevarInstruction(String varName,
String fileName,
boolean fNameOverride,
Types.DataType dt,
String format,
DataCharacteristics mc,
MatrixObject.UpdateType update,
boolean hasHeader,
String delim,
boolean sparse) |
void |
Data.updateDataCharacteristics(DataCharacteristics mc) |
Modifier and Type | Method and Description |
---|---|
static MatrixBlock |
MatrixIndexingSPInstruction.inmemoryIndexing(org.apache.spark.api.java.JavaPairRDD<MatrixIndexes,MatrixBlock> in1,
DataCharacteristics mcIn,
DataCharacteristics mcOut,
IndexRange ixrange) |
static boolean |
MatrixIndexingSPInstruction.isMultiBlockLookup(org.apache.spark.api.java.JavaPairRDD<?,?> in,
DataCharacteristics mcIn,
DataCharacteristics mcOut,
IndexRange ixrange)
Indicates if the given index range and input matrix exhibit the following properties:
(1) existing hash partitioner, (2) out-of-core input matrix (larger than aggregated memory),
(3) aligned indexing range (which does not required aggregation), and (4) the output fits
twice in memory (in order to collect the result).
|
static boolean |
MatrixIndexingSPInstruction.isSingleBlockLookup(DataCharacteristics mcIn,
IndexRange ixrange)
Indicates if the given index range only covers a single blocks of the inputs matrix.
|
void |
ParameterizedBuiltinSPInstruction.setOutputCharacteristicsForGroupedAgg(DataCharacteristics mc1,
DataCharacteristics mcOut,
org.apache.spark.api.java.JavaPairRDD<MatrixIndexes,MatrixCell> out) |
Constructor and Description |
---|
MergeWithShiftedBlocks(DataCharacteristics mc1,
DataCharacteristics mc2,
boolean cbind) |
PadBlocksFunction(DataCharacteristics mcOut) |
ShiftMatrix(DataCharacteristics mc1,
DataCharacteristics mc2,
boolean cbind) |
Modifier and Type | Method and Description |
---|---|
DataCharacteristics |
PartitionedBroadcast.getDataCharacteristics() |
Constructor and Description |
---|
BlockPartitioner(DataCharacteristics mc,
int numParts) |
PartitionedBroadcast(org.apache.spark.broadcast.Broadcast<PartitionedBlock<T>>[] broadcasts,
DataCharacteristics dc) |
Constructor and Description |
---|
ExtractBlockForBinaryReblock(DataCharacteristics mcIn,
DataCharacteristics mcOut) |
IsBlockInList(long[] cols,
DataCharacteristics mc) |
IsBlockInRange(long rl,
long ru,
long cl,
long cu,
DataCharacteristics mc) |
IsFrameBlockInRange(long rl,
long ru,
DataCharacteristics mcOut) |
Modifier and Type | Method and Description |
---|---|
static DataCharacteristics |
SparkUtils.computeDataCharacteristics(org.apache.spark.api.java.JavaPairRDD<MatrixIndexes,MatrixCell> input)
Utility to compute dimensions and non-zeros in a given RDD of binary cells.
|
Modifier and Type | Method and Description |
---|---|
static org.apache.spark.api.java.JavaRDD<String> |
FrameRDDConverterUtils.binaryBlockToCsv(org.apache.spark.api.java.JavaPairRDD<Long,FrameBlock> in,
DataCharacteristics mcIn,
FileFormatPropertiesCSV props,
boolean strict) |
static org.apache.spark.api.java.JavaRDD<String> |
RDDConverterUtils.binaryBlockToCsv(org.apache.spark.api.java.JavaPairRDD<MatrixIndexes,MatrixBlock> in,
DataCharacteristics mcIn,
FileFormatPropertiesCSV props,
boolean strict) |
static org.apache.spark.sql.Dataset<org.apache.spark.sql.Row> |
FrameRDDConverterUtils.binaryBlockToDataFrame(org.apache.spark.sql.SparkSession sparkSession,
org.apache.spark.api.java.JavaPairRDD<Long,FrameBlock> in,
DataCharacteristics mc,
Types.ValueType[] schema) |
static org.apache.spark.sql.Dataset<org.apache.spark.sql.Row> |
RDDConverterUtils.binaryBlockToDataFrame(org.apache.spark.sql.SparkSession sparkSession,
org.apache.spark.api.java.JavaPairRDD<MatrixIndexes,MatrixBlock> in,
DataCharacteristics mc,
boolean toVector) |
static org.apache.spark.sql.Dataset<org.apache.spark.sql.Row> |
FrameRDDConverterUtils.binaryBlockToDataFrame(org.apache.spark.sql.SQLContext sqlContext,
org.apache.spark.api.java.JavaPairRDD<Long,FrameBlock> in,
DataCharacteristics mc,
Types.ValueType[] schema)
Deprecated.
|
static org.apache.spark.sql.Dataset<org.apache.spark.sql.Row> |
RDDConverterUtils.binaryBlockToDataFrame(org.apache.spark.sql.SQLContext sqlContext,
org.apache.spark.api.java.JavaPairRDD<MatrixIndexes,MatrixBlock> in,
DataCharacteristics mc,
boolean toVector)
Deprecated.
|
static org.apache.spark.api.java.JavaPairRDD<MatrixIndexes,MatrixBlock> |
FrameRDDConverterUtils.binaryBlockToMatrixBlock(org.apache.spark.api.java.JavaPairRDD<Long,FrameBlock> input,
DataCharacteristics mcIn,
DataCharacteristics mcOut) |
static org.apache.spark.api.java.JavaRDD<String> |
FrameRDDConverterUtils.binaryBlockToTextCell(org.apache.spark.api.java.JavaPairRDD<Long,FrameBlock> input,
DataCharacteristics mcIn) |
static org.apache.spark.api.java.JavaRDD<String> |
RDDConverterUtils.binaryBlockToTextCell(org.apache.spark.api.java.JavaPairRDD<MatrixIndexes,MatrixBlock> in,
DataCharacteristics mc) |
static org.apache.spark.api.java.JavaPairRDD<MatrixIndexes,MatrixBlock> |
RDDConverterUtils.binaryCellToBinaryBlock(org.apache.spark.api.java.JavaSparkContext sc,
org.apache.spark.api.java.JavaPairRDD<MatrixIndexes,MatrixCell> input,
DataCharacteristics mcOut,
boolean outputEmptyBlocks) |
static org.apache.spark.api.java.JavaPairRDD<MatrixIndexes,MatrixBlock> |
RDDConverterUtilsExt.coordinateMatrixToBinaryBlock(org.apache.spark.api.java.JavaSparkContext sc,
org.apache.spark.mllib.linalg.distributed.CoordinateMatrix input,
DataCharacteristics mcIn,
boolean outputEmptyBlocks) |
static org.apache.spark.api.java.JavaPairRDD<MatrixIndexes,MatrixBlock> |
RDDConverterUtilsExt.coordinateMatrixToBinaryBlock(org.apache.spark.SparkContext sc,
org.apache.spark.mllib.linalg.distributed.CoordinateMatrix input,
DataCharacteristics mcIn,
boolean outputEmptyBlocks) |
static org.apache.spark.api.java.JavaPairRDD<MatrixIndexes,MatrixBlock> |
RDDConverterUtils.csvToBinaryBlock(org.apache.spark.api.java.JavaSparkContext sc,
org.apache.spark.api.java.JavaPairRDD<org.apache.hadoop.io.LongWritable,org.apache.hadoop.io.Text> input,
DataCharacteristics mc,
boolean hasHeader,
String delim,
boolean fill,
double fillValue,
Set<String> naStrings) |
static org.apache.spark.api.java.JavaPairRDD<Long,FrameBlock> |
FrameRDDConverterUtils.csvToBinaryBlock(org.apache.spark.api.java.JavaSparkContext sc,
org.apache.spark.api.java.JavaPairRDD<org.apache.hadoop.io.LongWritable,org.apache.hadoop.io.Text> input,
DataCharacteristics mc,
Types.ValueType[] schema,
boolean hasHeader,
String delim,
boolean fill,
double fillValue,
Set<String> naStrings) |
static org.apache.spark.api.java.JavaPairRDD<MatrixIndexes,MatrixBlock> |
RDDConverterUtils.csvToBinaryBlock(org.apache.spark.api.java.JavaSparkContext sc,
org.apache.spark.api.java.JavaRDD<String> input,
DataCharacteristics mcOut,
boolean hasHeader,
String delim,
boolean fill,
double fillValue,
Set<String> naStrings) |
static org.apache.spark.api.java.JavaPairRDD<Long,FrameBlock> |
FrameRDDConverterUtils.csvToBinaryBlock(org.apache.spark.api.java.JavaSparkContext sc,
org.apache.spark.api.java.JavaRDD<String> input,
DataCharacteristics mcOut,
Types.ValueType[] schema,
boolean hasHeader,
String delim,
boolean fill,
double fillValue,
Set<String> naStrings) |
static org.apache.spark.api.java.JavaPairRDD<Long,FrameBlock> |
FrameRDDConverterUtils.dataFrameToBinaryBlock(org.apache.spark.api.java.JavaSparkContext sc,
org.apache.spark.sql.Dataset<org.apache.spark.sql.Row> df,
DataCharacteristics mc,
boolean containsID) |
static org.apache.spark.api.java.JavaPairRDD<MatrixIndexes,MatrixBlock> |
RDDConverterUtils.dataFrameToBinaryBlock(org.apache.spark.api.java.JavaSparkContext sc,
org.apache.spark.sql.Dataset<org.apache.spark.sql.Row> df,
DataCharacteristics mc,
boolean containsID,
boolean isVector) |
static org.apache.spark.api.java.JavaPairRDD<Long,FrameBlock> |
FrameRDDConverterUtils.dataFrameToBinaryBlock(org.apache.spark.api.java.JavaSparkContext sc,
org.apache.spark.sql.Dataset<org.apache.spark.sql.Row> df,
DataCharacteristics mc,
boolean containsID,
Pair<String[],Types.ValueType[]> out) |
static org.apache.spark.api.java.JavaPairRDD<MatrixIndexes,MatrixBlock> |
SparkUtils.getEmptyBlockRDD(org.apache.spark.api.java.JavaSparkContext sc,
DataCharacteristics mc)
Creates an RDD of empty blocks according to the given matrix characteristics.
|
static int |
SparkUtils.getNumPreferredPartitions(DataCharacteristics dc) |
static int |
SparkUtils.getNumPreferredPartitions(DataCharacteristics dc,
org.apache.spark.api.java.JavaPairRDD<?,?> in) |
static void |
RDDConverterUtils.libsvmToBinaryBlock(org.apache.spark.api.java.JavaSparkContext sc,
String pathIn,
String pathX,
String pathY,
DataCharacteristics mcOutX)
Converts a libsvm text input file into two binary block matrices for features
and labels, and saves these to the specified output files.
|
static org.apache.spark.api.java.JavaPairRDD<org.apache.hadoop.io.LongWritable,FrameBlock> |
FrameRDDConverterUtils.matrixBlockToBinaryBlock(org.apache.spark.api.java.JavaSparkContext sc,
org.apache.spark.api.java.JavaPairRDD<MatrixIndexes,MatrixBlock> input,
DataCharacteristics mcIn) |
static org.apache.spark.api.java.JavaPairRDD<Long,FrameBlock> |
FrameRDDConverterUtils.matrixBlockToBinaryBlockLongIndex(org.apache.spark.api.java.JavaSparkContext sc,
org.apache.spark.api.java.JavaPairRDD<MatrixIndexes,MatrixBlock> input,
DataCharacteristics dcIn) |
static org.apache.spark.api.java.JavaPairRDD<MatrixIndexes,MatrixBlock> |
RDDConverterUtils.textCellToBinaryBlock(org.apache.spark.api.java.JavaSparkContext sc,
org.apache.spark.api.java.JavaPairRDD<org.apache.hadoop.io.LongWritable,org.apache.hadoop.io.Text> input,
DataCharacteristics mcOut,
boolean outputEmptyBlocks,
FileFormatPropertiesMM mmProps) |
static org.apache.spark.api.java.JavaPairRDD<Long,FrameBlock> |
FrameRDDConverterUtils.textCellToBinaryBlock(org.apache.spark.api.java.JavaSparkContext sc,
org.apache.spark.api.java.JavaPairRDD<org.apache.hadoop.io.LongWritable,org.apache.hadoop.io.Text> in,
DataCharacteristics mcOut,
Types.ValueType[] schema) |
static org.apache.spark.api.java.JavaPairRDD<Long,FrameBlock> |
FrameRDDConverterUtils.textCellToBinaryBlockLongIndex(org.apache.spark.api.java.JavaSparkContext sc,
org.apache.spark.api.java.JavaPairRDD<Long,org.apache.hadoop.io.Text> input,
DataCharacteristics mc,
Types.ValueType[] schema) |
Constructor and Description |
---|
BinaryCellToBinaryBlockFunction(DataCharacteristics mc) |
Modifier and Type | Method and Description |
---|---|
DataCharacteristics |
MatrixBlock.getDataCharacteristics() |
Modifier and Type | Method and Description |
---|---|
static boolean |
MatrixBlock.evalSparseFormatInMemory(DataCharacteristics dc) |
static List<IndexedMatrixValue> |
LibMatrixReorg.reshape(IndexedMatrixValue in,
DataCharacteristics mcIn,
DataCharacteristics mcOut,
boolean rowwise,
boolean outputEmptyBlocks)
MR/SPARK reshape interface - for reshape we cannot view blocks independently, and hence,
there are different CP and MR interfaces.
|
Modifier and Type | Class and Description |
---|---|
class |
MatrixCharacteristics |
class |
TensorCharacteristics |
Modifier and Type | Method and Description |
---|---|
DataCharacteristics |
MetaData.getDataCharacteristics() |
DataCharacteristics |
DataCharacteristics.set(DataCharacteristics that) |
DataCharacteristics |
TensorCharacteristics.set(DataCharacteristics that) |
DataCharacteristics |
MatrixCharacteristics.set(DataCharacteristics that) |
DataCharacteristics |
DataCharacteristics.set(long[] dims,
int blocksize) |
DataCharacteristics |
TensorCharacteristics.set(long[] dims,
int blocksize) |
DataCharacteristics |
DataCharacteristics.set(long[] dims,
int blocksize,
long nnz) |
DataCharacteristics |
TensorCharacteristics.set(long[] dims,
int blocksize,
long nnz) |
DataCharacteristics |
DataCharacteristics.set(long nr,
long nc,
int blen) |
DataCharacteristics |
MatrixCharacteristics.set(long nr,
long nc,
int blen) |
DataCharacteristics |
DataCharacteristics.set(long nr,
long nc,
int blen,
long nnz) |
DataCharacteristics |
MatrixCharacteristics.set(long nr,
long nc,
int blen,
long nnz) |
DataCharacteristics |
DataCharacteristics.setBlocksize(int blen) |
DataCharacteristics |
DataCharacteristics.setCols(long clen) |
DataCharacteristics |
MatrixCharacteristics.setCols(long clen) |
DataCharacteristics |
DataCharacteristics.setDim(int i,
long dim) |
DataCharacteristics |
TensorCharacteristics.setDim(int i,
long dim) |
DataCharacteristics |
DataCharacteristics.setDimension(long nr,
long nc) |
DataCharacteristics |
MatrixCharacteristics.setDimension(long nr,
long nc) |
DataCharacteristics |
DataCharacteristics.setDims(long[] dims) |
DataCharacteristics |
TensorCharacteristics.setDims(long[] dims) |
DataCharacteristics |
DataCharacteristics.setNonZeros(long nnz) |
DataCharacteristics |
TensorCharacteristics.setNonZeros(long nnz) |
DataCharacteristics |
MatrixCharacteristics.setNonZeros(long nnz) |
DataCharacteristics |
DataCharacteristics.setNonZerosBound(long nnz) |
DataCharacteristics |
MatrixCharacteristics.setNonZerosBound(long nnz) |
DataCharacteristics |
DataCharacteristics.setRows(long rlen) |
DataCharacteristics |
MatrixCharacteristics.setRows(long rlen) |
Modifier and Type | Method and Description |
---|---|
static void |
DataCharacteristics.aggregateBinary(DataCharacteristics dim1,
DataCharacteristics dim2,
AggregateBinaryOperator op,
DataCharacteristics dimOut) |
static void |
DataCharacteristics.aggregateUnary(DataCharacteristics dim,
AggregateUnaryOperator op,
DataCharacteristics dimOut) |
static void |
DataCharacteristics.reorg(DataCharacteristics dim,
ReorgOperator op,
DataCharacteristics dimOut) |
DataCharacteristics |
DataCharacteristics.set(DataCharacteristics that) |
DataCharacteristics |
TensorCharacteristics.set(DataCharacteristics that) |
DataCharacteristics |
MatrixCharacteristics.set(DataCharacteristics that) |
Constructor and Description |
---|
MatrixCharacteristics(DataCharacteristics that) |
MetaData(DataCharacteristics dc) |
MetaDataFormat(DataCharacteristics dc,
Types.FileFormat fmt) |
TensorCharacteristics(DataCharacteristics that) |
Copyright © 2020 The Apache Software Foundation. All rights reserved.