Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 163 additions & 0 deletions src/main/java/org/redis/RedisMap.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package org.redis;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.*;

public class RedisMap implements Map<String, String>, AutoCloseable {

private final JedisPool pool;
private final String redisKey;

public RedisMap(JedisPool pool, String redisKey) {
Objects.requireNonNull(pool, "JedisPool не должен быть null");
Objects.requireNonNull(redisKey, "redisKey не должен быть null");
this.pool = pool;
this.redisKey = redisKey;
}

private void requireNonNullKey(Object key) {
if (key == null) {
throw new NullPointerException("null ключи не поддерживаются");
}
}

private void requireNonNullValue(Object value) {
if (value == null) {
throw new NullPointerException("null значения не поддерживаются");
}
}

@Override
public void close() {
pool.close();
}

@Override
public int size() {
try (Jedis jedis = pool.getResource()) {
Long l = jedis.hlen(redisKey);
return l.intValue();
}
}

@Override
public boolean isEmpty() {
return size() == 0;
}

@Override
public boolean containsKey(Object key) {
requireNonNullKey(key);
try (Jedis jedis = pool.getResource()) {
return jedis.hexists(redisKey, key.toString());
}
}

@Override
public boolean containsValue(Object value) {
requireNonNullValue(value);
try (Jedis jedis = pool.getResource()) {
List<String> values = jedis.hvals(redisKey);
return values.contains(value.toString());
}
}

@Override
public String get(Object key) {
requireNonNullKey(key);
try (Jedis jedis = pool.getResource()) {
return jedis.hget(redisKey, key.toString());
}
}

@Override
public String put(String key, String value) {
requireNonNullKey(key);
requireNonNullValue(value);
try (Jedis jedis = pool.getResource()) {
String previous = jedis.hget(redisKey, key.toString());
jedis.hset(redisKey, key, value);
return previous;
}
}

@Override
public String remove(Object key) {
requireNonNullKey(key);
try (Jedis jedis = pool.getResource()) {
String previous = jedis.hget(redisKey, key.toString());
jedis.hdel(redisKey, key.toString());
return previous;
}
}

@Override
public void putAll(Map<? extends String, ? extends String> m) {
Objects.requireNonNull(m, "map не должна быть null");
if (m.isEmpty()) return;
Map<String, String> toSet = new HashMap<>();
for (Entry<? extends String, ? extends String> entry : m.entrySet()) {
if (entry.getKey() == null) throw new NullPointerException("null ключи не поддерживаются");
if (entry.getValue() == null) throw new NullPointerException("null значения не поддерживаются");
toSet.put(entry.getKey(), entry.getValue());
}
try (Jedis jedis = pool.getResource()) {
jedis.hmset(redisKey, toSet);
}

}

@Override
public void clear() {
try (Jedis jedis = pool.getResource()) {
jedis.del(redisKey);
}
}

@Override
public Set<String> keySet() {
try (Jedis jedis = pool.getResource()) {
return new HashSet<>(jedis.hkeys(redisKey));
}
}

@Override
public Collection<String> values() {
try (Jedis jedis = pool.getResource()) {
return new ArrayList<>(jedis.hvals(redisKey));
}
}

@Override
public Set<Entry<String, String>> entrySet() {
try (Jedis jedis = pool.getResource()) {
Map<String, String> all = jedis.hgetAll(redisKey);
Set<Entry<String, String>> entries = new HashSet<>();
for (Map.Entry<String, String> entry : all.entrySet()) {
entries.add(new AbstractMap.SimpleEntry<>(entry.getKey(), entry.getValue()));
}
return entries;
}
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Map)) return false;
Map<?, ?> other = (Map<?, ?>) o;
try (Jedis jedis = pool.getResource()) {
Map<String, String> all = jedis.hgetAll(redisKey);
return all.equals(other);
}
}

@Override
public int hashCode() {
try (Jedis j = pool.getResource()) {
Map<String, String> all = j.hgetAll(redisKey);
return all.hashCode();
}
}
}
111 changes: 111 additions & 0 deletions src/test/java/org/redis/RedisMapTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package org.redis;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.JedisPool;

import java.util.*;

import static org.junit.jupiter.api.Assertions.*;

class RedisMapTest {
private JedisPool pool;
private RedisMap map;
private final String KEY = "test-map";

@BeforeEach
void setup() {
pool = new JedisPool("localhost", 6379);
map = new RedisMap(pool, KEY);
map.clear();
}

@AfterEach
void teardown() {
map.clear();
map.close();
}

@Test
void testPutGetSizeIsEmpty() {
assertTrue(map.isEmpty());
assertEquals(0, map.size());

assertNull(map.put("a", "1"));
assertEquals("1", map.get("a"));
assertFalse(map.isEmpty());
assertEquals(1, map.size());

assertEquals("1", map.put("a", "2"));
assertEquals("2", map.get("a"));
assertEquals(1, map.size());
}

@Test
void testContainsKeyAndValue() {
map.put("k1", "v1");
map.put("k2", "v2");
assertTrue(map.containsKey("k1"));
assertTrue(map.containsValue("v2"));
assertFalse(map.containsKey("no"));
}

@Test
void testRemove() {
map.put("x", "y");
assertEquals("y", map.remove("x"));
assertNull(map.get("x"));
assertFalse(map.containsKey("x"));
assertFalse(map.containsValue("y"));
}

@Test
void testPutAllAndClear() {
Map<String, String> src = new HashMap<>();
src.put("a", "1");
src.put("b", "2");
map.putAll(src);
assertEquals(2, map.size());
map.clear();
assertTrue(map.isEmpty());
}

@Test
void testKeySetValuesEntrySet() {
map.put("k1", "v1");
map.put("k2", "v2");

Set<String> keys = map.keySet();
assertEquals(new HashSet<>(Arrays.asList("k1", "k2")), keys);

Collection<String> vals = map.values();
assertTrue(vals.containsAll(Arrays.asList("v1", "v2")));

Set<Map.Entry<String, String>> entries = map.entrySet();
assertEquals(2, entries.size());
}

@Test
void testEqualsHashCode() {
map.put("a", "1");
map.put("b", "2");

Map<String, String> other = new HashMap<>();
other.put("a", "1");
other.put("b", "2");

assertEquals(other, map);
assertEquals(other.hashCode(), map.hashCode());
}

@Test
void testNullKeyOrValueThrows() {
assertThrows(NullPointerException.class, () -> map.put(null, "v"));
assertThrows(NullPointerException.class, () -> map.put("k", null));
Map<String, String> m = new HashMap<>();
m.put("k1", null);
assertThrows(NullPointerException.class, () -> map.putAll(m));
}

}