Skip to content

Commit 38885de

Browse files
kofemannmksahakyan
authored andcommitted
poolmanager: update wrandom partition to respect gap
Motivation: The wrandom partition ignores pool gap, thus can select a full pull. Issue: #7863 Modification: Update WRandomPartition to skip pools that will run into gap if accept the file. Added unit test to ensure the behavior. Result: full pulls are skipped by wrandom partition. Acked-by: Dmitry Litvintsev Target: master, 11.0, 10.2, 10.1, 10.0, 9.2 Require-book: no Require-notes: yes (cherry picked from commit a778f97) Signed-off-by: Tigran Mkrtchyan <[email protected]>
1 parent a59c6bb commit 38885de

File tree

2 files changed

+85
-6
lines changed

2 files changed

+85
-6
lines changed

modules/dcache/src/main/java/org/dcache/poolmanager/WRandomPartition.java

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
import java.security.SecureRandom;
77
import java.util.Arrays;
8-
import java.util.Collection;
98
import java.util.Collections;
109
import java.util.Comparator;
1110
import java.util.List;
@@ -84,27 +83,49 @@ public SelectedPool selectStagePool(CostModule cm, List<PoolInfo> pools, Optiona
8483

8584
@Override
8685
public SelectedPool selectWritePool(CostModule cm, List<PoolInfo> pools, FileAttributes attributes, long preallocated) throws CacheException {
87-
WeightedPool weightedPools[] = toWeightedWritePoolsArray(pools);
86+
WeightedPool weightedPools[] = toWeightedWritePoolsArray(pools, preallocated);
87+
if (weightedPools.length == 0) {
88+
throw new CostException("All pools are full", null, false, false);
89+
}
8890
int index = selectWrandomIndex(weightedPools);
8991
return new SelectedPool(weightedPools[index].getCostInfo());
9092
}
9193

92-
private WeightedPool[] toWeightedWritePoolsArray(Collection<PoolInfo> costInfos) {
94+
private WeightedPool[] toWeightedWritePoolsArray(List<PoolInfo> costInfos, long fileSize)
95+
throws CacheException {
9396

9497
long totalFree = 0;
98+
int validCount = 0;
9599
for (PoolInfo costInfo : costInfos) {
100+
long gap = costInfo.getCostInfo().getSpaceInfo().getGap();
101+
96102
long spaceToUse = costInfo.getCostInfo().getSpaceInfo().getFreeSpace()
97103
+ costInfo.getCostInfo().getSpaceInfo().getRemovableSpace();
104+
if (fileSize > spaceToUse - gap) {
105+
continue; // skip pools that do not have enough space
106+
}
98107
totalFree += spaceToUse;
108+
validCount++;
99109
}
100110

101-
WeightedPool[] weghtedPools = new WeightedPool[costInfos.size()];
102-
int i = 0;
103-
for (PoolInfo costInfo : costInfos) {
111+
// the validCount should macht the number of pools that have enough space, thus elegible for selection
112+
WeightedPool[] weghtedPools = new WeightedPool[validCount];
113+
114+
for (int i = 0; i < weghtedPools.length; /* incremented in the loop */) {
115+
var costInfo = costInfos.get(i);
116+
117+
long gap = costInfo.getCostInfo().getSpaceInfo().getGap();
118+
104119
long spaceToUse = costInfo.getCostInfo().getSpaceInfo().getFreeSpace()
105120
+ costInfo.getCostInfo().getSpaceInfo().getRemovableSpace();
106121

107122
weghtedPools[i] = new WeightedPool(costInfo, (double) spaceToUse / totalFree);
123+
if (fileSize > spaceToUse - gap) {
124+
continue; // skip pools that do not have enough space
125+
}
126+
127+
weghtedPools[i] = new WeightedPool(costInfo, (double) spaceToUse / totalFree);
128+
108129
i++;
109130
}
110131

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package org.dcache.poolmanager;
2+
3+
import com.google.common.collect.ImmutableMap;
4+
import diskCacheV111.pools.PoolCostInfo;
5+
import diskCacheV111.util.CacheException;
6+
import dmg.cells.nucleus.CellAddressCore;
7+
import org.hamcrest.MatcherAssert;
8+
import org.junit.Assert;
9+
import org.junit.Test;
10+
import org.mockito.AdditionalMatchers;
11+
12+
import java.util.Map;
13+
import java.util.stream.Collectors;
14+
import java.util.stream.IntStream;
15+
16+
import static org.junit.Assert.*;
17+
18+
public class WRandomPartitionTest {
19+
20+
21+
@Test(expected = CostException.class)
22+
public void shouldFailIfAllocatesIntoGap() throws CacheException {
23+
24+
var wrandom = new WRandomPartition(Map.of());
25+
var pools = IntStream.range(0, 10).mapToObj(i -> {
26+
var cost = new PoolCostInfo("pool" + i, "default-queue");
27+
cost.setSpaceUsage(10_000L, 3000L, 0L, 0L);
28+
cost.getSpaceInfo().setParameter(0.0d, 2500L);
29+
30+
return new PoolInfo(new CellAddressCore("pool" + i), cost, ImmutableMap.of());
31+
}
32+
).collect(Collectors.toList());
33+
34+
long fileSize = 1000L;
35+
var selectedPool = wrandom.selectWritePool(null, pools, null, fileSize);
36+
}
37+
38+
@Test
39+
public void shouldSelectValidPool() throws CacheException {
40+
41+
var wrandom = new WRandomPartition(Map.of());
42+
var pools = IntStream.range(0, 10).mapToObj(i -> {
43+
var cost = new PoolCostInfo("pool" + i, "default-queue");
44+
cost.setSpaceUsage(10_000L, 5000L, 0L, 0L);
45+
cost.getSpaceInfo().setParameter(0.0d, 2500L);
46+
47+
return new PoolInfo(new CellAddressCore("pool" + i), cost, ImmutableMap.of());
48+
}
49+
).collect(Collectors.toList());
50+
51+
long fileSize = 1000L;
52+
var selectedPool = wrandom.selectWritePool(null, pools, null, fileSize);
53+
54+
var spaceInfo = selectedPool.info().getCostInfo().getSpaceInfo();
55+
assertTrue("selected pool has no sufficient space", spaceInfo.getFreeSpace() + spaceInfo.getRemovableSpace() - fileSize > spaceInfo.getGap());
56+
}
57+
58+
}

0 commit comments

Comments
 (0)