private void removeValue(int inputId, Value value) { final Object input = getInput(value); if (input == null) { return; } if (input instanceof ChangeBufferingList) { final ChangeBufferingList changesList = (ChangeBufferingList) input; changesList.remove(inputId); if (!changesList.isEmpty()) return; } else if (input instanceof Integer) { if (((Integer) input).intValue() != inputId) { return; } } if (!(myInputIdMapping instanceof THashMap)) { myInputIdMapping = null; myInputIdMappingValue = null; } else { THashMap<Value, Object> mapping = (THashMap<Value, Object>) myInputIdMapping; mapping.remove(value); if (mapping.size() == 1) { myInputIdMapping = mapping.keySet().iterator().next(); myInputIdMappingValue = mapping.get((Value) myInputIdMapping); } } }
@Override public void addValue(int inputId, Value value) { final Object input = getInput(value); if (input == null) { attachFileSetForNewValue(value, inputId); } else if (input instanceof Integer) { ChangeBufferingList list = new ChangeBufferingList(); list.add(((Integer) input).intValue()); list.add(inputId); resetFileSetForValue(value, list); } else { ((ChangeBufferingList) input).add(inputId); } }
private void ensureFileSetCapacityForValue(Value value, int count) { if (count <= 1) return; Object input = getInput(value); if (input != null) { if (input instanceof Integer) { ChangeBufferingList list = new ChangeBufferingList(count + 1); list.add(((Integer) input).intValue()); resetFileSetForValue(value, list); } else if (input instanceof ChangeBufferingList) { ChangeBufferingList list = (ChangeBufferingList) input; list.ensureCapacity(count); } return; } final Object fileSet = new ChangeBufferingList(count); attachFileSetForNewValue(value, fileSet); }
@Override public void saveTo(DataOutput out, DataExternalizer<Value> externalizer) throws IOException { DataInputOutputUtil.writeINT(out, size()); for (final Iterator<Value> valueIterator = getValueIterator(); valueIterator.hasNext(); ) { final Value value = valueIterator.next(); externalizer.save(out, value); Object input = getInput(value); if (input instanceof Integer) { DataInputOutputUtil.writeINT( out, (Integer) input); // most common 90% case during index building } else { // serialize positive file ids with delta encoding ChangeBufferingList originalInput = (ChangeBufferingList) input; IntIterator intIterator = originalInput.intIterator(); DataInputOutputUtil.writeINT(out, -intIterator.size()); if (intIterator.hasAscendingOrder()) { IdSet checkSet = originalInput.getCheckSet(); if (checkSet != null && checkSet.size() != intIterator.size()) { // debug code int a = 1; assert false; } int prev = 0; while (intIterator.hasNext()) { int fileId = intIterator.next(); if (checkSet != null && !checkSet.contains(fileId)) { // debug code int a = 1; assert false; } DataInputOutputUtil.writeINT(out, fileId - prev); prev = fileId; } } else { // sorting numbers via bitset before writing deltas int max = 0, min = Integer.MAX_VALUE; while (intIterator.hasNext()) { int nextInt = intIterator.next(); max = Math.max(max, nextInt); min = Math.min(min, nextInt); } assert min > 0; final int offset = (min >> INT_BITS_SHIFT) << INT_BITS_SHIFT; final int bitsLength = ((max - offset) >> INT_BITS_SHIFT) + 1; final int[] bits = ourSpareBuffer.getBuffer(bitsLength); for (int i = 0; i < bitsLength; ++i) bits[i] = 0; intIterator = originalInput.intIterator(); while (intIterator.hasNext()) { final int id = intIterator.next() - offset; bits[id >> INT_BITS_SHIFT] |= (1 << (id)); } int pos = nextSetBit(0, bits, bitsLength); int prev = 0; while (pos != -1) { DataInputOutputUtil.writeINT(out, pos + offset - prev); prev = pos + offset; pos = nextSetBit(pos + 1, bits, bitsLength); } } } } }