/** * Reads the area code entries from the provided input stream and stores them to the internal byte * buffers. */ private void readEntries(ObjectInput objectInput) { numOfEntries = objectInput.readInt(); if (phoneNumberPrefixes == null || phoneNumberPrefixes.capacity() < numOfEntries) { phoneNumberPrefixes = ByteBuffer.allocate(numOfEntries * prefixSizeInBytes); } if (descriptionIndexes == null || descriptionIndexes.capacity() < numOfEntries) { descriptionIndexes = ByteBuffer.allocate(numOfEntries * descIndexSizeInBytes); } for (int i = 0; i < numOfEntries; i++) { readExternalWord(objectInput, prefixSizeInBytes, phoneNumberPrefixes, i); readExternalWord(objectInput, descIndexSizeInBytes, descriptionIndexes, i); } }
public override void readFromSortedMap(SortedMap<Integer, String> areaCodeMap) { SortedSet<String> descriptionsSet = new TreeSet<String>(); numOfEntries = areaCodeMap.size(); prefixSizeInBytes = getOptimalNumberOfBytesForValue(areaCodeMap.lastKey()); phoneNumberPrefixes = ByteBuffer.allocate(numOfEntries * prefixSizeInBytes); // Fill the phone number prefixes byte buffer, the set of possible lengths of prefixes and the // description set. int index = 0; foreach (Entry<Integer, String> entry in areaCodeMap.entrySet()) { int prefix = entry.getKey(); storeWordInBuffer(phoneNumberPrefixes, prefixSizeInBytes, index, prefix); possibleLengths.add((int) Math.log10(prefix) + 1); descriptionsSet.add(entry.getValue()); ++index; } createDescriptionPool(descriptionsSet, areaCodeMap); }
/** * Creates the description pool from the provided set of string descriptions and area code map. */ private void createDescriptionPool(SortedSet<String> descriptionsSet, SortedMap<Integer, String> areaCodeMap) { descIndexSizeInBytes = getOptimalNumberOfBytesForValue(descriptionsSet.size() - 1); descriptionIndexes = ByteBuffer.allocate(numOfEntries * descIndexSizeInBytes); descriptionPool = new String[descriptionsSet.size()]; descriptionsSet.toArray(descriptionPool); // Map the phone number prefixes to the descriptions. int index = 0; for (int i = 0; i < numOfEntries; i++) { int prefix = readWordFromBuffer(phoneNumberPrefixes, prefixSizeInBytes, i); String description = areaCodeMap.get(prefix); int positionInDescriptionPool = Arrays.binarySearch(descriptionPool, description); storeWordInBuffer(descriptionIndexes, descIndexSizeInBytes, index, positionInDescriptionPool); ++index; } }
/** * Writes the value read from the provided byte {@code buffer} at the specified {@code index} to * the provided {@code objectOutput}. * * @param objectOutput the object output stream to which the value is written * @param wordSize the number of bytes used to store the value * @param inputBuffer the byte buffer from which the value is read * @param index the index of the value in the the byte buffer * @throws IOException if an error occurred writing to the provided object output stream */ private static void writeExternalWord(ObjectOutput objectOutput, int wordSize, ByteBuffer inputBuffer, int index) { int wordIndex = index * wordSize; if (wordSize == SHORT_NUM_BYTES) { objectOutput.writeShort(inputBuffer.getShort(wordIndex)); } else { objectOutput.writeInt(inputBuffer.getInt(wordIndex)); } }
/** * Stores the provided {@code value} to the provided byte {@code buffer} at the specified {@code * index} using the provided {@code wordSize} in bytes. Note that only integer and short sizes are * supported. * * @param buffer the byte buffer to which the value is stored * @param wordSize the number of bytes used to store the provided value * @param index the index to which the value is stored * @param value the value that is stored assuming it does not require more than the specified * number of bytes. */ private static void storeWordInBuffer(ByteBuffer buffer, int wordSize, int index, int value) { int wordIndex = index * wordSize; if (wordSize == SHORT_NUM_BYTES) { buffer.putShort(wordIndex, (short) value); } else { buffer.putInt(wordIndex, value); } }
/** * Reads the {@code value} at the specified {@code index} from the provided byte {@code buffer}. * Note that only integer and short sizes are supported. * * @param buffer the byte buffer from which the value is read * @param wordSize the number of bytes used to store the value * @param index the index where the value is read from * * @return the value read from the buffer */ private static int readWordFromBuffer(ByteBuffer buffer, int wordSize, int index) { int wordIndex = index * wordSize; return wordSize == SHORT_NUM_BYTES ? buffer.getShort(wordIndex) : buffer.getInt(wordIndex); }
/** * Stores a value which is read from the provided {@code objectInput} to the provided byte {@code * buffer} at the specified {@code index}. * * @param objectInput the object input stream from which the value is read * @param wordSize the number of bytes used to store the value read from the stream * @param outputBuffer the byte buffer to which the value is stored * @param index the index where the value is stored in the buffer * @throws IOException if an error occurred reading from the object input stream */ private static void readExternalWord(ObjectInput objectInput, int wordSize, ByteBuffer outputBuffer, int index) { int wordIndex = index * wordSize; if (wordSize == SHORT_NUM_BYTES) { outputBuffer.putShort(wordIndex, objectInput.readShort()); } else { outputBuffer.putInt(wordIndex, objectInput.readInt()); } }