@Override
	public int getChunk(long offset, int size, byte[] dest, boolean stopOnUninitialized) {
		int bytesRead = 0;
		if (size == 0) {
			return bytesRead;
		}
		try {
			//align if necessary
			int adjustment = (int) offset % WORD_SIZE;
			if (adjustment != 0) {
				WordInfo word = map.get(offset & ALIGNMENT_MASK);
				if (word == null) {
					throw new LowlevelError("Attempted to read uninitialized word in unique space");
				}
				for (int i = adjustment; i < WORD_SIZE && bytesRead < size; ++i) {
					dest[bytesRead++] = word.getByte(i);
					offset += 1;
				}
			}
			//copy a word at a time
			while (size - bytesRead > 0) {
				WordInfo word = map.get(offset & ALIGNMENT_MASK);
				if (word == null) {
					throw new LowlevelError("Attempted to read uninitialized word in unique space");
				}
				offset += WORD_SIZE;
				//whole word is initialized, copy it (or the appropriate
				//initial segment) all at once
				int bytesToRead = Math.min(WORD_SIZE, size - bytesRead);
				if (word.isEntireWordInitialized()) {
					word.getWord(buffer);
					System.arraycopy(buffer, 0, dest, bytesRead,
						Math.min(WORD_SIZE, size - bytesRead));
					bytesRead += bytesToRead;
					continue;
				}
				//not entirely initialized, copy one byte at a time until 
				//all requested bytes read (or word.getByte throws an exception)
				int base = bytesRead;
				for (int i = 0; i < bytesToRead; ++i) {
					dest[base + i] = word.getByte(i);
					bytesRead += 1;
				}
			}
			return bytesRead;
		}
		catch (LowlevelError e) {
			if (stopOnUninitialized) {
				return bytesRead;
			}
			throw e;
		}
	}
A map from {@link Long} offsets to byte values would require many lookups.
As an optimization, this map is defined from {@link Long} values to 
{@link WordInfo} objects, each of which represents an eight-byte word
of memory.  Each key in this map must be 0 mod 8.
Ghidra/Framework/Emulation/src/main/java/ghidra/pcode/memstate/UniqueMemoryBank.java