private void iterateMapEntryOrTree()

in application/org.openjdk.jmc.joverflow/src/main/java/org/openjdk/jmc/joverflow/descriptors/ArrayBasedCollectionDescriptor.java [256:328]


	private void iterateMapEntryOrTree(MapIteratorCallback cb) {
		JavaObjectArray entriesArray = getElementsArray();
		if (entriesArray == null) {
			return; // Can happen if entries array is unresolved
		}

		if (!cb.scanImplementationObject(entriesArray)) {
			return;
		}

		int numElements = getNumElements();
		if (numElements == 0) {
			return;
		}

		JavaHeapObject[] entries = entriesArray.getElements();
		JavaThing[] entryFields = null;

		int keyFieldIdx = -1, valueFieldIdx = -1, nextFieldIdx = -1;

		outerLoop: for (JavaHeapObject entryThing : entries) {
			if (entryThing == null || !(entryThing instanceof JavaObject)) {
				continue;
			}

			JavaObject entry = (JavaObject) entryThing;

			if (keyFieldIdx < 0) {
				keyFieldIdx = factory.getKeyFieldIdx(entry);
				valueFieldIdx = factory.getValueFieldIdx(entry);
				nextFieldIdx = factory.getEntryNextFieldIdx(entry);
			}

			if (entry.getField("root") == null) {
				while (entry != null) {
					if (!cb.scanImplementationObject(entry)) {
						// We get this in BFS if entry already seen
						break;
					}
					entryFields = entry.getFields(entryFields);

					JavaThing keyThing = entryFields[keyFieldIdx];
					JavaHeapObject key = (keyThing instanceof JavaHeapObject) ? (JavaHeapObject) keyThing : null;

					JavaThing valueThing = entryFields[valueFieldIdx];
					JavaHeapObject value = (valueThing instanceof JavaHeapObject) ? (JavaHeapObject) valueThing : null;

					if (!cb.scanMapEntry(key, value)) {
						break outerLoop;
					}

					if (!(entryFields[nextFieldIdx] instanceof JavaObject)) {
						break; // Unresolved object
					}
					JavaObject prevEntry = entry;
					entry = (JavaObject) entryFields[nextFieldIdx];
					if (entry == prevEntry) {
						break;
					}
				}
			} else {
				if (!cb.scanImplementationObject(entry)) {
					break;
				}
				JavaThing root = entry.getField("root");
				if (!(root instanceof JavaObject)) {
					continue;
				}
				// Traverse the tree to scan
				preOrderTraverseTree((JavaObject) root, cb);
			}
		}
	}