org.gridkit.jvmtool.heapdump.MapEntrySetStep Maven / Gradle / Ivy
/**
* Copyright 2014 Alexey Ragozin
*
* 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 org.gridkit.jvmtool.heapdump;
import java.util.Collections;
import java.util.Iterator;
import java.util.NoSuchElementException;
import org.netbeans.lib.profiler.heap.FieldValue;
import org.netbeans.lib.profiler.heap.Instance;
import org.netbeans.lib.profiler.heap.ObjectArrayInstance;
import org.netbeans.lib.profiler.heap.ObjectFieldValue;
/** This a special step type handling java.util.HashMap */
class MapEntrySetStep extends PathStep {
@Override
public Iterator walk(Instance instance) {
Object t = instance.getValueOfField("table");
if (t instanceof ObjectArrayInstance) {
return new InstanceIterator(".table", (ObjectArrayInstance) t);
}
else {
return Collections.emptySet().iterator();
}
}
@Override
public Iterator track(Instance instance) {
Object t = instance.getValueOfField("table");
if (t instanceof ObjectArrayInstance) {
return new MoveIterator(".table", (ObjectArrayInstance) t);
}
else {
return Collections.emptySet().iterator();
}
}
public String toString() {
return "?entrySet";
}
private static Instance getField(Instance i, String field) {
for(FieldValue fv: i.getFieldValues()) {
if (fv instanceof ObjectFieldValue && field.equals(fv.getField().getName())) {
return ((ObjectFieldValue)fv).getInstance();
}
}
return null;
}
private static class EntryIterator {
ObjectArrayInstance array;
int nextIndex;
Instance nextEntity;
String pref;
StringBuilder path;
public EntryIterator(String pref, ObjectArrayInstance array) {
this.array = array;
this.pref = pref;
this.path = new StringBuilder();
seek();
}
public boolean hasNext() {
return nextEntity != null;
}
public Instance nextInstance() {
if (nextEntity == null) {
throw new NoSuchElementException();
}
Instance e = nextEntity;
seek();
return e;
}
public Move nextMove() {
if (nextEntity == null) {
throw new NoSuchElementException();
}
Move e = new Move(path.toString(), nextEntity);
seek();
return e;
}
public void remove() {
throw new UnsupportedOperationException();
}
private void seek() {
if (nextEntity != null) {
path.append(".next");
nextEntity = getField(nextEntity, "next");
}
while(nextEntity == null && nextIndex < array.getLength()) {
path.setLength(0);
path.append(pref).append("[").append(nextIndex).append("]");
nextEntity = array.getValues().get(nextIndex++);
}
}
}
private static class InstanceIterator extends EntryIterator implements Iterator {
public InstanceIterator(String pref, ObjectArrayInstance array) {
super(pref, array);
}
@Override
public Instance next() {
return nextInstance();
}
}
private static class MoveIterator extends EntryIterator implements Iterator {
public MoveIterator(String pref, ObjectArrayInstance array) {
super(pref, array);
}
@Override
public Move next() {
return nextMove();
}
}
}