/* Copyright (c) 2011 Danish Maritime Authority. * * 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 dk.dma.ais.store; import com.beust.jcommander.Parameter; import com.datastax.driver.core.ConsistencyLevel; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.ResultSetFuture; import com.datastax.driver.core.Session; import com.datastax.driver.core.Statement; import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.core.querybuilder.Select; import com.google.inject.Injector; import dk.dma.ais.store.cli.baseclients.AisStoreCommandLineTool; import dk.dma.commons.management.ManagedResource; import dk.dma.db.cassandra.CassandraConnection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.time.Instant; import java.util.Arrays; import static com.datastax.driver.core.querybuilder.QueryBuilder.gte; import static com.datastax.driver.core.querybuilder.QueryBuilder.in; import static com.datastax.driver.core.querybuilder.QueryBuilder.lt; import static dk.dma.ais.store.AisStoreSchema.Column.COLUMN_TIMEBLOCK; import static dk.dma.ais.store.AisStoreSchema.Column.COLUMN_TIMESTAMP; import static dk.dma.ais.store.AisStoreSchema.Table.TABLE_PACKETS_TIME; import static java.lang.Integer.min; /** * * @author Thomas Borg Salling */ @ManagedResource public class CassandraStats extends AisStoreCommandLineTool { /** The logger. */ static final Logger LOG = LoggerFactory.getLogger(CassandraStats.class); @Parameter(names = "-from", description = "The instant to count from (format \"2015-01-01T00:00:00.000Z\") (inclusive)", required = true) String from; @Parameter(names = "-to", description = "The instant to count to (format \"2015-02-01T00:00:00.000Z\") (exclusive)", required = true) String to; @Parameter(names = "-tb", description = "No. of timeblocks per select query") int tbPerSelect = 10; /** {@inheritDoc} */ @Override protected void run(Injector injector) throws Exception { printPacketsTimeStats(connect()); } private void printPacketsTimeStats(CassandraConnection conn) { final Session session = conn.getSession(); final Instant ts0 = Instant.parse(from); final Instant ts1 = Instant.parse(to); final int tb0 = AisStoreSchema.timeBlock(TABLE_PACKETS_TIME, ts0); final int tb1 = AisStoreSchema.timeBlock(TABLE_PACKETS_TIME, ts1); LOG.debug(String.format("Duration from %s to %s spans %d timeblocks", from, to, tb1 - tb0)); final int n = tb1-tb0+1; // no. of timeblocks to include in query Integer timeblocks[] = new Integer[n]; for (int i=0; i<n; i++) { timeblocks[i] = tb0+i; } long numPackets = 0; final int step = tbPerSelect; for (int i=0; i<n; i += step) { Integer[] queryTimeBlocks = Arrays.copyOfRange(timeblocks, i, min(i + step, n)); Statement statement = QueryBuilder .select() .countAll() .from(TABLE_PACKETS_TIME.toString()) .where(in(COLUMN_TIMEBLOCK.toString(), queryTimeBlocks)); if (i == 0) ((Select.Where) statement).and(gte(COLUMN_TIMESTAMP.toString(), ts0.toEpochMilli())); if (i >= n-step) ((Select.Where) statement).and(lt(COLUMN_TIMESTAMP.toString(), ts1.toEpochMilli())); statement.setConsistencyLevel(ConsistencyLevel.ONE); LOG.debug(((Select.Where) statement).getQueryString()); ResultSetFuture future = session.executeAsync(statement); ResultSet resultSet = future.getUninterruptibly(); final long count = resultSet.one().getLong(0); numPackets += count; System.out.println("Timeblocks " + queryTimeBlocks[0] + ".." + queryTimeBlocks[queryTimeBlocks.length-1] + ": " + count); printProgress(((float) (i))/n); } printProgress(1); System.out.println(String.format("Counted a total of %d AisPackets in %s.", numPackets, TABLE_PACKETS_TIME.toString())); } private static void printProgress(float pct) { String status = String.format("%5.1f %% done counting AisPackets in %s\r", pct*100f, TABLE_PACKETS_TIME.toString()); LOG.debug(status); System.out.print(status); } public static void main(String[] args) throws Exception { // args = AisReaders.getDefaultSources(); if (args.length == 0) { System.err.println("Must specify at least 1 source (sourceName=host:port,host:port sourceName=host:port)"); System.exit(1); } new CassandraStats().execute(args); } }