/** * 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); }
/** * @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); }
/** * @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); }
IgniteUuid affKey = map == null ? null : map.affinityKey(block * fileInfo.blockSize(), true);
/** * Creates block key based on block ID, file info and local affinity range. * * @param block Block ID. * @param fileInfo File info being written. * @param locRange Local affinity range to update. * @return Block key. */ private IgfsBlockKey createBlockKey( long block, IgfsEntryInfo fileInfo, IgfsFileAffinityRange locRange ) { // If affinityKey is present, return block key as is. if (fileInfo.affinityKey() != null) return new IgfsBlockKey(fileInfo.id(), fileInfo.affinityKey(), fileInfo.evictExclude(), block); // If range is done, no colocated writes are attempted. if (locRange == null) return new IgfsBlockKey(fileInfo.id(), null, fileInfo.evictExclude(), block); long blockStart = block * fileInfo.blockSize(); // If block does not belong to new range, return old affinity key. if (locRange.less(blockStart)) { IgniteUuid affKey = fileInfo.fileMap().affinityKey(blockStart, false); return new IgfsBlockKey(fileInfo.id(), affKey, fileInfo.evictExclude(), block); } if (!locRange.belongs(blockStart)) locRange.expand(blockStart, fileInfo.blockSize()); return new IgfsBlockKey(fileInfo.id(), locRange.affinityKey(), fileInfo.evictExclude(), block); }
/** * Checks affinity validity. * * @param blockSize Block size. * @param info File info. * @param affinity Affinity block locations to check. */ private void checkAffinity(int blockSize, IgfsEntryInfo info, Iterable<IgfsBlockLocation> affinity) { for (IgfsBlockLocation loc : affinity) { info("Going to check IGFS block location: " + loc); int block = (int)(loc.start() / blockSize); int endPos; do { IgfsBlockKey key = new IgfsBlockKey(info.id(), info.fileMap().affinityKey(block * blockSize, false), false, block); ClusterNode affNode = grid(0).affinity(grid(0).igfsx("igfs").configuration() .getDataCacheConfiguration().getName()).mapKeyToNode(key); assertTrue("Failed to find node in affinity [dataMgr=" + loc.nodeIds() + ", nodeId=" + affNode.id() + ", block=" + block + ']', loc.nodeIds().contains(affNode.id())); endPos = (block + 1) * blockSize; block++; } while (endPos < loc.start() + loc.length()); } }
/** * 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); }
/** * @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); }
IgniteUuid affKey = map == null ? null : map.affinityKey(block * fileInfo.blockSize(), true);
/** * Creates block key based on block ID, file info and local affinity range. * * @param block Block ID. * @param fileInfo File info being written. * @param locRange Local affinity range to update. * @return Block key. */ private IgfsBlockKey createBlockKey( long block, IgfsEntryInfo fileInfo, IgfsFileAffinityRange locRange ) { // If affinityKey is present, return block key as is. if (fileInfo.affinityKey() != null) return new IgfsBlockKey(fileInfo.id(), fileInfo.affinityKey(), fileInfo.evictExclude(), block); // If range is done, no colocated writes are attempted. if (locRange == null) return new IgfsBlockKey(fileInfo.id(), null, fileInfo.evictExclude(), block); long blockStart = block * fileInfo.blockSize(); // If block does not belong to new range, return old affinity key. if (locRange.less(blockStart)) { IgniteUuid affKey = fileInfo.fileMap().affinityKey(blockStart, false); return new IgfsBlockKey(fileInfo.id(), affKey, fileInfo.evictExclude(), block); } if (!locRange.belongs(blockStart)) locRange.expand(blockStart, fileInfo.blockSize()); return new IgfsBlockKey(fileInfo.id(), locRange.affinityKey(), fileInfo.evictExclude(), block); }