Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
K
key_value-server
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
amir.yosef
key_value-server
Commits
da928f4f
Commit
da928f4f
authored
Aug 24, 2024
by
amir.yosef
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update validation technique
parent
c6c0e76b
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
95 additions
and
106 deletions
+95
-106
Redis_jar.xml
.idea/artifacts/Redis_jar.xml
+0
-43
CommandValidator.java
src/command/CommandValidator.java
+49
-29
EchoCommand.java
src/command/EchoCommand.java
+2
-1
SetCommand.java
src/command/SetCommand.java
+28
-17
ReplicaSetCommand.java
src/command/replica/ReplicaSetCommand.java
+13
-12
Command.java
src/model/Command.java
+0
-1
Storage.java
src/storage/Storage.java
+2
-2
StorageManager.java
src/storage/StorageManager.java
+1
-1
No files found.
.idea/artifacts/Redis_jar.xml
deleted
100644 → 0
View file @
c6c0e76b
<component
name=
"ArtifactManager"
>
<artifact
type=
"jar"
name=
"Redis:jar"
>
<output-path>
$PROJECT_DIR$/out/artifacts/Redis_jar
</output-path>
<root
id=
"archive"
name=
"Redis.jar"
>
<element
id=
"module-output"
name=
"Redis"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-all-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-codec-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-buffer-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-common-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-handler-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-resolver-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-codec-dns-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-codec-xml-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-transport-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-codec-http-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-codec-mqtt-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-codec-smtp-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-codec-http2-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-codec-redis-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-codec-socks-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-codec-stomp-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-resolver-dns-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-codec-haproxy-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-handler-proxy-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-transport-udt-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-codec-memcache-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-transport-rxtx-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-transport-sctp-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-handler-ssl-ocsp-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-transport-classes-epoll-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-transport-classes-kqueue-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-resolver-dns-classes-macos-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-transport-native-unix-common-4.1.112.Final.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-transport-native-kqueue-4.1.112.Final-osx-x86_64.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-transport-native-epoll-4.1.112.Final-linux-x86_64.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-resolver-dns-native-macos-4.1.112.Final-osx-x86_64.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-transport-native-epoll-4.1.112.Final-linux-riscv64.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-transport-native-kqueue-4.1.112.Final-osx-aarch_64.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-transport-native-epoll-4.1.112.Final-linux-aarch_64.jar"
path-in-jar=
"/"
/>
<element
id=
"extracted-dir"
path=
"$PROJECT_DIR$/../Socket/lib/netty-resolver-dns-native-macos-4.1.112.Final-osx-aarch_64.jar"
path-in-jar=
"/"
/>
</root>
</artifact>
</component>
\ No newline at end of file
src/command/CommandValidator.java
View file @
da928f4f
package
command
;
import
model.Command
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.stream.Collectors
;
import
java.util.stream.IntStream
;
public
class
CommandValidator
{
public
final
class
CommandValidator
{
private
CommandValidator
()
{
}
private
static
final
CommandValidator
INSTANCE
=
new
CommandValidator
();
private
static
final
class
InstanceHolder
{
private
static
final
CommandValidator
instance
=
new
CommandValidator
();
private
CommandValidator
()
{
}
public
static
CommandValidator
getInstance
()
{
return
I
nstanceHolder
.
instance
;
return
I
NSTANCE
;
}
public
boolean
validateSetCommand
(
List
<
String
>
args
)
{
if
(
args
==
null
||
args
.
isEmpty
()
)
{
if
(
args
==
null
||
args
.
size
()
<
2
)
{
return
false
;
}
if
(
args
.
size
()
<
2
)
{
return
false
;
int
size
=
args
.
size
();
if
(
size
==
2
)
{
return
true
;
}
if
(
args
.
size
()
>
2
)
{
Map
<
String
,
String
>
commandsMap
=
IntStream
.
iterate
(
2
,
i
->
i
<
args
.
size
(),
i
->
i
+
2
)
.
boxed
()
.
collect
(
Collectors
.
toMap
(
i
->
args
.
get
(
i
).
toLowerCase
(),
i
->
args
.
get
(
i
+
1
),
(
a
,
b
)
->
b
));
String
expiration
=
commandsMap
.
get
(
Command
.
PX
.
getValue
().
toLowerCase
());
if
(
expiration
!=
null
)
{
try
{
Long
.
parseLong
(
expiration
);
}
catch
(
NumberFormatException
e
)
{
return
false
;
}
boolean
hasPx
=
false
;
String
pxValue
=
null
;
for
(
int
i
=
2
;
i
<
size
-
1
;
i
+=
2
)
{
String
key
=
args
.
get
(
i
).
toLowerCase
();
if
(
"px"
.
equals
(
key
))
{
hasPx
=
true
;
pxValue
=
args
.
get
(
i
+
1
);
break
;
}
}
if
(
hasPx
)
{
return
isValidLong
(
pxValue
);
}
else
{
return
size
%
2
==
0
||
isValidLong
(
args
.
get
(
size
-
1
));
}
}
private
boolean
isValidLong
(
String
value
)
{
if
(
value
==
null
||
value
.
isEmpty
())
{
return
false
;
}
int
len
=
value
.
length
();
if
(
len
>
19
)
{
return
false
;
}
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
char
c
=
value
.
charAt
(
i
);
if
(
i
==
0
&&
c
==
'-'
)
{
if
(
len
==
1
)
return
false
;
continue
;
}
if
(
c
<
'0'
||
c
>
'9'
)
{
return
false
;
}
}
return
true
;
}
...
...
@@ -51,8 +67,12 @@ public class CommandValidator {
return
args
!=
null
&&
args
.
size
()
==
1
;
}
public
boolean
validateInfoCommand
(
List
<
String
>
args
)
{
return
args
!=
null
&&
args
.
size
()
==
1
&&
"replication"
.
equalsIgnoreCase
(
args
.
getFirst
());
return
args
!=
null
&&
args
.
size
()
==
1
&&
"replication"
.
equalsIgnoreCase
(
args
.
getFirst
());
}
public
boolean
validateEchoCommand
(
List
<
String
>
args
)
{
return
!
args
.
isEmpty
()
&&
args
.
getFirst
()
!=
null
;
}
}
}
\ No newline at end of file
src/command/EchoCommand.java
View file @
da928f4f
...
...
@@ -6,6 +6,7 @@ import java.util.List;
public
class
EchoCommand
implements
CommandExecutable
<
byte
[]>
{
private
final
List
<
String
>
args
;
private
final
CommandValidator
validator
=
CommandValidator
.
getInstance
();
public
EchoCommand
(
List
<
String
>
args
)
{
this
.
args
=
args
;
...
...
@@ -13,7 +14,7 @@ public class EchoCommand implements CommandExecutable<byte[]> {
@Override
public
byte
[]
execute
()
{
if
(
!
args
.
isEmpty
()
&&
args
.
getFirst
()
!=
null
)
{
if
(
validator
.
validateEchoCommand
(
args
)
)
{
return
(
Response
.
getResponse
(
args
.
getFirst
()));
}
else
{
return
""
.
getBytes
();
...
...
src/command/SetCommand.java
View file @
da928f4f
package
command
;
import
model.Command
;
import
storage.Storage
;
import
util.Response
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.stream.Collectors
;
import
java.util.stream.IntStream
;
public
class
SetCommand
implements
CommandExecutable
<
byte
[]>
{
private
static
final
byte
[]
OK_RESPONSE
=
"+OK\r\n"
.
getBytes
();
private
static
final
byte
[]
ERROR_RESPONSE
=
Response
.
getResponse
(
"wrong args"
);
private
final
Storage
storage
=
Storage
.
getInstance
();
private
final
List
<
String
>
args
;
private
final
CommandValidator
validator
=
CommandValidator
.
getInstance
();
...
...
@@ -21,21 +20,33 @@ public class SetCommand implements CommandExecutable<byte[]> {
@Override
public
byte
[]
execute
()
{
if
(!
validator
.
validateSetCommand
(
args
))
{
return
Response
.
getResponse
(
"wrong args"
)
;
return
ERROR_RESPONSE
;
}
Map
<
String
,
String
>
commandsMap
=
IntStream
.
iterate
(
2
,
i
->
i
<
args
.
size
(),
i
->
i
+
2
)
.
boxed
()
.
collect
(
Collectors
.
toMap
(
i
->
args
.
get
(
i
).
toLowerCase
(),
i
->
args
.
get
(
i
+
1
),
(
a
,
b
)
->
b
));
String
key
=
args
.
get
(
0
).
toLowerCase
();
String
value
=
args
.
get
(
1
);
String
expiration
=
commandsMap
.
get
(
Command
.
PX
.
getValue
().
toLowerCase
());
if
(
expiration
!=
null
)
{
Long
expirationTime
=
Long
.
parseLong
(
expiration
);
storage
.
save
(
args
.
getFirst
().
toLowerCase
(),
value
,
expirationTime
);
int
size
=
args
.
size
();
if
(
size
>
2
)
{
String
lastArg
=
args
.
get
(
size
-
1
);
try
{
if
(
size
%
2
==
0
)
{
if
(
"px"
.
equalsIgnoreCase
(
args
.
get
(
size
-
2
)))
{
long
expirationTime
=
Long
.
parseLong
(
lastArg
);
storage
.
save
(
key
,
value
,
expirationTime
);
}
else
{
storage
.
save
(
key
,
value
);
}
}
else
{
long
expirationTime
=
Long
.
parseLong
(
lastArg
);
storage
.
save
(
key
,
value
,
expirationTime
);
}
}
catch
(
NumberFormatException
e
)
{
return
ERROR_RESPONSE
;
}
}
else
{
storage
.
save
(
args
.
getFirst
().
toLowerCase
()
,
value
);
storage
.
save
(
key
,
value
);
}
return
(
"+OK\r\n"
.
getBytes
());
return
OK_RESPONSE
;
}
}
}
\ No newline at end of file
src/command/replica/ReplicaSetCommand.java
View file @
da928f4f
package
command
.
replica
;
import
command.CommandExecutable
;
import
model.Command
;
import
storage.Storage
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
import
java.util.stream.Collectors
;
import
java.util.stream.IntStream
;
public
class
ReplicaSetCommand
implements
CommandExecutable
<
Void
>
{
private
final
Storage
storage
=
Storage
.
getInstance
();
...
...
@@ -22,22 +18,27 @@ public class ReplicaSetCommand implements CommandExecutable<Void> {
@Override
public
Void
execute
()
{
Map
<
String
,
String
>
commandsMap
=
IntStream
.
iterate
(
2
,
i
->
i
<
args
.
size
(),
i
->
i
+
2
).
boxed
()
.
collect
(
Collectors
.
toMap
(
i
->
args
.
get
(
i
).
toLowerCase
(),
i
->
args
.
get
(
i
+
1
),
(
a
,
b
)
->
b
));
String
key
=
args
.
get
(
0
).
toLowerCase
();
String
value
=
args
.
get
(
1
);
String
expiration
=
commandsMap
.
get
(
Command
.
PX
.
getValue
().
toLowerCase
());
String
expiration
=
null
;
for
(
int
i
=
2
;
i
<
args
.
size
()
-
1
;
i
+=
2
)
{
if
(
"px"
.
equalsIgnoreCase
(
args
.
get
(
i
)))
{
expiration
=
args
.
get
(
i
+
1
);
break
;
}
}
if
(
expiration
!=
null
)
{
try
{
L
ong
expirationTime
=
Long
.
parseLong
(
expiration
);
storage
.
save
(
args
.
getFirst
().
toLowerCase
()
,
value
,
expirationTime
);
l
ong
expirationTime
=
Long
.
parseLong
(
expiration
);
storage
.
save
(
key
,
value
,
expirationTime
);
}
catch
(
NumberFormatException
e
)
{
logger
.
log
(
Level
.
SEVERE
,
"NumberFormatException"
,
e
);
}
}
else
{
storage
.
save
(
args
.
getFirst
().
toLowerCase
()
,
value
);
storage
.
save
(
key
,
value
);
}
return
null
;
}
}
}
\ No newline at end of file
src/model/Command.java
View file @
da928f4f
...
...
@@ -11,7 +11,6 @@ public enum Command {
PING
(
"PING"
),
PONG
(
"PONG"
),
PSYNC
(
"PSYNC"
),
PX
(
"PX"
),
REPLCONF
(
"REPLCONF"
),
REPLICATION
(
"REPLICATION"
),
SET
(
"SET"
),
...
...
src/storage/Storage.java
View file @
da928f4f
...
...
@@ -5,7 +5,7 @@ import java.util.concurrent.ConcurrentHashMap;
import
java.util.logging.Logger
;
public
class
Storage
{
private
final
int
capacity
=
10000
;
private
final
int
capacity
=
10000
00
;
private
static
final
Logger
logger
=
Logger
.
getLogger
(
Storage
.
class
.
getName
());
private
final
CachePolicy
<
String
,
String
>
storage
;
private
final
Map
<
String
,
Long
>
timeToExpiration
=
new
ConcurrentHashMap
<>(
capacity
);
...
...
@@ -19,7 +19,7 @@ public class Storage {
}
private
static
final
class
StorageHolder
{
private
static
final
Storage
instance
=
new
Storage
(
8000
);
private
static
final
Storage
instance
=
new
Storage
(
8000
00
);
}
public
static
Storage
getInstance
()
{
...
...
src/storage/StorageManager.java
View file @
da928f4f
...
...
@@ -14,7 +14,7 @@ public class StorageManager {
public
StorageManager
()
{
this
.
storage
=
Storage
.
getInstance
();
this
.
scheduler
=
Executors
.
newSingleThreadScheduledExecutor
();
scheduler
.
scheduleAtFixedRate
(
this
::
performMaintenance
,
2
,
2
,
TimeUnit
.
MINUTE
S
);
scheduler
.
scheduleAtFixedRate
(
this
::
performMaintenance
,
30
,
30
,
TimeUnit
.
SECOND
S
);
}
private
void
performMaintenance
()
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment