Skip to content

Commit ed89aa7

Browse files
committed
separate memory classes, perf improvements
1 parent 4450f30 commit ed89aa7

18 files changed

+154
-147
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.github.rxrav.redislite.core;
2+
3+
import java.util.Map;
4+
import java.util.concurrent.ConcurrentHashMap;
5+
6+
public class Memory {
7+
private Map<String, Object> mainMemory;
8+
private Map<String, ExpiryMetaData> expiryDetails;
9+
10+
public Memory() {
11+
this.mainMemory = new ConcurrentHashMap<>();
12+
this.expiryDetails = new ConcurrentHashMap<>();
13+
}
14+
15+
public Map<String, Object> getMainMemory() {
16+
return mainMemory;
17+
}
18+
19+
public void setMainMemory(Map<String, Object> mainMemory) {
20+
this.mainMemory = mainMemory;
21+
}
22+
23+
public Map<String, ExpiryMetaData> getExpiryDetails() {
24+
return expiryDetails;
25+
}
26+
27+
public void setExpiryDetails(Map<String, ExpiryMetaData> expiryDetails) {
28+
this.expiryDetails = expiryDetails;
29+
}
30+
}

src/main/java/com/github/rxrav/redislite/core/cmd/Command.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
package com.github.rxrav.redislite.core.cmd;
22

3+
import com.github.rxrav.redislite.core.Memory;
34
import com.github.rxrav.redislite.core.error.ValidationError;
45

56
public abstract class Command {
67
private String cmd;
78
private String[] args;
89
protected Command() {}
910
protected abstract void validate() throws ValidationError;
10-
protected abstract Object execute();
11-
protected final Object handle() throws ValidationError {
11+
protected abstract Object execute(Memory memoryRef);
12+
protected final Object handle(Memory memoryRef) throws ValidationError {
1213
this.validate();
13-
return this.execute();
14+
return this.execute(memoryRef);
1415
}
1516
public String getCmd() {
1617
return this.cmd;

src/main/java/com/github/rxrav/redislite/core/cmd/CommandHandler.java

+17-15
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package com.github.rxrav.redislite.core.cmd;
22

3+
import com.github.rxrav.redislite.core.Memory;
34
import com.github.rxrav.redislite.core.cmd.impl.*;
45
import com.github.rxrav.redislite.core.error.UnknownCommandError;
56
import com.github.rxrav.redislite.core.ser.Resp2Deserializer;
67
import com.github.rxrav.redislite.core.ser.Resp2Serializer;
7-
import com.github.rxrav.redislite.server.RedisLiteServer;
88

99
import java.net.SocketException;
1010
import java.util.ArrayList;
@@ -15,9 +15,11 @@
1515
public class CommandHandler {
1616
private final Resp2Serializer serializer;
1717
private final Resp2Deserializer deserializer;
18-
public CommandHandler(Resp2Serializer serializer, Resp2Deserializer deserializer) {
18+
private final Memory memoryRef;
19+
public CommandHandler(Resp2Serializer serializer, Resp2Deserializer deserializer, Memory memoryRef) {
1920
this.serializer = serializer;
2021
this.deserializer = deserializer;
22+
this.memoryRef = memoryRef;
2123
}
2224
public String handleCommand(String command) throws SocketException {
2325
char firstByte = command.charAt(0);
@@ -28,36 +30,36 @@ public String handleCommand(String command) throws SocketException {
2830
Object[] deserializedArray = deserializer.deserializeArray(command);
2931
return switch (deserializedArray[0].toString().toUpperCase()) {
3032
case "EXIT" -> throw new SocketException("Disconnecting client");
31-
case "PING" -> serializer.serialize(String.valueOf(new Ping().builder(deserializedArray).handle()), false);
32-
case "ECHO" -> serializer.serialize(String.valueOf(new Echo().builder(deserializedArray).handle()), true);
33+
case "PING" -> serializer.serialize(String.valueOf(new Ping().builder(deserializedArray).handle(null)), false);
34+
case "ECHO" -> serializer.serialize(String.valueOf(new Echo().builder(deserializedArray).handle(null)), true);
3335
case "SET" -> {
34-
Object resp = new Set().builder(deserializedArray).handle();
36+
Object resp = new Set().builder(deserializedArray).handle(memoryRef);
3537
if (resp == null) yield serializer.serialize(null, true);
3638
else yield serializer.serialize(String.valueOf(resp), false);
3739
}
3840
case "GET" -> {
39-
Object resp = new Get().builder(deserializedArray).handle();
41+
Object resp = new Get().builder(deserializedArray).handle(memoryRef);
4042
if (resp == null) yield serializer.serialize(null, true);
4143
if (resp instanceof Integer) yield serializer.serialize((int) resp);
4244
else yield serializer.serialize(String.valueOf(resp), true);
4345
}
44-
case "EXISTS" -> serializer.serialize((int) new Exists().builder(deserializedArray).handle());
45-
case "DEL" -> serializer.serialize((int) new Del().builder(deserializedArray).handle());
46-
case "INCR" -> serializer.serialize((int) new Incr().builder(deserializedArray).handle());
47-
case "DECR" -> serializer.serialize((int) new Decr().builder(deserializedArray).handle());
48-
case "LPUSH" -> serializer.serialize((int) new Lpush().builder(deserializedArray).handle());
46+
case "EXISTS" -> serializer.serialize((int) new Exists().builder(deserializedArray).handle(memoryRef));
47+
case "DEL" -> serializer.serialize((int) new Del().builder(deserializedArray).handle(memoryRef));
48+
case "INCR" -> serializer.serialize((int) new Incr().builder(deserializedArray).handle(memoryRef));
49+
case "DECR" -> serializer.serialize((int) new Decr().builder(deserializedArray).handle(memoryRef));
50+
case "LPUSH" -> serializer.serialize((int) new Lpush().builder(deserializedArray).handle(memoryRef));
4951
case "LRANGE" -> {
50-
Object obj = new Lrange().builder(deserializedArray).handle();
52+
Object obj = new Lrange().builder(deserializedArray).handle(memoryRef);
5153
List<String> list = ((ArrayList<?>) obj).stream().map(String::valueOf).toList();
5254
String[] arr = new String[list.size()];
5355
for(int i = 0; i < arr.length; i ++) {
5456
arr[i] = list.get(i);
5557
}
5658
yield serializer.serialize(arr);
5759
}
58-
case "RPUSH" -> serializer.serialize((int) new Rpush().builder(deserializedArray).handle());
59-
case "FLUSHALL" -> serializer.serialize(String.valueOf(new FlushAll().builder(deserializedArray).handle()), false);
60-
case "SAVE" -> serializer.serialize(String.valueOf(new Save().builder(deserializedArray).handle()), false);
60+
case "RPUSH" -> serializer.serialize((int) new Rpush().builder(deserializedArray).handle(memoryRef));
61+
case "FLUSHALL" -> serializer.serialize(String.valueOf(new FlushAll().builder(deserializedArray).handle(memoryRef)), false);
62+
case "SAVE" -> serializer.serialize(String.valueOf(new Save().builder(deserializedArray).handle(memoryRef)), false);
6163
default -> throw new UnknownCommandError("unknown command");
6264
};
6365
} catch (RuntimeException e) {

src/main/java/com/github/rxrav/redislite/core/cmd/impl/Decr.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package com.github.rxrav.redislite.core.cmd.impl;
22

3+
import com.github.rxrav.redislite.core.Memory;
34
import com.github.rxrav.redislite.core.cmd.Command;
45
import com.github.rxrav.redislite.core.error.ValidationError;
56
import com.github.rxrav.redislite.core.error.WrongTypeError;
6-
import com.github.rxrav.redislite.server.RedisLiteServer;
77

88
public class Decr extends Command {
99
@Override
@@ -13,20 +13,20 @@ protected void validate() throws ValidationError {
1313
}
1414

1515
@Override
16-
protected Object execute() {
16+
protected Object execute(Memory memoryRef) {
1717
int iVal = 0;
18-
if (RedisLiteServer.getMemoryMap().containsKey(super.getArgs()[0])) {
18+
if (memoryRef.getMainMemory().containsKey(super.getArgs()[0])) {
1919
try {
20-
iVal = Integer.parseInt(RedisLiteServer.getMemoryMap().get(super.getArgs()[0]).toString());
21-
RedisLiteServer.getMemoryMap().put(super.getArgs()[0], --iVal);
20+
iVal = Integer.parseInt(memoryRef.getMainMemory().get(super.getArgs()[0]).toString());
21+
memoryRef.getMainMemory().put(super.getArgs()[0], --iVal);
2222
return iVal;
2323
} catch (NumberFormatException e) {
2424
throw new WrongTypeError("Not a valid number type");
2525
}
2626
} else {
2727
// according to this command's documentation, the key is set to 0 first, then decreased by 1
28-
RedisLiteServer.getMemoryMap().put(super.getArgs()[0], iVal);
29-
RedisLiteServer.getMemoryMap().put(super.getArgs()[0], --iVal);
28+
memoryRef.getMainMemory().put(super.getArgs()[0], iVal);
29+
memoryRef.getMainMemory().put(super.getArgs()[0], --iVal);
3030
return iVal;
3131
}
3232
}

src/main/java/com/github/rxrav/redislite/core/cmd/impl/Del.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package com.github.rxrav.redislite.core.cmd.impl;
22

3+
import com.github.rxrav.redislite.core.Memory;
34
import com.github.rxrav.redislite.core.cmd.Command;
45
import com.github.rxrav.redislite.core.error.ValidationError;
5-
import com.github.rxrav.redislite.server.RedisLiteServer;
66

77
public class Del extends Command {
88
@Override
@@ -12,10 +12,10 @@ protected void validate() throws ValidationError {
1212
}
1313

1414
@Override
15-
protected Object execute() {
15+
protected Object execute(Memory memoryRef) {
1616
int i = 0;
1717
for (String key: super.getArgs()) {
18-
Object obj = RedisLiteServer.getMemoryMap().remove(key);
18+
Object obj = memoryRef.getMainMemory().remove(key);
1919
if (obj != null) ++i;
2020
}
2121
return i;

src/main/java/com/github/rxrav/redislite/core/cmd/impl/Echo.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.github.rxrav.redislite.core.cmd.impl;
22

3+
import com.github.rxrav.redislite.core.Memory;
34
import com.github.rxrav.redislite.core.cmd.Command;
45
import com.github.rxrav.redislite.core.error.ValidationError;
56

@@ -11,7 +12,7 @@ protected void validate() {
1112
}
1213

1314
@Override
14-
protected Object execute() {
15+
protected Object execute(Memory memoryRef) {
1516
return super.getArgs()[0];
1617
}
1718
}

src/main/java/com/github/rxrav/redislite/core/cmd/impl/Exists.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package com.github.rxrav.redislite.core.cmd.impl;
22

3+
import com.github.rxrav.redislite.core.Memory;
34
import com.github.rxrav.redislite.core.cmd.Command;
45
import com.github.rxrav.redislite.core.error.ValidationError;
5-
import com.github.rxrav.redislite.server.RedisLiteServer;
66

77
public class Exists extends Command {
88
@Override
@@ -12,10 +12,10 @@ protected void validate() throws ValidationError {
1212
}
1313

1414
@Override
15-
protected Object execute() {
15+
protected Object execute(Memory memoryRef) {
1616
int i = 0;
1717
for (String key: super.getArgs()) {
18-
if (RedisLiteServer.getMemoryMap().containsKey(key)) ++i;
18+
if (memoryRef.getMainMemory().containsKey(key)) ++i;
1919
}
2020
return i;
2121
}

src/main/java/com/github/rxrav/redislite/core/cmd/impl/FlushAll.java

+4-10
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
package com.github.rxrav.redislite.core.cmd.impl;
22

3+
import com.github.rxrav.redislite.core.Memory;
34
import com.github.rxrav.redislite.core.cmd.Command;
4-
import com.github.rxrav.redislite.core.error.RedisLiteError;
55
import com.github.rxrav.redislite.core.error.ValidationError;
6-
import com.github.rxrav.redislite.server.RedisLiteServer;
7-
8-
import java.io.BufferedWriter;
9-
import java.io.FileWriter;
10-
import java.io.IOException;
11-
import java.util.Map;
126

137
public class FlushAll extends Command {
148
@Override
@@ -18,10 +12,10 @@ protected void validate() throws ValidationError {
1812
}
1913

2014
@Override
21-
protected Object execute() {
15+
protected Object execute(Memory memoryRef) {
2216
try{
23-
RedisLiteServer.getMemoryMap().clear();
24-
RedisLiteServer.getExpiryDetailsMap().clear();
17+
memoryRef.getMainMemory().clear();
18+
memoryRef.getExpiryDetails().clear();
2519
} catch(Exception e) {
2620
System.out.println(e.getMessage());
2721
System.out.println(e.getClass());

src/main/java/com/github/rxrav/redislite/core/cmd/impl/Get.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package com.github.rxrav.redislite.core.cmd.impl;
22

33
import com.github.rxrav.redislite.core.ExpiryMetaData;
4+
import com.github.rxrav.redislite.core.Memory;
45
import com.github.rxrav.redislite.core.cmd.Command;
56
import com.github.rxrav.redislite.core.error.ValidationError;
6-
import com.github.rxrav.redislite.server.RedisLiteServer;
77

88
import java.util.Date;
99

@@ -19,16 +19,16 @@ protected void validate() throws ValidationError {
1919
* @return Value from the memory, or null
2020
*/
2121
@Override
22-
protected Object execute() {
22+
protected Object execute(Memory memoryRef) {
2323
String key = super.getArgs()[0];
24-
Object val = RedisLiteServer.getMemoryMap().get(key);
25-
ExpiryMetaData expiryMetaData = RedisLiteServer.getExpiryDetailsMap().get(key);
24+
Object val = memoryRef.getMainMemory().get(key);
25+
ExpiryMetaData expiryMetaData = memoryRef.getExpiryDetails().get(key);
2626
boolean itHasExpired = (expiryMetaData != null) && hasExpired(expiryMetaData);
2727

2828
if (val == null) return null;
2929
else if (itHasExpired) {
30-
RedisLiteServer.getMemoryMap().remove(key);
31-
RedisLiteServer.getExpiryDetailsMap().remove(key);
30+
memoryRef.getMainMemory().remove(key);
31+
memoryRef.getExpiryDetails().remove(key);
3232
return null;
3333
}
3434
else if (val instanceof String) return val.toString();

src/main/java/com/github/rxrav/redislite/core/cmd/impl/Incr.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package com.github.rxrav.redislite.core.cmd.impl;
22

3+
import com.github.rxrav.redislite.core.Memory;
34
import com.github.rxrav.redislite.core.cmd.Command;
45
import com.github.rxrav.redislite.core.error.ValidationError;
56
import com.github.rxrav.redislite.core.error.WrongTypeError;
6-
import com.github.rxrav.redislite.server.RedisLiteServer;
77

88
public class Incr extends Command {
99
@Override
@@ -13,20 +13,20 @@ protected void validate() throws ValidationError {
1313
}
1414

1515
@Override
16-
protected Object execute() {
16+
protected Object execute(Memory memoryRef) {
1717
int iVal = 0;
18-
if (RedisLiteServer.getMemoryMap().containsKey(super.getArgs()[0])) {
18+
if (memoryRef.getMainMemory().containsKey(super.getArgs()[0])) {
1919
try {
20-
iVal = Integer.parseInt(RedisLiteServer.getMemoryMap().get(super.getArgs()[0]).toString());
21-
RedisLiteServer.getMemoryMap().put(super.getArgs()[0], ++iVal);
20+
iVal = Integer.parseInt(memoryRef.getMainMemory().get(super.getArgs()[0]).toString());
21+
memoryRef.getMainMemory().put(super.getArgs()[0], ++iVal);
2222
return iVal;
2323
} catch (NumberFormatException e) {
2424
throw new WrongTypeError("Not a valid number type");
2525
}
2626
} else {
2727
// According to this command's documentation, the key is set to 0 first, then increased by 1
28-
RedisLiteServer.getMemoryMap().put(super.getArgs()[0], iVal);
29-
RedisLiteServer.getMemoryMap().put(super.getArgs()[0], ++iVal);
28+
memoryRef.getMainMemory().put(super.getArgs()[0], iVal);
29+
memoryRef.getMainMemory().put(super.getArgs()[0], ++iVal);
3030
return iVal;
3131
}
3232
}

src/main/java/com/github/rxrav/redislite/core/cmd/impl/Lpush.java

+6-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
package com.github.rxrav.redislite.core.cmd.impl;
22

3+
import com.github.rxrav.redislite.core.Memory;
34
import com.github.rxrav.redislite.core.cmd.Command;
4-
import com.github.rxrav.redislite.core.error.RedisLiteError;
55
import com.github.rxrav.redislite.core.error.ValidationError;
66
import com.github.rxrav.redislite.core.error.WrongTypeError;
7-
import com.github.rxrav.redislite.server.RedisLiteServer;
87

9-
import java.lang.reflect.Array;
108
import java.util.ArrayList;
119
import java.util.Arrays;
1210
import java.util.List;
@@ -19,27 +17,27 @@ protected void validate() throws ValidationError {
1917
}
2018

2119
@Override
22-
protected Object execute() {
20+
protected Object execute(Memory memoryRef) {
2321
String key = super.getArgs()[0];
2422
String[] args = new String[super.getArgs().length-1];
2523
for (int i = 1; i < super.getArgs().length; i++) {
2624
args[i-1] = super.getArgs()[i];
2725
}
2826

2927
ArrayList<String> newList;
30-
if (RedisLiteServer.getMemoryMap().containsKey(key)) {
31-
Object obj = RedisLiteServer.getMemoryMap().get(key);
28+
if (memoryRef.getMainMemory().containsKey(key)) {
29+
Object obj = memoryRef.getMainMemory().get(key);
3230
if (obj instanceof ArrayList) {
3331
List<String> list = ((ArrayList<?>) obj).stream().map(String::valueOf).toList();
3432
newList = new ArrayList<>(Arrays.asList(args).reversed());
3533
newList.addAll(list);
36-
RedisLiteServer.getMemoryMap().put(key, newList);
34+
memoryRef.getMainMemory().put(key, newList);
3735
} else {
3836
throw new WrongTypeError("Operation against a key holding the wrong kind of value");
3937
}
4038
} else {
4139
newList = new ArrayList<>(Arrays.asList(args).reversed());
42-
RedisLiteServer.getMemoryMap().put(key, newList);
40+
memoryRef.getMainMemory().put(key, newList);
4341
}
4442
return newList.size();
4543
}

0 commit comments

Comments
 (0)