/** * @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))); }
/** * @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); }
/** {@inheritDoc} */ @Override public IgfsEntryInfo process(MutableEntry<IgniteUuid, IgfsEntryInfo> entry, Object... args) throws EntryProcessorException { IgfsEntryInfo oldInfo = entry.getValue(); IgfsFileMap newMap = new IgfsFileMap(oldInfo.fileMap()); newMap.deleteRange(range); IgfsEntryInfo newInfo = oldInfo.fileMap(newMap); entry.setValue(newInfo); return newInfo; }
/** {@inheritDoc} */ @Override public IgfsEntryInfo process(MutableEntry<IgniteUuid, IgfsEntryInfo> entry, Object... args) throws EntryProcessorException { IgfsEntryInfo oldInfo = entry.getValue(); IgfsFileMap newMap = new IgfsFileMap(oldInfo.fileMap()); newMap.updateRangeStatus(range, status); IgfsEntryInfo newInfo = oldInfo.fileMap(newMap); entry.setValue(newInfo); return newInfo; }
/** {@inheritDoc} */ @Override public IgfsEntryInfo process(MutableEntry<IgniteUuid, IgfsEntryInfo> entry, Object... args) throws EntryProcessorException { IgfsEntryInfo oldInfo = entry.getValue(); IgfsFileMap newMap = new IgfsFileMap(oldInfo.fileMap()); newMap.addRange(affRange); IgfsEntryInfo newInfo = oldInfo.length(oldInfo.length() + space).fileMap(newMap); entry.setValue(newInfo); return newInfo; }
final IgfsFileMap map = new IgfsFileMap(); map.addRange(new IgfsFileAffinityRange(10, 19, affKey1)); map.addRange(new IgfsFileAffinityRange(30, 39, affKey1)); assertEquals(2, map.ranges().size());
/** * 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); }
@Override public Object call() throws Exception { map.updateRangeStatus(new IgfsFileAffinityRange(15, 19, affKey1), RANGE_STATUS_MOVING); return null; } }, IgfsInvalidRangeException.class, null);
/** * Constructs file info. * * @param id ID or {@code null} to generate it automatically. * @param blockSize Block size. * @param len Size of a file. * @param affKey Affinity key for data blocks. * @param props File properties. * @param fileMap File map. * @param lockId Lock ID. * @param accessTime Last access time. * @param modificationTime Last modification time. * @param evictExclude Evict exclude flag. */ IgfsFileInfo(IgniteUuid id, int blockSize, long len, @Nullable IgniteUuid affKey, @Nullable Map<String, String> props, @Nullable IgfsFileMap fileMap, @Nullable IgniteUuid lockId, long accessTime, long modificationTime, boolean evictExclude) { super(id, props, accessTime, modificationTime); this.len = len; this.blockSize = blockSize; this.affKey = affKey; if (fileMap == null) fileMap = new IgfsFileMap(); this.fileMap = fileMap; this.lockId = lockId; this.evictExclude = evictExclude; }
updateRangeStatus0(lastIdx, last, range, status); updateRangeStatus0(firstIdx, first, range, status); updateRangeStatus0(midIdx, midRange, range, status);
/** {@inheritDoc} */ @Override public Void process(MutableEntry<IgniteUuid, IgfsEntryInfo> entry, Object... args) throws EntryProcessorException { IgfsEntryInfo oldInfo = entry.getValue(); assert oldInfo != null; IgfsEntryInfo newInfo = oldInfo.unlock(modificationTime); if (updateSpace) { IgfsFileMap newMap = new IgfsFileMap(newInfo.fileMap()); newMap.addRange(affRange); newInfo = newInfo.length(newInfo.length() + space).fileMap(newMap); } entry.setValue(newInfo); return null; }
if (!exclude.contains(fileInfo.id()) && fileInfo.fileMap() != null && !fileInfo.fileMap().ranges().isEmpty()) return fileInfo;
/** * @param blockIdx Block index. * @param fileInfo File info. * @return Block key. */ public IgfsBlockKey blockKey(long blockIdx, IgfsEntryInfo fileInfo) { if (fileInfo.affinityKey() != null) return new IgfsBlockKey(fileInfo.id(), fileInfo.affinityKey(), fileInfo.evictExclude(), blockIdx); if (fileInfo.fileMap() != null) { IgniteUuid affKey = fileInfo.fileMap().affinityKey(blockIdx * fileInfo.blockSize(), false); return new IgfsBlockKey(fileInfo.id(), affKey, fileInfo.evictExclude(), blockIdx); } return new IgfsBlockKey(fileInfo.id(), null, fileInfo.evictExclude(), blockIdx); }
/** {@inheritDoc} */ @Override public IgfsEntryInfo process(MutableEntry<IgniteUuid, IgfsEntryInfo> entry, Object... args) throws EntryProcessorException { IgfsEntryInfo oldInfo = entry.getValue(); IgfsFileMap newMap = new IgfsFileMap(oldInfo.fileMap()); newMap.updateRangeStatus(range, status); IgfsEntryInfo newInfo = oldInfo.fileMap(newMap); entry.setValue(newInfo); return newInfo; }
@Override public Object call() throws Exception { map.updateRangeStatus(new IgfsFileAffinityRange(0, 5, affKey1), RANGE_STATUS_MOVING); return null; } }, IgfsInvalidRangeException.class, null);
/** * Constructs file info. * * @param id ID or {@code null} to generate it automatically. * @param blockSize Block size. * @param len Size of a file. * @param affKey Affinity key for data blocks. * @param props File properties. * @param fileMap File map. * @param lockId Lock ID. * @param accessTime Last access time. * @param modificationTime Last modification time. * @param evictExclude Evict exclude flag. */ IgfsFileInfo(IgniteUuid id, int blockSize, long len, @Nullable IgniteUuid affKey, @Nullable Map<String, String> props, @Nullable IgfsFileMap fileMap, @Nullable IgniteUuid lockId, long accessTime, long modificationTime, boolean evictExclude) { super(id, props, accessTime, modificationTime); this.len = len; this.blockSize = blockSize; this.affKey = affKey; if (fileMap == null) fileMap = new IgfsFileMap(); this.fileMap = fileMap; this.lockId = lockId; this.evictExclude = evictExclude; }
updateRangeStatus0(lastIdx, last, range, status); updateRangeStatus0(firstIdx, first, range, status); updateRangeStatus0(midIdx, midRange, range, status);
IgfsFileMap map = new IgfsFileMap(); 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); List<IgfsFileAffinityRange> ranges = map.ranges(); 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); ranges = map.ranges(); map.deleteRange(new IgfsFileAffinityRange(30, 39, affKey)); map.deleteRange(new IgfsFileAffinityRange(10, 19, affKey)); map.deleteRange(new IgfsFileAffinityRange(70, 79, affKey)); ranges = map.ranges();
/** @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); }