@Override
	default DBTraceDefinedDataAdapter getComponent(int index) {
		// We may write to the cache
		try (LockHold hold = LockHold.lock(getTrace().getReadWriteLock().writeLock())) {
			if (index < 0 || index >= getNumComponents()) {
				return null;
			}

			DBTraceDefinedDataAdapter[] cache = doGetComponentCache();
			if (cache[index] != null) {
				return cache[index];
			}

			DataType baseDataType = getBaseDataType();
			if (baseDataType instanceof Array) {
				Array array = (Array) baseDataType;
				int elementLength = array.getElementLength();
				Address componentAddress = getAddress().add(index * elementLength);
				return cache[index] = new DBTraceDataArrayElementComponent(getRoot(), this, index,
					componentAddress, array.getDataType(), elementLength);
			}
			if (baseDataType instanceof Composite) {
				Composite composite = (Composite) baseDataType;
				DataTypeComponent dtc = composite.getComponent(index);
				Address componentAddress = getAddress().add(dtc.getOffset());
				return cache[index] =
					new DBTraceDataCompositeFieldComponent(getRoot(), this, componentAddress, dtc);
			}
			if (baseDataType instanceof DynamicDataType) {
				DynamicDataType dynamic = (DynamicDataType) baseDataType;
				DataTypeComponent dtc = dynamic.getComponent(index, this);
				Address componentAddress = getAddress().add(dtc.getOffset());
				return cache[index] =
					new DBTraceDataCompositeFieldComponent(getRoot(), this, componentAddress, dtc);
			}
			Msg.error(this,
				"Unsupported composite data type class: " + baseDataType.getClass().getName());
			return null;
		}
	}
TODO: Document me

Note this will always be called with the write lock

@return the new or existing component cache
Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/listing/DBTraceDefinedDataAdapter.java