/** * Tries to concatenate this range with a given one. If ranges are not adjacent, will return {@code null}. * * @param range Range to concatenate with. * @return Concatenation result or {@code null} if ranges are not adjacent. */ @Nullable public IgfsFileAffinityRange concat(IgfsFileAffinityRange range) { if (endOff + 1 != range.startOff || !F.eq(affKey, range.affKey) || status != RANGE_STATUS_INITIAL) return null; return new IgfsFileAffinityRange(startOff, range.endOff, affKey); }
/** * Splits range into collection if smaller ranges with length equal to {@code maxSize}. * * @param maxSize Split part maximum size. * @return Collection of range parts. */ public Collection<IgfsFileAffinityRange> split(long maxSize) { long len = endOff - startOff + 1; if (len > maxSize) { int size = (int)(len / maxSize + 1); Collection<IgfsFileAffinityRange> res = new ArrayList<>(size); long pos = startOff; while (pos < endOff + 1) { long end = Math.min(pos + maxSize - 1, endOff); IgfsFileAffinityRange part = new IgfsFileAffinityRange(pos, end, affKey); part.status = status; res.add(part); pos = end + 1; } return res; } else return Collections.singletonList(this); }
/** * Read IgfsFileAffinityRange. * * @param reader Reader. * @return File affinity range. */ public static IgfsFileAffinityRange readFileAffinityRange(BinaryRawReader reader) { if (reader.readBoolean()) { IgfsFileAffinityRange affRange = new IgfsFileAffinityRange(); affRange.readRawBinary(reader); return affRange; } else return null; }
@Override public Object call() throws Exception { map.updateRangeStatus(new IgfsFileAffinityRange(15, 19, affKey1), RANGE_STATUS_MOVING); return null; } }, IgfsInvalidRangeException.class, null);
@Override public Object call() throws Exception { map.updateRangeStatus(new IgfsFileAffinityRange(10, 19, affKey2), RANGE_STATUS_MOVING); return null; } }, AssertionError.class, null);
@Override public Object call() throws Exception { map.updateRangeStatus(new IgfsFileAffinityRange(10, 22, affKey1), RANGE_STATUS_MOVING); return null; } }, AssertionError.class, null);
@Override public Object call() throws Exception { map.updateRangeStatus(new IgfsFileAffinityRange(0, 5, affKey1), RANGE_STATUS_MOVING); return null; } }, IgfsInvalidRangeException.class, null);
/** * Updates range status at given position (will split range into two if necessary). * * @param origIdx Original range index. * @param orig Original range at index. * @param update Range being updated. * @param status New status for range. */ private void updateRangeStatus0(int origIdx, IgfsFileAffinityRange orig, IgfsFileAffinityRange update, int status) { assert F.eq(orig.affinityKey(), update.affinityKey()); assert ranges.get(origIdx) == orig; if (orig.regionEqual(update)) ranges.set(origIdx, new IgfsFileAffinityRange(update, status)); else { // If range was expanded, new one should be larger. assert orig.endOffset() > update.endOffset(); ranges.set(origIdx, new IgfsFileAffinityRange(update, status)); ranges.add(origIdx + 1, new IgfsFileAffinityRange(update.endOffset() + 1, orig.endOffset(), orig.affinityKey())); } }
@Override public Object call() throws Exception { IgfsFileAffinityRange range = new IgfsFileAffinityRange(); mgr.storeDataBlocks(reserved, reserved.length(), null, 0, ByteBuffer.wrap(data), false, range, null); return null; } }, IgfsException.class, msg);
/** * @throws Exception If failed. */ @Test public void testAddUpdateAdd() throws Exception { IgfsFileMap map = new IgfsFileMap(); IgniteUuid affKey = IgniteUuid.randomUuid(); map.addRange(new IgfsFileAffinityRange(0, 9, affKey)); map.updateRangeStatus(new IgfsFileAffinityRange(0, 9, affKey), RANGE_STATUS_MOVING); map.addRange(new IgfsFileAffinityRange(10, 19, affKey)); List<IgfsFileAffinityRange> ranges = map.ranges(); assertEquals(2, ranges.size()); assertEquals(RANGE_STATUS_MOVING, ranges.get(0).status()); assertTrue(ranges.get(0).regionEqual(new IgfsFileAffinityRange(0, 9, affKey))); assertEquals(RANGE_STATUS_INITIAL, ranges.get(1).status()); assertTrue(ranges.get(1).regionEqual(new IgfsFileAffinityRange(10, 19, affKey))); }
/** * Gets initial affinity range. This range will have 0 length and will start from first * non-occupied file block. * * @param fileInfo File info to build initial range for. * @return Affinity range. */ private IgfsFileAffinityRange initialStreamRange(IgfsEntryInfo fileInfo) { if (!igfsCtx.configuration().isFragmentizerEnabled()) return null; if (!Boolean.parseBoolean(fileInfo.properties().get(IgfsUtils.PROP_PREFER_LOCAL_WRITES))) return null; int blockSize = fileInfo.blockSize(); // Find first non-occupied block offset. long off = ((fileInfo.length() + blockSize - 1) / blockSize) * blockSize; // Need to get last affinity key and reuse it if we are on the same node. long lastBlockOff = off - fileInfo.blockSize(); if (lastBlockOff < 0) lastBlockOff = 0; IgfsFileMap map = fileInfo.fileMap(); IgniteUuid prevAffKey = map == null ? null : map.affinityKey(lastBlockOff, false); IgniteUuid affKey = igfsCtx.data().nextAffinityKey(prevAffKey); return affKey == null ? null : new IgfsFileAffinityRange(off, off, affKey); }
IgniteUuid affKey = IgniteUuid.randomUuid(); IgfsFileAffinityRange range = new IgfsFileAffinityRange(0, 9999, affKey); assertTrue(part.regionEqual(new IgfsFileAffinityRange(0, 4999, affKey))); assertTrue(part.regionEqual(new IgfsFileAffinityRange(5000, 9999, affKey))); assertTrue(part.regionEqual(new IgfsFileAffinityRange(0, 2999, affKey))); assertTrue(part.regionEqual(new IgfsFileAffinityRange(3000, 5999, affKey))); assertTrue(part.regionEqual(new IgfsFileAffinityRange(6000, 8999, affKey))); assertTrue(part.regionEqual(new IgfsFileAffinityRange(9000, 9999, affKey)));
map.addRange(new IgfsFileAffinityRange(i * 20 + 10, i * 20 + 19, affKey)); map.updateRangeStatus(new IgfsFileAffinityRange(30, 39, affKey), RANGE_STATUS_MOVING); map.updateRangeStatus(new IgfsFileAffinityRange(10, 19, affKey), RANGE_STATUS_MOVING); map.updateRangeStatus(new IgfsFileAffinityRange(70, 79, affKey), RANGE_STATUS_MOVING); map.updateRangeStatus(new IgfsFileAffinityRange(30, 39, affKey), RANGE_STATUS_MOVED); map.updateRangeStatus(new IgfsFileAffinityRange(10, 19, affKey), RANGE_STATUS_MOVED); map.updateRangeStatus(new IgfsFileAffinityRange(70, 79, affKey), RANGE_STATUS_MOVED); map.deleteRange(new IgfsFileAffinityRange(30, 39, affKey)); map.deleteRange(new IgfsFileAffinityRange(10, 19, affKey)); map.deleteRange(new IgfsFileAffinityRange(70, 79, affKey)); assertTrue(ranges.get(0).regionEqual(new IgfsFileAffinityRange(50, 59, affKey)));
map.addRange(new IgfsFileAffinityRange(i * 20 + 10, i * 20 + 19, affKey)); map.updateRangeStatus(new IgfsFileAffinityRange(30, 35, affKey), RANGE_STATUS_MOVING); map.updateRangeStatus(new IgfsFileAffinityRange(10, 15, affKey), RANGE_STATUS_MOVING); map.updateRangeStatus(new IgfsFileAffinityRange(70, 75, affKey), RANGE_STATUS_MOVING); assertTrue(ranges.get(idx).regionEqual(new IgfsFileAffinityRange(10, 15, affKey))); assertEquals(RANGE_STATUS_MOVING, ranges.get(idx).status()); idx++; assertTrue(ranges.get(idx).regionEqual(new IgfsFileAffinityRange(16, 19, affKey))); assertEquals(RANGE_STATUS_INITIAL, ranges.get(idx).status()); idx++; assertTrue(ranges.get(idx).regionEqual(new IgfsFileAffinityRange(30, 35, affKey))); assertEquals(RANGE_STATUS_MOVING, ranges.get(idx).status()); idx++; assertTrue(ranges.get(idx).regionEqual(new IgfsFileAffinityRange(36, 39, affKey))); assertEquals(RANGE_STATUS_INITIAL, ranges.get(idx).status()); idx++; assertTrue(ranges.get(idx).regionEqual(new IgfsFileAffinityRange(50, 59, affKey))); assertEquals(RANGE_STATUS_INITIAL, ranges.get(idx).status()); idx++; assertTrue(ranges.get(idx).regionEqual(new IgfsFileAffinityRange(70, 75, affKey))); assertEquals(RANGE_STATUS_MOVING, ranges.get(idx).status()); idx++;
final IgniteUuid affKey2 = IgniteUuid.randomUuid(); map.addRange(new IgfsFileAffinityRange(10, 19, affKey1)); map.addRange(new IgfsFileAffinityRange(30, 39, affKey1)); map.updateRangeStatus(new IgfsFileAffinityRange(0, 5, affKey1), RANGE_STATUS_MOVING);
/** @throws Exception If failed. */ @Test public void testAffinityFileMap() throws Exception { int blockSize = BLOCK_SIZE; long t = System.currentTimeMillis(); IgfsEntryInfo info = IgfsUtils.createFile(IgniteUuid.randomUuid(), blockSize, 1024 * 1024, null, null, false, null, t, t); IgniteUuid affKey = IgniteUuid.randomUuid(); IgfsFileMap map = new IgfsFileMap(); map.addRange(new IgfsFileAffinityRange(3 * BLOCK_SIZE, 5 * BLOCK_SIZE - 1, affKey)); map.addRange(new IgfsFileAffinityRange(13 * BLOCK_SIZE, 17 * BLOCK_SIZE - 1, affKey)); info = info.fileMap(map); Collection<IgfsBlockLocation> affinity = mgr.affinity(info, 0, info.length()); checkAffinity(blockSize, info, affinity); // Check from middle of range. affinity = mgr.affinity(info, 3 * BLOCK_SIZE + BLOCK_SIZE / 2, info.length()); checkAffinity(blockSize, info, affinity); // Check from middle of last range. affinity = mgr.affinity(info, 14 * BLOCK_SIZE, info.length()); checkAffinity(blockSize, info, affinity); // Check inside one range. affinity = mgr.affinity(info, 14 * BLOCK_SIZE, 2 * BLOCK_SIZE); checkAffinity(blockSize, info, affinity); // Check outside last range. affinity = mgr.affinity(info, 18 * BLOCK_SIZE, info.length()); checkAffinity(blockSize, info, affinity); }
/** * @throws Exception If failed. */ @Test public void testRanges() throws Exception { IgfsFileMap map = new IgfsFileMap(); IgniteUuid[] affKeys = new IgniteUuid[20]; for (int i = 0; i < affKeys.length; i++) affKeys[i] = IgniteUuid.randomUuid(); int numOfRanges = 0; do { for (int i = 0; i < 2 * numOfRanges + 1; i++) { long off1 = i * 10; long off2 = i * 10 + 5; long off3 = i * 10 + 8; IgniteUuid affKey = i % 2 == 0 ? null : affKeys[i / 2]; assertEquals("For i: " + i, affKey, map.affinityKey(off1, false)); assertEquals("For i: " + i, affKey, map.affinityKey(off2, false)); assertEquals("For i: " + i, affKey, map.affinityKey(off3, false)); } map.addRange(new IgfsFileAffinityRange(10 + 20 * numOfRanges, 19 + 20 * numOfRanges, affKeys[numOfRanges])); numOfRanges++; } while (numOfRanges < 20); }
IgfsUtils.DELETE_LOCK_ID, false, null, t, t); IgfsFileAffinityRange range = new IgfsFileAffinityRange(); assertTrue(range.regionEqual(new IgfsFileAffinityRange(0, writesCnt * chunkSize - 1, null)));
IgfsFileAffinityRange range = new IgfsFileAffinityRange();
IgfsFileAffinityRange range = new IgfsFileAffinityRange();