diff --git a/pom.xml b/pom.xml index b4c0aac..616014c 100644 --- a/pom.xml +++ b/pom.xml @@ -26,6 +26,12 @@ 5.8.1 test + + org.assertj + assertj-core + 3.24.2 + test + \ No newline at end of file diff --git a/src/main/java/org/redis/Main.java b/src/main/java/org/redis/Main.java index 68b3db6..ec2b674 100644 --- a/src/main/java/org/redis/Main.java +++ b/src/main/java/org/redis/Main.java @@ -1,7 +1,57 @@ package org.redis; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +import java.util.HashMap; +import java.util.Map; + public class Main { public static void main(String[] args) { - System.out.println("Hello world!"); + JedisPoolConfig poolConfig = new JedisPoolConfig(); + try (JedisPool pool = new JedisPool(poolConfig, "localhost", 6379)) { + RedisMap map = new RedisMap(pool, "demo"); + + System.out.println("\n--- put / get / size ---"); + System.out.println("put(a, 1) returned: " + map.put("a", "1")); + System.out.println("get(a) = " + map.get("a")); + System.out.println("size = " + map.size()); + + System.out.println("\n--- overwrite ---"); + System.out.println("put(a, 100) returned previous: " + map.put("a", "100")); + System.out.println("get(a) = " + map.get("a")); + + System.out.println("\n--- add more keys ---"); + map.put("b", "2"); + map.put("c", "3"); + System.out.println("size = " + map.size()); + System.out.println("containsKey(\"b\") = " + map.containsKey("b")); + System.out.println("containsValue(\"2\") = " + map.containsValue("2")); + + System.out.println("\n--- keySet / values / entrySet ---"); + System.out.println("keySet = " + map.keySet()); + System.out.println("values = " + map.values()); + System.out.println("entrySet = " + map.entrySet()); + + System.out.println("\n--- putAll ---"); + Map toPut = new HashMap<>(); + toPut.put("x", "10"); + toPut.put("y", "20"); + map.putAll(toPut); + System.out.println("After putAll, size = " + map.size()); + System.out.println("entrySet = " + map.entrySet()); + + System.out.println("\n--- remove ---"); + System.out.println("remove(\"b\") returned: " + map.remove("b")); + System.out.println("containsKey(\"b\") = " + map.containsKey("b")); + System.out.println("keySet = " + map.keySet()); + + System.out.println("\n--- clear ---"); + map.clear(); + System.out.println("After clear, size = " + map.size()); + System.out.println("keySet = " + map.keySet()); + } catch (Exception e) { + System.err.println("Ошибка в работе RedisMap: " + e.getMessage()); + } } } \ No newline at end of file diff --git a/src/main/java/org/redis/RedisMap.java b/src/main/java/org/redis/RedisMap.java new file mode 100644 index 0000000..f9ed0fc --- /dev/null +++ b/src/main/java/org/redis/RedisMap.java @@ -0,0 +1,136 @@ +package org.redis; + +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; + +import java.util.*; +import java.util.stream.Collectors; + +public class RedisMap implements Map { + + private final JedisPool pool; + private final String redisHashKey; + + public RedisMap(JedisPool pool, String mapName) { + Objects.requireNonNull(pool, "JedisPool пустой"); + Objects.requireNonNull(mapName, "mapName пустое"); + this.pool = pool; + this.redisHashKey = "map:" + mapName; + } + + @Override + public int size() { + try (Jedis jedis = pool.getResource()) { + long len = jedis.hlen(redisHashKey); + return (int) len; + } + } + + @Override + public boolean isEmpty() { + return size() == 0; + } + + @Override + public boolean containsKey(Object key) { + if (key == null) { + return false; + } + try (Jedis jedis = pool.getResource()) { + return jedis.hexists(redisHashKey, key.toString()); + } + } + + @Override + public boolean containsValue(Object value) { + if (value == null) { + return false; + } + try (Jedis jedis = pool.getResource()) { + List values = jedis.hvals(redisHashKey); + return values.contains(value.toString()); + } + } + + @Override + public String get(Object key) { + if (key == null) { + return null; + } + try (Jedis jedis = pool.getResource()) { + return jedis.hget(redisHashKey, key.toString()); + } + } + + @Override + public String put(String key, String value) { + Objects.requireNonNull(key, "Пустой ключ"); + Objects.requireNonNull(key, "Пустое значение"); + try (Jedis jedis = pool.getResource()) { + String prev = jedis.hget(redisHashKey, key); + jedis.hset(redisHashKey, key, value); + return prev; + } + } + + @Override + public String remove(Object key) { + if (key == null) { + return null; + } + try (Jedis jedis = pool.getResource()) { + String prev = jedis.hget(redisHashKey, key.toString()); + jedis.hdel(redisHashKey, key.toString()); + return prev; + } + } + + @Override + public void putAll(Map m) { + if (m == null || m.isEmpty()) { + return; + } + try (Jedis jedis = pool.getResource()) { + Map toStore = new HashMap<>(); + for (Entry e : m.entrySet()) { + if (e.getKey() == null) { + throw new NullPointerException("Словарь содержит пустой ключ"); + } + toStore.put(e.getKey(), e.getValue()); + } + jedis.hset(redisHashKey, toStore); + } + } + + @Override + public void clear() { + try (Jedis jedis = pool.getResource()) { + jedis.del(redisHashKey); + } + } + + @Override + public Set keySet() { + try (Jedis jedis = pool.getResource()) { + return new HashSet<>(jedis.hkeys(redisHashKey)); + } + } + + @Override + public Collection values() { + try (Jedis jedis = pool.getResource()) { + return new ArrayList<>(jedis.hvals(redisHashKey)); + } + } + + @Override + public Set> entrySet() { + try (Jedis jedis = pool.getResource()) { + Map all = jedis.hgetAll(redisHashKey); + return all.entrySet().stream() + .map(e -> new AbstractMap.SimpleEntry<>(e.getKey(), e.getValue())) + .collect(Collectors.toUnmodifiableSet()); + } + } + +} diff --git a/src/test/java/org/redis/RedisMapTest.java b/src/test/java/org/redis/RedisMapTest.java new file mode 100644 index 0000000..072fdb2 --- /dev/null +++ b/src/test/java/org/redis/RedisMapTest.java @@ -0,0 +1,111 @@ +package org.redis; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +import java.util.*; + +import static org.junit.jupiter.api.Assertions.*; + +public class RedisMapTest { + + private JedisPool pool; + private RedisMap map; + + @BeforeEach + public void beforeEach() { + pool = new JedisPool(new JedisPoolConfig(), "localhost", 6379); + String MAP_NAME = "testMap"; + map = new RedisMap(pool, MAP_NAME); + map.clear(); + } + + private void closePool() { + if (pool != null) { + pool.close(); + } + } + + @Test + public void testPutAndGet() { + assertNull(map.put("a", "1")); + assertEquals("1", map.get("a")); + assertEquals(1, map.size()); + assertTrue(map.containsKey("a")); + assertTrue(map.containsValue("1")); + + closePool(); + } + + @Test + public void testRemove() { + map.put("k", "v"); + + assertEquals("v", map.remove("k")); + assertNull(map.get("k")); + assertFalse(map.containsKey("k")); + + closePool(); + } + + @Test + public void testPutAllAndSize() { + Map m = new HashMap<>(); + m.put("x", "10"); + m.put("y", "20"); + + map.putAll(m); + + assertEquals(2, map.size()); + assertEquals("10", map.get("x")); + assertEquals("20", map.get("y")); + + closePool(); + } + + @Test + public void testClearAndIsEmpty() { + map.put("one", "1"); + map.clear(); + + assertTrue(map.isEmpty()); + assertEquals(0, map.size()); + + closePool(); + } + + @Test + public void testKeySetValuesEntrySet() { + map.put("k1", "v1"); + map.put("k2", "v2"); + + Set keys = map.keySet(); + + assertEquals(new HashSet<>(Arrays.asList("k1", "k2")), keys); + Collection values = map.values(); + assertTrue(values.containsAll(Arrays.asList("v1", "v2"))); + assertEquals(2, values.size()); + Set> entries = map.entrySet(); + Map snapshot = new HashMap<>(); + for (Map.Entry e : entries) { + snapshot.put(e.getKey(), e.getValue()); + } + assertEquals(2, snapshot.size()); + assertEquals("v1", snapshot.get("k1")); + + closePool(); + } + + @Test + public void testOverwritePutReturnsPrevious() { + map.put("a", "1"); + + assertEquals("1", map.put("a", "2")); + assertEquals("2", map.get("a")); + + closePool(); + } + +} \ No newline at end of file