All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.datakernel.aggregation.AggregationChunkCodec Maven / Gradle / Ivy

/*
 * Copyright (C) 2015-2018 SoftIndex LLC.
 *
 * 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 io.datakernel.aggregation;

import io.datakernel.codec.StructuredCodec;
import io.datakernel.codec.StructuredInput;
import io.datakernel.codec.StructuredOutput;
import io.datakernel.exception.ParseException;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import static io.datakernel.codec.StructuredCodecs.STRING_CODEC;

public class AggregationChunkCodec implements StructuredCodec {
	private static final StructuredCodec> MEASURES_CODEC = STRING_CODEC.ofList();
	public static final String ID = "id";
	public static final String MIN = "min";
	public static final String MAX = "max";
	public static final String COUNT = "count";
	public static final String MEASURES = "measures";

	private final ChunkIdCodec chunkIdCodec;
	private final StructuredCodec primaryKeyCodec;
	private final Set allowedMeasures;

	@SuppressWarnings("unchecked")
	private AggregationChunkCodec(ChunkIdCodec chunkIdCodec,
			StructuredCodec primaryKeyCodec,
			Set allowedMeasures) {
		this.chunkIdCodec = (ChunkIdCodec) chunkIdCodec;
		this.primaryKeyCodec = primaryKeyCodec;
		this.allowedMeasures = allowedMeasures;
	}

	public static AggregationChunkCodec create(ChunkIdCodec chunkIdCodec,
			StructuredCodec primaryKeyCodec,
			Set allowedMeasures) {
		return new AggregationChunkCodec(chunkIdCodec, primaryKeyCodec, allowedMeasures);
	}

	@Override
	public void encode(StructuredOutput out, AggregationChunk chunk) {
		out.writeObject(() -> {
			out.writeKey(ID);
			chunkIdCodec.encode(out, chunk.getChunkId());
			out.writeKey(MIN);
			primaryKeyCodec.encode(out, chunk.getMinPrimaryKey());
			out.writeKey(MAX);
			primaryKeyCodec.encode(out, chunk.getMaxPrimaryKey());
			out.writeKey(COUNT);
			out.writeInt(chunk.getCount());
			out.writeKey(MEASURES);
			MEASURES_CODEC.encode(out, chunk.getMeasures());
		});
	}

	@Override
	public AggregationChunk decode(StructuredInput in) throws ParseException {
		return in.readObject($ -> {
			in.readKey(ID);
			Object id = chunkIdCodec.decode(in);
			in.readKey(MIN);
			PrimaryKey from = primaryKeyCodec.decode(in);
			in.readKey(MAX);
			PrimaryKey to = primaryKeyCodec.decode(in);
			in.readKey(COUNT);
			int count = in.readInt();
			in.readKey(MEASURES);
			List measures = MEASURES_CODEC.decode(in);
			List invalidMeasures = getInvalidMeasures(measures);
			if (!invalidMeasures.isEmpty()) throw new ParseException("Unknown fields: " + invalidMeasures);
			return AggregationChunk.create(id, measures, from, to, count);
		});
	}

	private List getInvalidMeasures(List measures) {
		List invalidMeasures = new ArrayList<>();
		for (String measure : measures) {
			if (!allowedMeasures.contains(measure)) {
				invalidMeasures.add(measure);
			}
		}
		return invalidMeasures;
	}

}