Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -117,30 +117,40 @@ private FetchShuffleBlocks createFetchShuffleBlocksMsg(
boolean batchFetchEnabled = firstBlock.length == 5;

HashMap<Long, ArrayList<Integer>> mapIdToReduceIds = new HashMap<>();
// The mapIds and reducesId must be same order with blockIds because the shuffle data's
Comment thread
seayoun marked this conversation as resolved.
Outdated
// return order will match the `blockIds` order to ensure blockId and data match.
Comment thread
seayoun marked this conversation as resolved.
Outdated
ArrayList<Long> orderedMapId = new ArrayList<>();
Comment thread
seayoun marked this conversation as resolved.
Outdated
for (String blockId : blockIds) {
String[] blockIdParts = splitBlockId(blockId);
if (Integer.parseInt(blockIdParts[1]) != shuffleId) {
throw new IllegalArgumentException("Expected shuffleId=" + shuffleId +
", got:" + blockId);
}
long mapId = Long.parseLong(blockIdParts[2]);
assert(orderedMapId.isEmpty() || mapId >= orderedMapId.get(orderedMapId.size() - 1));
Comment thread
seayoun marked this conversation as resolved.
Outdated
if (!mapIdToReduceIds.containsKey(mapId)) {
mapIdToReduceIds.put(mapId, new ArrayList<>());
orderedMapId.add(mapId);
}
mapIdToReduceIds.get(mapId).add(Integer.parseInt(blockIdParts[3]));
ArrayList<Integer> reduceIdsByMapId = mapIdToReduceIds.get(mapId);
int reduceId = Integer.parseInt(blockIdParts[3]);
assert(reduceIdsByMapId.isEmpty()
|| reduceId > reduceIdsByMapId.get(reduceIdsByMapId.size() - 1));
Comment thread
seayoun marked this conversation as resolved.
Outdated
reduceIdsByMapId.add(reduceId);
if (batchFetchEnabled) {
// When we read continuous shuffle blocks in batch, we will reuse reduceIds in
// FetchShuffleBlocks to store the start and end reduce id for range
// [startReduceId, endReduceId).
assert(blockIdParts.length == 5);
mapIdToReduceIds.get(mapId).add(Integer.parseInt(blockIdParts[4]));
reduceIdsByMapId.add(Integer.parseInt(blockIdParts[4]));
}
}
long[] mapIds = Longs.toArray(mapIdToReduceIds.keySet());
long[] mapIds = Longs.toArray(orderedMapId);
Comment thread
seayoun marked this conversation as resolved.
Outdated
int[][] reduceIdArr = new int[mapIds.length][];
for (int i = 0; i < mapIds.length; i++) {
reduceIdArr[i] = Ints.toArray(mapIdToReduceIds.get(mapIds[i]));
}

return new FetchShuffleBlocks(
appId, execId, shuffleId, mapIds, reduceIdArr, batchFetchEnabled);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,50 @@ public void testEmptyBlockFetch() {
}
}

@Test
public void testFetchShuffleBlocksOrder() {
LinkedHashMap<String, ManagedBuffer> blocks = Maps.newLinkedHashMap();
blocks.put("shuffle_0_0_0", new NioManagedBuffer(ByteBuffer.wrap(new byte[1])));
blocks.put("shuffle_0_2_1", new NioManagedBuffer(ByteBuffer.wrap(new byte[2])));
blocks.put("shuffle_0_10_2", new NettyManagedBuffer(Unpooled.wrappedBuffer(new byte[3])));
String[] blockIds = blocks.keySet().toArray(new String[blocks.size()]);

BlockFetchingListener listener = fetchBlocks(
blocks,
blockIds,
new FetchShuffleBlocks("app-id", "exec-id", 0, new long[]{0}, new int[][]{{0, 3}}, false),
conf);

for (int chunkIndex = 0; chunkIndex < blockIds.length; chunkIndex++) {
String blockId = blockIds[chunkIndex];
verify(listener).onBlockFetchSuccess(blockId, blocks.get(blockId));
}
}

@Test
public void testBatchFetchShuffleBlocksOrder() {
LinkedHashMap<String, ManagedBuffer> blocks = Maps.newLinkedHashMap();
blocks.put("shuffle_0_0_1_2", new NioManagedBuffer(ByteBuffer.wrap(new byte[1])));
blocks.put("shuffle_0_2_2_3", new NioManagedBuffer(ByteBuffer.wrap(new byte[2])));
blocks.put("shuffle_0_10_3_4", new NettyManagedBuffer(Unpooled.wrappedBuffer(new byte[3])));
String[] blockIds = blocks.keySet().toArray(new String[blocks.size()]);

BlockFetchingListener listener = fetchBlocks(
blocks,
blockIds,
new OpenBlocks("app-id", "exec-id", blockIds),
Comment thread
seayoun marked this conversation as resolved.
Outdated
new TransportConf("shuffle", new MapConfigProvider(
new HashMap<String, String>() {{
put("spark.shuffle.useOldFetchProtocol", "true");
}}
)));

for (int chunkIndex = 0; chunkIndex < blockIds.length; chunkIndex++) {
String blockId = blockIds[chunkIndex];
verify(listener).onBlockFetchSuccess(blockId, blocks.get(blockId));
}
}

/**
* Begins a fetch on the given set of blocks by mocking out the server side of the RPC which
* simply returns the given (BlockId, Block) pairs.
Expand Down