int getID(InstructionPrototype prototype, MemBuffer memBuf, ProcessorContextView context) {

		try {
			return protoHt.get(prototype);
		}
		catch (NoValueException e) {
			// new prototype handled below
		}
		int protoID;
		try {
			protoID = (int) protoAdapter.getKey();
			nextKey = protoID + 1;
			int protoArrayIndex = protoID;
			protoArray.put(protoArrayIndex, prototype);
			protoHt.put(prototype, protoID);

			byte[] b = new byte[prototype.getLength()];
			if (memBuf.getBytes(b, 0) != b.length) {
				throw new AssertException("Insufficient bytes for prototype");
			}
			Address address = memBuf.getAddress();
			long addr = addrMap.getKey(address, true);
			protoAdapter.createRecord(protoID, addr, b, prototype.isInDelaySlot());

			if (baseContextRegister != null) {
				RegisterValue registerValue = context.getRegisterValue(baseContextRegister);
				String valueStr =
					registerValue != null ? registerValue.getUnsignedValueIgnoreMask().toString()
							: "0";
				DBRecord record = REGISTER_SCHEMA.createRecord(protoID);
				record.setString(0, valueStr);
				contextTable.putRecord(record);
			}
			return protoID;
		}
		catch (IOException exc) {
			program.dbError(exc);
		}
		return 0;
	}
Get the unique ID for this prototype.  If a prototype matching
this one doesn't exist yet, then this one is stored and given a
new ID.  If a prototype already exists that matches this prototype,
then the ID already assigned to that prototype is returned.  This
relies on the assumption that the Language module provides a
good equals() method.
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/code/PrototypeManager.java