Sharding Pattern (#1056)

* Create sharding module

* Add Unit Tests

* Fix readme hyperlink

* Fix check-style issue
This commit is contained in:
Azureyjt
2019-11-08 14:20:32 +08:00
committed by Ilkka Seppälä
parent 50986fa15b
commit 1fa8a604eb
16 changed files with 1010 additions and 0 deletions

View File

@ -0,0 +1,88 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.sharding;
/**
* Sharding pattern means dividing a data store into a set of horizontal partitions
* or shards. This pattern can improve scalability when storing and accessing large
* volumes of data.
*/
public class App {
/**
* Program main entry point.
* @param args program runtime arguments
*/
public static void main(String[] args) {
var data1 = new Data(1, "data1", Data.DataType.type1);
var data2 = new Data(2, "data2", Data.DataType.type2);
var data3 = new Data(3, "data3", Data.DataType.type3);
var data4 = new Data(4, "data4", Data.DataType.type1);
var shard1 = new Shard(1);
var shard2 = new Shard(2);
var shard3 = new Shard(3);
ShardManager manager = new LookupShardManager();
manager.addNewShard(shard1);
manager.addNewShard(shard2);
manager.addNewShard(shard3);
manager.storeData(data1);
manager.storeData(data2);
manager.storeData(data3);
manager.storeData(data4);
shard1.clearData();
shard2.clearData();
shard3.clearData();
manager = new RangeShardManager();
manager.addNewShard(shard1);
manager.addNewShard(shard2);
manager.addNewShard(shard3);
manager.storeData(data1);
manager.storeData(data2);
manager.storeData(data3);
manager.storeData(data4);
shard1.clearData();
shard2.clearData();
shard3.clearData();
manager = new HashShardManager();
manager.addNewShard(shard1);
manager.addNewShard(shard2);
manager.addNewShard(shard3);
manager.storeData(data1);
manager.storeData(data2);
manager.storeData(data3);
manager.storeData(data4);
shard1.clearData();
shard2.clearData();
shard3.clearData();
}
}

View File

@ -0,0 +1,84 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.sharding;
/**
* Basic data structure for each tuple stored in data shards.
*/
public class Data {
private int key;
private String value;
private DataType type;
/**
* Constructor of Data class.
* @param key data key
* @param value data vlue
* @param type data type
*/
public Data(final int key, final String value, final DataType type) {
this.key = key;
this.value = value;
this.type = type;
}
public int getKey() {
return key;
}
public void setKey(final int key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(final String value) {
this.value = value;
}
public DataType getType() {
return type;
}
public void setType(DataType type) {
this.type = type;
}
enum DataType {
type1, type2, type3
}
@Override
public String toString() {
return "Data {" + "key="
+ key + ", value='" + value
+ '\'' + ", type=" + type + '}';
}
}

View File

@ -0,0 +1,55 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.sharding;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* ShardManager with hash strategy. The purpose of this strategy is to reduce the
* chance of hot-spots in the data. It aims to distribute the data across the shards
* in a way that achieves a balance between the size of each shard and the average
* load that each shard will encounter.
*/
public class HashShardManager extends ShardManager {
private static final Logger LOGGER = LoggerFactory.getLogger(HashShardManager.class);
@Override
public int storeData(Data data) {
var shardId = allocateShard(data);
var shard = shardMap.get(shardId);
shard.storeData(data);
LOGGER.info(data.toString() + " is stored in Shard " + shardId);
return shardId;
}
@Override
protected int allocateShard(Data data) {
var shardCount = shardMap.size();
var hash = data.getKey() % shardCount;
return hash == 0 ? hash + shardCount : hash;
}
}

View File

@ -0,0 +1,66 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.sharding;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* ShardManager with lookup strategy. In this strategy the sharding logic implements
* a map that routes a request for data to the shard that contains that data by using
* the shard key.
*/
public class LookupShardManager extends ShardManager {
private static final Logger LOGGER = LoggerFactory.getLogger(LookupShardManager.class);
private Map<Integer, Integer> lookupMap = new HashMap<>();
@Override
public int storeData(Data data) {
var shardId = allocateShard(data);
lookupMap.put(data.getKey(), shardId);
var shard = shardMap.get(shardId);
shard.storeData(data);
LOGGER.info(data.toString() + " is stored in Shard " + shardId);
return shardId;
}
@Override
protected int allocateShard(Data data) {
var key = data.getKey();
if (lookupMap.containsKey(key)) {
return lookupMap.get(key);
} else {
var shardCount = shardMap.size();
var allocatedShardId = new Random().nextInt(shardCount - 1) + 1;
return allocatedShardId;
}
}
}

View File

@ -0,0 +1,66 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.sharding;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* ShardManager with range strategy. This strategy groups related items together
* in the same shard, and orders them by shard key.
*/
public class RangeShardManager extends ShardManager {
private static final Logger LOGGER = LoggerFactory.getLogger(RangeShardManager.class);
@Override
public int storeData(Data data) {
var shardId = allocateShard(data);
var shard = shardMap.get(shardId);
shard.storeData(data);
LOGGER.info(data.toString() + " is stored in Shard " + shardId);
return shardId;
}
@Override
protected int allocateShard(Data data) {
var type = data.getType();
var shardId = -1;
switch (type) {
case type1:
shardId = 1;
break;
case type2:
shardId = 2;
break;
case type3:
shardId = 3;
break;
default:
break;
}
return shardId;
}
}

View File

@ -0,0 +1,59 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.sharding;
import java.util.HashMap;
import java.util.Map;
/**
* The Shard class stored data in a HashMap.
*/
public class Shard {
private final int id;
private Map<Integer, Data> dataStore;
public Shard(final int id) {
this.id = id;
this.dataStore = new HashMap<>();
}
public void storeData(Data data) {
dataStore.put(data.getKey(), data);
}
public void clearData() {
dataStore.clear();
}
public Data getDataById(final int id) {
return dataStore.get(id);
}
public int getId() {
return id;
}
}

View File

@ -0,0 +1,103 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.sharding;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Abstract class for ShardManager.
*/
public abstract class ShardManager {
private static final Logger LOGGER = LoggerFactory.getLogger(ShardManager.class);
protected Map<Integer, Shard> shardMap;
public ShardManager() {
shardMap = new HashMap<>();
}
/**
* Add a provided shard instance to shardMap.
*
* @param shard new shard instance.
* @return {@code true} if succeed to add the new instance.
* {@code false} if the shardId is already existed.
*/
public boolean addNewShard(final Shard shard) {
var shardId = shard.getId();
if (!shardMap.containsKey(shardId)) {
shardMap.put(shardId, shard);
return true;
} else {
return false;
}
}
/**
* Remove a shard instance by provided Id.
*
* @param shardId Id of shard instance to remove.
* @return {@code true} if removed. {@code false} if the shardId is not existed.
*/
public boolean removeShardById(final int shardId) {
if (shardMap.containsKey(shardId)) {
shardMap.remove(shardId);
return true;
} else {
return false;
}
}
/**
* Get shard instance by provided shardId.
*
* @param shardId id of shard instance to get
* @return required shard instance
*/
public Shard getShardById(final int shardId) {
return shardMap.get(shardId);
}
/**
* Store data in proper shard instance.
*
* @param data new data
* @return id of shard that the data is stored in
*/
public abstract int storeData(final Data data);
/**
* Allocate proper shard to provided data.
*
* @param data new data
* @return id of shard that the data should be stored
*/
protected abstract int allocateShard(final Data data);
}

View File

@ -0,0 +1,39 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.sharding;
import org.junit.Test;
/**
* Unit tests for App class.
*/
public class AppTest {
@Test
public void testMain() {
String[] args = {};
App.main(args);
}
}

View File

@ -0,0 +1,64 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.sharding;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* Unit tests for HashShardManager class.
*/
public class HashShardManagerTest {
private HashShardManager hashShardManager;
/**
* Initialize hashShardManager instance.
*/
@Before
public void setup() {
hashShardManager = new HashShardManager();
var shard1 = new Shard(1);
var shard2 = new Shard(2);
var shard3 = new Shard(3);
hashShardManager.addNewShard(shard1);
hashShardManager.addNewShard(shard2);
hashShardManager.addNewShard(shard3);
}
@After
public void tearDown() {
}
@Test
public void testStoreData() {
var data = new Data(1, "test", Data.DataType.type1);
hashShardManager.storeData(data);
Assert.assertEquals(data, hashShardManager.getShardById(1).getDataById(1));
}
}

View File

@ -0,0 +1,68 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.sharding;
import java.util.Map;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* Unit tests for LookupShardManager class.
*/
public class LookupShardManagerTest {
private LookupShardManager lookupShardManager;
/**
* Initialize lookupShardManager instance.
*/
@Before
public void setup() {
lookupShardManager = new LookupShardManager();
var shard1 = new Shard(1);
var shard2 = new Shard(2);
var shard3 = new Shard(3);
lookupShardManager.addNewShard(shard1);
lookupShardManager.addNewShard(shard2);
lookupShardManager.addNewShard(shard3);
}
@Test
public void testStoreData() {
try {
var data = new Data(1, "test", Data.DataType.type1);
lookupShardManager.storeData(data);
var field = LookupShardManager.class.getDeclaredField("lookupMap");
field.setAccessible(true);
Map<Integer, Integer> lookupMap = (Map<Integer, Integer>) field.get(lookupShardManager);
var shardId = lookupMap.get(1);
var shard = lookupShardManager.getShardById(shardId);
Assert.assertEquals(data, shard.getDataById(1));
} catch (NoSuchFieldException | IllegalAccessException e) {
Assert.fail("Fail to modify field access.");
}
}
}

View File

@ -0,0 +1,58 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.sharding;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* Unit tests for RangeShardManager class.
*/
public class RangeShardManagerTest {
private RangeShardManager rangeShardManager;
/**
* Initialize rangeShardManager instance.
*/
@Before
public void setup() {
rangeShardManager = new RangeShardManager();
var shard1 = new Shard(1);
var shard2 = new Shard(2);
var shard3 = new Shard(3);
rangeShardManager.addNewShard(shard1);
rangeShardManager.addNewShard(shard2);
rangeShardManager.addNewShard(shard3);
}
@Test
public void testStoreData() {
var data = new Data(1, "test", Data.DataType.type1);
rangeShardManager.storeData(data);
Assert.assertEquals(data, rangeShardManager.getShardById(1).getDataById(1));
}
}

View File

@ -0,0 +1,104 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.sharding;
import java.util.Map;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* Unit tests for ShardManager class.
*/
public class ShardManagerTest {
private ShardManager shardManager;
/**
* Initialize shardManager instance.
*/
@Before
public void setup() {
shardManager = new TestShardManager();
}
@After
public void tearDown() {
}
@Test
public void testAddNewShard() {
try {
var shard = new Shard(1);
shardManager.addNewShard(shard);
var field = ShardManager.class.getDeclaredField("shardMap");
field.setAccessible(true);
Map<Integer, Shard> map = (Map<Integer, Shard>) field.get(shardManager);
Assert.assertEquals(1, map.size());
Assert.assertEquals(shard, map.get(1));
} catch (NoSuchFieldException | IllegalAccessException e) {
Assert.fail("Fail to modify field access.");
}
}
@Test
public void testRemoveShardById() {
try {
var shard = new Shard(1);
shardManager.addNewShard(shard);
boolean flag = shardManager.removeShardById(1);
var field = ShardManager.class.getDeclaredField("shardMap");
field.setAccessible(true);
Map<Integer, Shard> map = (Map<Integer, Shard>) field.get(shardManager);
Assert.assertEquals(true, flag);
Assert.assertEquals(0, map.size());
} catch (IllegalAccessException | NoSuchFieldException e) {
Assert.fail("Fail to modify field access.");
}
}
@Test
public void testGetShardById() {
Shard shard = new Shard(1);
shardManager.addNewShard(shard);
Shard tmpShard = shardManager.getShardById(1);
Assert.assertEquals(shard, tmpShard);
}
class TestShardManager extends ShardManager {
@Override
public int storeData(Data data) {
return 0;
}
@Override
protected int allocateShard(Data data) {
return 0;
}
}
}

View File

@ -0,0 +1,83 @@
/*
* The MIT License
* Copyright © 2014-2019 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.sharding;
import java.util.HashMap;
import java.util.Map;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* Unit tests for Shard class.
*/
public class ShardTest {
private Data data;
private Shard shard;
@Before
public void setup() {
data = new Data(1, "test", Data.DataType.type1);
shard = new Shard(1);
}
@After
public void tearDown() {}
@Test
public void testStoreData() {
try {
shard.storeData(data);
var field = Shard.class.getDeclaredField("dataStore");
field.setAccessible(true);
Map<Integer, Data> dataMap = (Map<Integer, Data>) field.get(shard);
Assert.assertEquals(1, dataMap.size());
Assert.assertEquals(data, dataMap.get(1));
} catch (NoSuchFieldException | IllegalAccessException e) {
Assert.fail("Fail to modify field access.");
}
}
@Test
public void testClearData() {
try {
Map<Integer, Data> dataMap = new HashMap<>();
dataMap.put(1, data);
var field = Shard.class.getDeclaredField("dataStore");
field.setAccessible(true);
field.set(shard, dataMap);
shard.clearData();
dataMap = (Map<Integer, Data>) field.get(shard);
Assert.assertEquals(0, dataMap.size());
} catch (NoSuchFieldException | IllegalAccessException e) {
Assert.fail("Fail to modify field access.");
}
}
}