Skip to content
Snippets Groups Projects
Commit 5c3273f7 authored by felmer's avatar felmer
Browse files

LMS-2167 SpeedOptimizedShareFinder introduced and tested

SVN: 21013
parent 405f104b
No related branches found
No related tags found
No related merge requests found
Showing
with 295 additions and 41 deletions
...@@ -24,6 +24,7 @@ import org.apache.commons.io.FileUtils; ...@@ -24,6 +24,7 @@ import org.apache.commons.io.FileUtils;
import ch.rinn.restrictions.Private; import ch.rinn.restrictions.Private;
import ch.systemsx.cisd.common.utilities.PropertyUtils; import ch.systemsx.cisd.common.utilities.PropertyUtils;
import ch.systemsx.cisd.openbis.dss.generic.shared.AbstractShareFinder; import ch.systemsx.cisd.openbis.dss.generic.shared.AbstractShareFinder;
import ch.systemsx.cisd.openbis.dss.generic.shared.ISpeedChecker;
import ch.systemsx.cisd.openbis.dss.generic.shared.utils.Share; import ch.systemsx.cisd.openbis.dss.generic.shared.utils.Share;
import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO; import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO;
......
...@@ -29,44 +29,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO; ...@@ -29,44 +29,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO;
*/ */
public abstract class AbstractShareFinder implements IShareFinder public abstract class AbstractShareFinder implements IShareFinder
{ {
/**
* Returns <code>true</code> if speed of specified share and speed hint of specified data set
* are allowed.
*
* @author Franz-Josef Elmer
*/
public static interface ISpeedChecker
{
boolean check(SimpleDataSetInformationDTO dataSet, Share share);
}
private enum SpeedChecker implements ISpeedChecker
{
MATCHING_CHECKER()
{
public boolean check(SimpleDataSetInformationDTO dataSet, Share share)
{
return Math.abs(dataSet.getSpeedHint()) == share.getSpeed();
}
},
RESPECTUNG_SPEED_HINT_CHECKER()
{
public boolean check(SimpleDataSetInformationDTO dataSet, Share share)
{
int speedHint = dataSet.getSpeedHint();
int speed = share.getSpeed();
return speedHint < 0 ? speed < Math.abs(speedHint) : speed > speedHint;
}
},
IGNORING_SPEED_HINT_CHECKER()
{
public boolean check(SimpleDataSetInformationDTO dataSet, Share share)
{
return true;
}
}
}
/** /**
* Tries to find a share fulfilling speed hint contract. * Tries to find a share fulfilling speed hint contract.
*/ */
......
package ch.systemsx.cisd.openbis.dss.generic.shared;
import ch.systemsx.cisd.openbis.dss.generic.shared.utils.Share;
import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO;
/**
* Returns <code>true</code> if speed of specified share and speed hint of specified data set
* are allowed.
*
* @author Franz-Josef Elmer
*/
public interface ISpeedChecker
{
public boolean check(SimpleDataSetInformationDTO dataSet, Share share);
}
\ No newline at end of file
/*
* Copyright 2011 ETH Zuerich, CISD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.systemsx.cisd.openbis.dss.generic.shared;
import ch.systemsx.cisd.openbis.dss.generic.shared.utils.Share;
import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO;
/**
* Enumeration of {@link ISpeedChecker} ordered in accordance to strictness.
*
*
* @author Franz-Josef Elmer
*/
public enum SpeedChecker implements ISpeedChecker
{
MATCHING_CHECKER()
{
public boolean check(SimpleDataSetInformationDTO dataSet, Share share)
{
return Math.abs(dataSet.getSpeedHint()) == share.getSpeed();
}
},
RESPECTUNG_SPEED_HINT_CHECKER()
{
public boolean check(SimpleDataSetInformationDTO dataSet, Share share)
{
int speedHint = dataSet.getSpeedHint();
int speed = share.getSpeed();
return speedHint < 0 ? speed < Math.abs(speedHint) : speed > speedHint;
}
},
IGNORING_SPEED_HINT_CHECKER()
{
public boolean check(SimpleDataSetInformationDTO dataSet, Share share)
{
return true;
}
}
}
\ No newline at end of file
/*
* Copyright 2011 ETH Zuerich, CISD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.systemsx.cisd.openbis.dss.generic.shared;
import java.util.List;
import java.util.Properties;
import ch.systemsx.cisd.openbis.dss.generic.shared.utils.Share;
import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO;
/**
* A share finder which first searches for the extension share with most free space which matches
* speed. If nothing found it does the same also for all extension shares but speed needs not to
* match but speed hint needs to be respected. If this isn't working {@link SimpleShareFinder} is
* used ignoring speed hint.
*
* @author Franz-Josef Elmer
*/
public class SpeedOptimizedShareFinder implements IShareFinder
{
private final SimpleShareFinder simpleFinder;
public SpeedOptimizedShareFinder(Properties properties)
{
simpleFinder = new SimpleShareFinder(properties);
}
public Share tryToFindShare(SimpleDataSetInformationDTO dataSet, List<Share> shares)
{
Share share = tryToFindeExtensionShare(dataSet, shares, SpeedChecker.MATCHING_CHECKER);
if (share != null)
{
return share;
}
share =
tryToFindeExtensionShare(dataSet, shares,
SpeedChecker.RESPECTUNG_SPEED_HINT_CHECKER);
if (share != null)
{
return share;
}
return simpleFinder.tryToFindShare(dataSet, shares,
SpeedChecker.IGNORING_SPEED_HINT_CHECKER);
}
private Share tryToFindeExtensionShare(SimpleDataSetInformationDTO dataSet, List<Share> shares,
ISpeedChecker speedChecker)
{
Share result = null;
long maxFreeSpace = dataSet.getDataSetSize();
for (Share share : shares)
{
if (share.isIncoming() || speedChecker.check(dataSet, share) == false)
{
continue;
}
long freeSpace = share.calculateFreeSpace();
if (freeSpace > maxFreeSpace)
{
maxFreeSpace = freeSpace;
result = share;
}
}
return result;
}
}
...@@ -36,7 +36,7 @@ import ch.rinn.restrictions.Friend; ...@@ -36,7 +36,7 @@ import ch.rinn.restrictions.Friend;
import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel; import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel;
import ch.systemsx.cisd.common.filesystem.HostAwareFile; import ch.systemsx.cisd.common.filesystem.HostAwareFile;
import ch.systemsx.cisd.common.filesystem.IFreeSpaceProvider; import ch.systemsx.cisd.common.filesystem.IFreeSpaceProvider;
import ch.systemsx.cisd.openbis.dss.generic.shared.AbstractShareFinder; import ch.systemsx.cisd.openbis.dss.generic.shared.ISpeedChecker;
import ch.systemsx.cisd.openbis.dss.generic.shared.utils.Share; import ch.systemsx.cisd.openbis.dss.generic.shared.utils.Share;
import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO; import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO;
...@@ -50,7 +50,7 @@ public class SimpleShufflingShareFinderTest extends AssertJUnit ...@@ -50,7 +50,7 @@ public class SimpleShufflingShareFinderTest extends AssertJUnit
{ {
private static final String DATA_SET_CODE = "ds-1"; private static final String DATA_SET_CODE = "ds-1";
private static final class MockSpeedChecker implements AbstractShareFinder.ISpeedChecker private static final class MockSpeedChecker implements ISpeedChecker
{ {
private final boolean[] checkingResults; private final boolean[] checkingResults;
......
...@@ -40,7 +40,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO; ...@@ -40,7 +40,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO;
*/ */
public class SimpleShareFinderTest extends AssertJUnit public class SimpleShareFinderTest extends AssertJUnit
{ {
private static final class MockSpeedChecker implements AbstractShareFinder.ISpeedChecker private static final class MockSpeedChecker implements ISpeedChecker
{ {
private final boolean[] checkingResults; private final boolean[] checkingResults;
......
/*
* Copyright 2011 ETH Zuerich, CISD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.systemsx.cisd.openbis.dss.generic.shared;
import static org.apache.commons.io.FileUtils.ONE_MB;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Properties;
import org.apache.commons.io.FileUtils;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.testng.AssertJUnit;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel;
import ch.systemsx.cisd.common.filesystem.HostAwareFile;
import ch.systemsx.cisd.common.filesystem.IFreeSpaceProvider;
import ch.systemsx.cisd.openbis.dss.generic.shared.utils.Share;
import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO;
/**
*
*
* @author Franz-Josef Elmer
*/
public class SpeedOptimizedShareFinderTest extends AssertJUnit
{
private static final String DATA_SET_CODE = "ds-1";
private SpeedOptimizedShareFinder finder;
private Mockery context;
private IFreeSpaceProvider freeSpaceProvider;
private SimpleDataSetInformationDTO dataSet;
@BeforeMethod
public void setUp()
{
context = new Mockery();
freeSpaceProvider = context.mock(IFreeSpaceProvider.class);
dataSet = new SimpleDataSetInformationDTO();
dataSet.setDataSetCode(DATA_SET_CODE);
dataSet.setDataSetSize(FileUtils.ONE_MB);
finder = new SpeedOptimizedShareFinder(new Properties());
}
@AfterMethod
public void tearDown(Method method)
{
try
{
context.assertIsSatisfied();
} catch (Throwable t)
{
// assert expectations were met, including the name of the failed method
throw new Error(method.getName() + "() : ", t);
}
}
@Test
public void testFindMatchingExtensionShare()
{
dataSet.setSpeedHint(-50);
Share s1 = share(false, 50, 10 * ONE_MB);
Share s2 = share(true, 50, 0);
Share s3 = share(false, 40, 0);
Share s4 = share(false, 50, 11 * ONE_MB);
Share foundShare = finder.tryToFindShare(dataSet, Arrays.asList(s1, s2, s3, s4));
assertSame(s4.getShare(), foundShare.getShare());
}
@Test
public void testFindExtensionShareRespectingSpeedHint()
{
dataSet.setSpeedHint(-50);
Share s1 = share(false, 49, 10 * ONE_MB);
Share s2 = share(true, 50, 0);
Share s3 = share(false, 40, 11 * ONE_MB);
Share foundShare = finder.tryToFindShare(dataSet, Arrays.asList(s1, s2, s3));
assertSame(s3.getShare(), foundShare.getShare());
}
@Test
public void testFindShareIgnoringSpeedHint()
{
dataSet.setSpeedHint(-50);
dataSet.setDataSetShareId("20");
Share s1 = share(false, 51, 10 * ONE_MB);
Share s2 = share(true, 50, 20 * ONE_MB);
Share s3 = share(false, 60, 11 * ONE_MB);
Share s4 = share(true, 50, 15 * ONE_MB);
Share foundShare = finder.tryToFindShare(dataSet, Arrays.asList(s1, s2, s3, s4));
assertSame(s3.getShare(), foundShare.getShare());
}
private Share share(boolean incoming, int speed, final long freeSpace)
{
final File file = new File(Integer.toString(speed) + "/" + incoming + "/" + freeSpace);
if (freeSpace > 0)
{
context.checking(new Expectations()
{
{
try
{
one(freeSpaceProvider).freeSpaceKb(new HostAwareFile(file));
will(returnValue(freeSpace / FileUtils.ONE_KB));
} catch (IOException ex)
{
throw CheckedExceptionTunnel.wrapIfNecessary(ex);
}
}
});
}
Share share = new Share(file, speed, freeSpaceProvider);
share.setIncoming(incoming);
return share;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment