class HaversineDistance extends FastDistance {

    @Override
    public void updateLabel(FastDistanceData data) {
        if (data instanceof FastDistanceVectorData) {
            FastDistanceVectorData vectorData = (FastDistanceVectorData)data;
            Vector vec = vectorData.getVector();
            Preconditions.checkState(vec.size() == VECTOR_SIZE,
                "HaversineDistance only supports vector size 2, the first value is latitude and the second value is "
                    + "longitude");
            if (vectorData.label == null || vectorData.label.size() != LABEL_SIZE) {
                vectorData.label = new DenseVector(LABEL_SIZE);
            }
            vectorData.label = new DenseVector(vectorLabel(vec.get(0), vec.get(1)));
        } else {
            FastDistanceMatrixData matrix = (FastDistanceMatrixData)data;
            if (matrix.label == null || matrix.label.numRows() != LABEL_SIZE || matrix.label.numCols() != matrix.vectors
                .numCols()) {
                matrix.label = new DenseMatrix(LABEL_SIZE, matrix.vectors.numCols());
            }
            double[] matrixData = matrix.vectors.getData();
            Preconditions.checkState(matrixData.length % VECTOR_SIZE == 0,
                "HaversineDistance only supports vector size 2, the first value is latitude and the second value is "
                    + "longitude");

            double[] normData = matrix.label.getData();
            int labelCnt = 0;
            for (int i = 0; i < matrixData.length; i += VECTOR_SIZE) {
                double[] norm = vectorLabel(matrixData[i], matrixData[i + 1]);
                normData[labelCnt++] = norm[0];
                normData[labelCnt++] = norm[1];
                normData[labelCnt++] = norm[2];
            }
        }
    }

}