/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 org.apache.ignite.internal.visor.cache; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import org.apache.ignite.IgniteCache; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cache.CacheMode; import org.apache.ignite.cache.CachePeekMode; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.internal.IgniteEx; import org.apache.ignite.internal.processors.cache.GridCacheAdapter; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionTopology; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheAdapter; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.internal.visor.VisorDataTransferObject; import org.apache.ignite.lang.IgniteUuid; import org.jetbrains.annotations.Nullable; /** * Data transfer object for {@link IgniteCache}. */ public class VisorCache extends VisorDataTransferObject { /** */ private static final long serialVersionUID = 0L; /** */ private static final CachePeekMode[] PEEK_NO_NEAR = new CachePeekMode[] {CachePeekMode.PRIMARY, CachePeekMode.BACKUP}; /** Default cache size sampling. */ private static final int DFLT_CACHE_SIZE_SAMPLING = 10; /** Cache name. */ private String name; /** Cache deployment ID. */ private IgniteUuid dynamicDeploymentId; /** Cache mode. */ private CacheMode mode; /** Cache size in bytes. */ private long memorySize; /** Cache size in bytes. */ private long indexesSize; /** Number of all entries in cache. */ private long size; /** Number of all entries in near cache. */ private int nearSize; /** Number of primary entries in cache. */ private long primarySize; /** Number of backup entries in cache. */ private long backupSize; /** Number of cache entries stored in heap memory. */ private long onHeapEntriesCnt; /** Number of partitions. */ private int partitions; /** Flag indicating that cache has near cache. */ private boolean near; /** Cache metrics. */ private VisorCacheMetrics metrics; /** Cache partitions states. */ private VisorPartitionMap parts; /** * Create data transfer object for given cache. */ public VisorCache() { // No-op. } /** * Create data transfer object for given cache. * * @param ca Internal cache. * @param sample Sample size. * @throws IgniteCheckedException If failed to create data transfer object. */ public VisorCache(IgniteEx ignite, GridCacheAdapter ca, int sample) throws IgniteCheckedException { assert ca != null; name = ca.name(); GridCacheContext cctx = ca.context(); CacheConfiguration cfg = ca.configuration(); mode = cfg.getCacheMode(); boolean partitioned = (mode == CacheMode.PARTITIONED || mode == CacheMode.REPLICATED) && cctx.affinityNode(); if (partitioned) { GridDhtCacheAdapter dca = null; if (ca instanceof GridNearCacheAdapter) dca = ((GridNearCacheAdapter)ca).dht(); else if (ca instanceof GridDhtCacheAdapter) dca = (GridDhtCacheAdapter)ca; if (dca != null) { GridDhtPartitionTopology top = dca.topology(); if (cfg.getCacheMode() != CacheMode.LOCAL && cfg.getBackups() > 0) parts = new VisorPartitionMap(top.localPartitionMap()); } } dynamicDeploymentId = cctx.dynamicDeploymentId(); size = ca.localSizeLong(PEEK_NO_NEAR); primarySize = ca.primarySizeLong(); backupSize = size - primarySize; // This is backup size. nearSize = ca.nearSize(); onHeapEntriesCnt = 0; // TODO GG-11148 Need to rename on ON-heap entries count, see partitions = ca.affinity().partitions(); metrics = new VisorCacheMetrics(ignite, name); // TODO: GG-11683 Move to separate thing near = cctx.isNear(); estimateMemorySize(ignite, ca, sample); } /** * Estimate memory size used by cache. * * @param ca Cache adapter. * @param sample Sample size. */ protected void estimateMemorySize(IgniteEx ignite, GridCacheAdapter ca, int sample) { /* TODO Fix after GG-11739 implemented. int size = ca.size(); Iterable<GridCacheEntryEx> set = ca.context().isNear() ? ((GridNearCacheAdapter)ca).dht().entries() : ca.entries(); long memSz = 0; Iterator<GridCacheEntryEx> it = set.iterator(); int sz = sample > 0 ? sample : DFLT_CACHE_SIZE_SAMPLING; int cnt = 0; while (it.hasNext() && cnt < sz) { memSz += it.next().memorySize(); cnt++; } if (cnt > 0) memSz = (long)((double)memSz / cnt * size); memorySize = memSz; */ memorySize = 0; } /** * @return New instance suitable to store in history. */ public VisorCache history() { VisorCache c = new VisorCache(); c.name = name; c.mode = mode; c.memorySize = memorySize; c.indexesSize = indexesSize; c.size = size; c.nearSize = nearSize; c.backupSize = backupSize; c.primarySize = primarySize; c.onHeapEntriesCnt = onHeapEntriesCnt; c.partitions = partitions; c.metrics = metrics; c.near = near; return c; } /** * @return Cache name. */ public String getName() { return name; } /** * Sets new value for cache name. * * @param name New cache name. */ public void setName(String name) { this.name = name; } /** * @return Dynamic deployment ID. */ public IgniteUuid getDynamicDeploymentId() { return dynamicDeploymentId; } /** * @return Cache mode. */ public CacheMode getMode() { return mode; } /** * @return Cache size in bytes. */ public long getMemorySize() { return memorySize; } /** * @return Indexes size in bytes. */ public long getIndexesSize() { return indexesSize; } /** * @return Number of all entries in cache. */ public long getSize() { return size; } /** * @return Number of all entries in near cache. */ public int getNearSize() { return nearSize; } /** * @return Number of backup entries in cache. */ public long getBackupSize() { return backupSize; } /** * @return Number of primary entries in cache. */ public long getPrimarySize() { return primarySize; } /** * @return Number of cache entries stored in heap memory. */ public long getOnHeapEntriesCount() { return onHeapEntriesCnt; } /** * @return Number of partitions. */ public int getPartitions() { return partitions; } /** * @return Cache metrics. */ public VisorCacheMetrics getMetrics() { return metrics; } /** * @return Cache partitions states. */ @Nullable public VisorPartitionMap getPartitionMap() { return parts; } /** * @return {@code true} if cache has near cache. */ public boolean isNear() { return near; } /** {@inheritDoc} */ @Override protected void writeExternalData(ObjectOutput out) throws IOException { U.writeString(out, name); U.writeGridUuid(out, dynamicDeploymentId); U.writeEnum(out, mode); out.writeLong(memorySize); out.writeLong(indexesSize); out.writeLong(size); out.writeInt(nearSize); out.writeLong(primarySize); out.writeLong(backupSize); out.writeLong(onHeapEntriesCnt); out.writeInt(partitions); out.writeBoolean(near); out.writeObject(metrics); out.writeObject(parts); } /** {@inheritDoc} */ @Override protected void readExternalData(byte protoVer, ObjectInput in) throws IOException, ClassNotFoundException { name = U.readString(in); dynamicDeploymentId = U.readGridUuid(in); mode = CacheMode.fromOrdinal(in.readByte()); memorySize = in.readLong(); indexesSize = in.readLong(); size = in.readLong(); nearSize = in.readInt(); primarySize = in.readLong(); backupSize = in.readLong(); onHeapEntriesCnt = in.readLong(); partitions = in.readInt(); near = in.readBoolean(); metrics = (VisorCacheMetrics)in.readObject(); parts = (VisorPartitionMap)in.readObject(); } /** {@inheritDoc} */ @Override public String toString() { return S.toString(VisorCache.class, this); } }