/** * Copyright 2011 LiveRamp * * 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.liveramp.hank.partition_server; import java.io.IOException; import java.nio.ByteBuffer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.liveramp.hank.coordinator.HostDomainPartition; import com.liveramp.hank.generated.HankResponse; import com.liveramp.hank.storage.Reader; import com.liveramp.hank.storage.ReaderResult; import com.liveramp.hank.util.AtomicLongCollection; import com.liveramp.hank.util.HankTimer; /** * Wrapper class that stores: 1. HostDomainPartition 2. Reader: The Reader * associated with the HostDomainPartition 3. AtomicLongCollection: counters * for number of requests and hits in a given time window */ public class PartitionAccessor { private static final HankResponse NOT_FOUND = HankResponse.not_found(true); private static final Logger LOG = LoggerFactory.getLogger(PartitionAccessor.class); private final HostDomainPartition partition; private final Reader reader; private final HankTimer windowTimer = new HankTimer(); //0: num requests //1: num hits //2: responses data num bytes //3: num L1 cache hits //4: num L2 cache hits private final AtomicLongCollection countersWindow; public PartitionAccessor(HostDomainPartition partition, Reader reader) { if (reader == null) { throw new IllegalArgumentException("Reader may not be null!"); } this.partition = partition; this.reader = reader; windowTimer.restart(); countersWindow = new AtomicLongCollection(5, new long[]{0, 0, 0, 0, 0}); } public HostDomainPartition getHostDomainPartition() { return partition; } public HankResponse get(ByteBuffer key, ReaderResult result) throws IOException { // Increment requests counter LOG.trace("Partition GET"); reader.get(key, result); int l1CacheHit = result.getL1CacheHit() ? 1 : 0; int l2CacheHit = result.getL2CacheHit() ? 1 : 0; if (result.isFound()) { countersWindow.increment(1, 1, result.getBuffer().remaining(), l1CacheHit, l2CacheHit); return HankResponse.value(result.getBuffer()); } else { countersWindow.increment(1, 0, 0, l1CacheHit, l2CacheHit); return NOT_FOUND; } } public PartitionAccessorRuntimeStatistics getRuntimeStatistics() { // Copy duration and counts long windowDurationNanos = windowTimer.getDuration(); windowTimer.restart(); // Get atomic counters long[] counters = countersWindow.getAsArrayAndSet(0, 0, 0, 0, 0); long numRequestsInWindow = counters[0]; long numHitsInWindow = counters[1]; long responsesNumBytesInWindow = counters[2]; long numL1CacheHitsInWindow = counters[3]; long numL2CacheHitsInWindow = counters[4]; double throughput = 0; double responseDataThroughput = 0; if (windowDurationNanos != 0) { throughput = numRequestsInWindow / (windowDurationNanos / 1000000000d); responseDataThroughput = responsesNumBytesInWindow / (windowDurationNanos / 1000000000d); } return new PartitionAccessorRuntimeStatistics(numRequestsInWindow, numHitsInWindow, throughput, responseDataThroughput, numL1CacheHitsInWindow, numL2CacheHitsInWindow, reader.getCacheStatistics()); } public void shutDown() { if (reader != null) { try { reader.close(); } catch (IOException e) { LOG.error("Exception while closing Reader", e); } } } }