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
49e510a1
Commit
49e510a1
authored
Aug 31, 2024
by
amir.yosef
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Decoupling classes
parent
1d9fb337
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
165 additions
and
108 deletions
+165
-108
CommandExecutable.java
src/command/CommandExecutable.java
+19
-0
EchoCommand.java
src/command/EchoCommand.java
+4
-2
FullRsyncCommand.java
src/command/FullRsyncCommand.java
+6
-6
GetCommand.java
src/command/GetCommand.java
+7
-4
InfoCommand.java
src/command/InfoCommand.java
+6
-4
SetCommand.java
src/command/SetCommand.java
+6
-4
ReplicaSetCommand.java
src/command/replica/ReplicaSetCommand.java
+14
-17
EchoCommandValidator.java
src/command/validation/EchoCommandValidator.java
+19
-0
InfoCommandValidator.java
src/command/validation/InfoCommandValidator.java
+19
-0
SetCommandValidator.java
src/command/validation/SetCommandValidator.java
+7
-18
Validatable.java
src/command/validation/Validatable.java
+7
-0
CommandFactory.java
src/factory/CommandFactory.java
+1
-1
ExecutablesFactory.java
src/factory/ExecutablesFactory.java
+1
-1
ReplicaCommandFactory.java
src/factory/replica/ReplicaCommandFactory.java
+2
-2
ClientCommandHandler.java
src/handlers/ClientCommandHandler.java
+4
-2
RdbFile.java
src/model/RdbFile.java
+0
-1
ReplicaConnectionService.java
src/server/ReplicaConnectionService.java
+1
-2
SendToReplica.java
src/server/SendToReplica.java
+15
-14
ServerBuilder.java
src/server/ServerBuilder.java
+4
-4
ServiceInfo.java
src/server/ServiceInfo.java
+9
-8
Cacheable.java
src/storage/Cacheable.java
+1
-0
CaffeineCachePolicy.java
src/storage/CaffeineCachePolicy.java
+1
-2
RdbFileReader.java
src/storage/RdbFileReader.java
+0
-8
Storage.java
src/storage/Storage.java
+11
-7
StorageManager.java
src/storage/StorageManager.java
+1
-1
No files found.
src/command/CommandExecutable.java
View file @
49e510a1
package
command
;
package
command
;
import
command.validation.Validatable
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.util.List
;
public
interface
CommandExecutable
<
T
>
{
public
interface
CommandExecutable
<
T
>
{
T
execute
()
throws
IOException
;
T
execute
()
throws
IOException
;
class
GetCommandValidator
implements
Validatable
{
private
static
final
GetCommandValidator
INSTANCE
=
new
GetCommandValidator
();
private
GetCommandValidator
()
{
}
public
static
GetCommandValidator
getInstance
()
{
return
INSTANCE
;
}
@Override
public
boolean
isValid
(
List
<
String
>
args
)
{
return
args
!=
null
&&
args
.
size
()
==
1
;
}
}
}
}
src/command/EchoCommand.java
View file @
49e510a1
package
command
;
package
command
;
import
command.validation.EchoCommandValidator
;
import
command.validation.Validatable
;
import
util.Response
;
import
util.Response
;
import
java.util.List
;
import
java.util.List
;
public
final
class
EchoCommand
implements
CommandExecutable
<
byte
[]>
{
public
final
class
EchoCommand
implements
CommandExecutable
<
byte
[]>
{
private
final
List
<
String
>
args
;
private
final
List
<
String
>
args
;
private
final
CommandValidator
validator
=
CommandValidator
.
getInstance
();
private
final
Validatable
validator
=
Echo
CommandValidator
.
getInstance
();
public
EchoCommand
(
List
<
String
>
args
)
{
public
EchoCommand
(
List
<
String
>
args
)
{
this
.
args
=
args
;
this
.
args
=
args
;
...
@@ -14,7 +16,7 @@ public final class EchoCommand implements CommandExecutable<byte[]> {
...
@@ -14,7 +16,7 @@ public final class EchoCommand implements CommandExecutable<byte[]> {
@Override
@Override
public
byte
[]
execute
()
{
public
byte
[]
execute
()
{
if
(
validator
.
validateEchoComman
d
(
args
))
{
if
(
validator
.
isVali
d
(
args
))
{
return
(
Response
.
getResponse
(
args
.
getFirst
()));
return
(
Response
.
getResponse
(
args
.
getFirst
()));
}
else
{
}
else
{
return
""
.
getBytes
();
return
""
.
getBytes
();
...
...
src/command/FullRsyncCommand.java
View file @
49e510a1
...
@@ -3,7 +3,7 @@ package command;
...
@@ -3,7 +3,7 @@ package command;
import
model.Command
;
import
model.Command
;
import
server.SendToReplica
;
import
server.SendToReplica
;
import
server.Serv
er
Info
;
import
server.Serv
ice
Info
;
import
util.RdbFileInfo
;
import
util.RdbFileInfo
;
import
java.io.ByteArrayOutputStream
;
import
java.io.ByteArrayOutputStream
;
...
@@ -14,13 +14,13 @@ public final class FullRsyncCommand implements CommandExecutable<byte[]> {
...
@@ -14,13 +14,13 @@ public final class FullRsyncCommand implements CommandExecutable<byte[]> {
private
final
SendToReplica
replicaSender
;
private
final
SendToReplica
replicaSender
;
private
final
RdbFileInfo
rdbFileInfo
;
private
final
RdbFileInfo
rdbFileInfo
;
private
final
OutputStream
outputStream
;
private
final
OutputStream
outputStream
;
private
final
Serv
erInfo
server
Info
;
private
final
Serv
iceInfo
service
Info
;
public
FullRsyncCommand
(
SendToReplica
replicaSender
,
OutputStream
outputStream
)
{
public
FullRsyncCommand
(
SendToReplica
replicaSender
,
OutputStream
outputStream
)
{
this
.
outputStream
=
outputStream
;
this
.
outputStream
=
outputStream
;
this
.
replicaSender
=
replicaSender
;
this
.
replicaSender
=
replicaSender
;
rdbFileInfo
=
RdbFileInfo
.
getInstance
();
rdbFileInfo
=
RdbFileInfo
.
getInstance
();
this
.
serv
erInfo
=
Server
Info
.
getInstance
();
this
.
serv
iceInfo
=
Service
Info
.
getInstance
();
}
}
@Override
@Override
...
@@ -29,7 +29,7 @@ public final class FullRsyncCommand implements CommandExecutable<byte[]> {
...
@@ -29,7 +29,7 @@ public final class FullRsyncCommand implements CommandExecutable<byte[]> {
replicaSender
.
addConnection
(
outputStream
);
replicaSender
.
addConnection
(
outputStream
);
byte
[]
decode
=
rdbFileInfo
.
getContent
();
byte
[]
decode
=
rdbFileInfo
.
getContent
();
try
{
try
{
return
createCommandBytes
(
Command
.
FULLRESYNC
,
decode
,
serv
er
Info
);
return
createCommandBytes
(
Command
.
FULLRESYNC
,
decode
,
serv
ice
Info
);
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
throw
new
RuntimeException
(
e
);
throw
new
RuntimeException
(
e
);
}
}
...
@@ -37,9 +37,9 @@ public final class FullRsyncCommand implements CommandExecutable<byte[]> {
...
@@ -37,9 +37,9 @@ public final class FullRsyncCommand implements CommandExecutable<byte[]> {
}
}
public
byte
[]
createCommandBytes
(
Command
command
,
byte
[]
decode
,
Serv
erInfo
server
Info
)
throws
IOException
{
public
byte
[]
createCommandBytes
(
Command
command
,
byte
[]
decode
,
Serv
iceInfo
service
Info
)
throws
IOException
{
ByteArrayOutputStream
byteArrayOutputStream
=
new
ByteArrayOutputStream
();
ByteArrayOutputStream
byteArrayOutputStream
=
new
ByteArrayOutputStream
();
byteArrayOutputStream
.
write
((
"+"
+
command
.
getValue
()
+
" "
+
serv
er
Info
.
getInfo
().
get
(
"master_replid"
)
+
" 0\r\n"
).
getBytes
());
byteArrayOutputStream
.
write
((
"+"
+
command
.
getValue
()
+
" "
+
serv
ice
Info
.
getInfo
().
get
(
"master_replid"
)
+
" 0\r\n"
).
getBytes
());
byteArrayOutputStream
.
write
((
"$"
+
decode
.
length
+
"\r\n"
).
getBytes
());
byteArrayOutputStream
.
write
((
"$"
+
decode
.
length
+
"\r\n"
).
getBytes
());
byteArrayOutputStream
.
write
(
decode
);
byteArrayOutputStream
.
write
(
decode
);
return
byteArrayOutputStream
.
toByteArray
();
return
byteArrayOutputStream
.
toByteArray
();
...
...
src/command/GetCommand.java
View file @
49e510a1
package
command
;
package
command
;
import
command.validation.Validatable
;
import
storage.Cacheable
;
import
storage.Storage
;
import
storage.Storage
;
import
util.Response
;
import
util.Response
;
...
@@ -7,9 +9,10 @@ import java.util.List;
...
@@ -7,9 +9,10 @@ import java.util.List;
public
final
class
GetCommand
implements
CommandExecutable
<
byte
[]>
{
public
final
class
GetCommand
implements
CommandExecutable
<
byte
[]>
{
private
final
Storage
storage
=
Storage
.
getInstance
();
private
final
Cacheable
<
String
,
String
>
storage
=
Storage
.
getInstance
();
private
static
final
byte
[]
ERROR_RESPONSE
=
Response
.
getResponse
(
"wrong args"
);
private
final
List
<
String
>
args
;
private
final
List
<
String
>
args
;
private
final
CommandValidator
validator
=
CommandValidator
.
getInstance
();
private
final
Validatable
validator
=
Get
CommandValidator
.
getInstance
();
public
GetCommand
(
List
<
String
>
args
)
{
public
GetCommand
(
List
<
String
>
args
)
{
this
.
args
=
args
;
this
.
args
=
args
;
...
@@ -17,8 +20,8 @@ public final class GetCommand implements CommandExecutable<byte[]> {
...
@@ -17,8 +20,8 @@ public final class GetCommand implements CommandExecutable<byte[]> {
@Override
@Override
public
byte
[]
execute
()
{
public
byte
[]
execute
()
{
if
(!
validator
.
validateGetComman
d
(
args
))
{
if
(!
validator
.
isVali
d
(
args
))
{
return
Response
.
getResponse
(
"wrong args"
)
;
return
ERROR_RESPONSE
;
}
}
String
response
=
storage
.
get
(
args
.
getFirst
().
toLowerCase
());
String
response
=
storage
.
get
(
args
.
getFirst
().
toLowerCase
());
if
(
response
==
null
||
response
.
isEmpty
()
||
response
.
isBlank
())
{
if
(
response
==
null
||
response
.
isEmpty
()
||
response
.
isBlank
())
{
...
...
src/command/InfoCommand.java
View file @
49e510a1
package
command
;
package
command
;
import
server.ServerInfo
;
import
command.validation.InfoCommandValidator
;
import
command.validation.Validatable
;
import
server.ServiceInfo
;
import
util.Response
;
import
util.Response
;
import
java.util.List
;
import
java.util.List
;
...
@@ -8,8 +10,8 @@ import java.util.Map;
...
@@ -8,8 +10,8 @@ import java.util.Map;
import
java.util.stream.Collectors
;
import
java.util.stream.Collectors
;
public
final
class
InfoCommand
implements
CommandExecutable
<
byte
[]>
{
public
final
class
InfoCommand
implements
CommandExecutable
<
byte
[]>
{
private
final
Serv
erInfo
configuration
=
Server
Info
.
getInstance
();
private
final
Serv
iceInfo
configuration
=
Service
Info
.
getInstance
();
private
final
CommandValidator
validator
=
CommandValidator
.
getInstance
();
private
final
Validatable
validator
=
Info
CommandValidator
.
getInstance
();
List
<
String
>
args
;
List
<
String
>
args
;
public
InfoCommand
(
List
<
String
>
args
)
{
public
InfoCommand
(
List
<
String
>
args
)
{
...
@@ -18,7 +20,7 @@ public final class InfoCommand implements CommandExecutable<byte[]> {
...
@@ -18,7 +20,7 @@ public final class InfoCommand implements CommandExecutable<byte[]> {
@Override
@Override
public
byte
[]
execute
()
{
public
byte
[]
execute
()
{
if
(!
validator
.
validateInfoComman
d
(
args
))
{
if
(!
validator
.
isVali
d
(
args
))
{
return
Response
.
getResponse
(
"unsupported args"
);
return
Response
.
getResponse
(
"unsupported args"
);
}
}
String
command
=
args
.
getFirst
();
String
command
=
args
.
getFirst
();
...
...
src/command/SetCommand.java
View file @
49e510a1
package
command
;
package
command
;
import
command.validation.SetCommandValidator
;
import
command.validation.Validatable
;
import
storage.Cacheable
;
import
storage.Storage
;
import
storage.Storage
;
import
util.Response
;
import
util.Response
;
...
@@ -8,10 +11,9 @@ import java.util.List;
...
@@ -8,10 +11,9 @@ import java.util.List;
public
final
class
SetCommand
implements
CommandExecutable
<
byte
[]>
{
public
final
class
SetCommand
implements
CommandExecutable
<
byte
[]>
{
private
static
final
byte
[]
OK_RESPONSE
=
"+OK\r\n"
.
getBytes
();
private
static
final
byte
[]
OK_RESPONSE
=
"+OK\r\n"
.
getBytes
();
private
static
final
byte
[]
ERROR_RESPONSE
=
Response
.
getResponse
(
"wrong args"
);
private
static
final
byte
[]
ERROR_RESPONSE
=
Response
.
getResponse
(
"wrong args"
);
private
final
Cacheable
<
String
,
String
>
storage
=
Storage
.
getInstance
();
private
final
Storage
storage
=
Storage
.
getInstance
();
private
final
List
<
String
>
args
;
private
final
List
<
String
>
args
;
private
final
CommandValidator
validator
=
CommandValidator
.
getInstance
();
private
final
Validatable
validator
=
Set
CommandValidator
.
getInstance
();
public
SetCommand
(
List
<
String
>
args
)
{
public
SetCommand
(
List
<
String
>
args
)
{
this
.
args
=
args
;
this
.
args
=
args
;
...
@@ -19,7 +21,7 @@ public final class SetCommand implements CommandExecutable<byte[]> {
...
@@ -19,7 +21,7 @@ public final class SetCommand implements CommandExecutable<byte[]> {
@Override
@Override
public
byte
[]
execute
()
{
public
byte
[]
execute
()
{
if
(!
validator
.
validateSetComman
d
(
args
))
{
if
(!
validator
.
isVali
d
(
args
))
{
return
ERROR_RESPONSE
;
return
ERROR_RESPONSE
;
}
}
String
key
=
args
.
get
(
0
).
toLowerCase
();
String
key
=
args
.
get
(
0
).
toLowerCase
();
...
...
src/command/replica/ReplicaSetCommand.java
View file @
49e510a1
package
command
.
replica
;
package
command
.
replica
;
import
command.CommandExecutable
;
import
command.CommandExecutable
;
import
storage.Cacheable
;
import
storage.Storage
;
import
storage.Storage
;
import
java.util.List
;
import
java.util.List
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
public
final
class
ReplicaSetCommand
implements
CommandExecutable
<
Void
>
{
public
final
class
ReplicaSetCommand
implements
CommandExecutable
<
Void
>
{
private
final
Storage
storage
=
Storage
.
getInstance
();
private
final
Cacheable
<
String
,
String
>
storage
=
Storage
.
getInstance
();
private
final
List
<
String
>
args
;
private
final
List
<
String
>
args
;
private
static
final
Logger
logger
=
Logger
.
getLogger
(
ReplicaSetCommand
.
class
.
getName
());
public
ReplicaSetCommand
(
List
<
String
>
args
)
{
public
ReplicaSetCommand
(
List
<
String
>
args
)
{
this
.
args
=
args
;
this
.
args
=
args
;
...
@@ -21,20 +19,19 @@ public final class ReplicaSetCommand implements CommandExecutable<Void> {
...
@@ -21,20 +19,19 @@ public final class ReplicaSetCommand implements CommandExecutable<Void> {
String
key
=
args
.
get
(
0
).
toLowerCase
();
String
key
=
args
.
get
(
0
).
toLowerCase
();
String
value
=
args
.
get
(
1
);
String
value
=
args
.
get
(
1
);
String
expiration
=
null
;
int
size
=
args
.
size
();
for
(
int
i
=
2
;
i
<
args
.
size
()
-
1
;
i
+=
2
)
{
if
(
size
>
2
)
{
if
(
"px"
.
equalsIgnoreCase
(
args
.
get
(
i
)))
{
String
lastArg
=
args
.
get
(
size
-
1
);
expiration
=
args
.
get
(
i
+
1
);
if
(
size
%
2
==
0
)
{
break
;
if
(
"px"
.
equalsIgnoreCase
(
args
.
get
(
size
-
2
)))
{
}
long
expirationTime
=
Long
.
parseLong
(
lastArg
);
}
storage
.
save
(
key
,
value
,
expirationTime
);
}
else
{
if
(
expiration
!=
null
)
{
storage
.
save
(
key
,
value
);
try
{
}
long
expirationTime
=
Long
.
parseLong
(
expiration
);
}
else
{
long
expirationTime
=
Long
.
parseLong
(
lastArg
);
storage
.
save
(
key
,
value
,
expirationTime
);
storage
.
save
(
key
,
value
,
expirationTime
);
}
catch
(
NumberFormatException
e
)
{
logger
.
log
(
Level
.
SEVERE
,
"NumberFormatException"
,
e
);
}
}
}
else
{
}
else
{
storage
.
save
(
key
,
value
);
storage
.
save
(
key
,
value
);
...
...
src/command/validation/EchoCommandValidator.java
0 → 100644
View file @
49e510a1
package
command
.
validation
;
import
java.util.List
;
public
final
class
EchoCommandValidator
implements
Validatable
{
private
static
final
EchoCommandValidator
INSTANCE
=
new
EchoCommandValidator
();
private
EchoCommandValidator
()
{
}
public
static
EchoCommandValidator
getInstance
()
{
return
INSTANCE
;
}
@Override
public
boolean
isValid
(
List
<
String
>
args
)
{
return
!
args
.
isEmpty
()
&&
args
.
getFirst
()
!=
null
;
}
}
src/command/validation/InfoCommandValidator.java
0 → 100644
View file @
49e510a1
package
command
.
validation
;
import
java.util.List
;
public
final
class
InfoCommandValidator
implements
Validatable
{
private
static
final
InfoCommandValidator
INSTANCE
=
new
InfoCommandValidator
();
private
InfoCommandValidator
()
{
}
public
static
InfoCommandValidator
getInstance
()
{
return
INSTANCE
;
}
@Override
public
boolean
isValid
(
List
<
String
>
args
)
{
return
args
!=
null
&&
args
.
size
()
==
1
&&
"replication"
.
equalsIgnoreCase
(
args
.
getFirst
());
}
}
src/command/CommandValidator.java
→
src/command/
validation/Set
CommandValidator.java
View file @
49e510a1
package
command
;
package
command
.
validation
;
import
java.util.List
;
import
java.util.List
;
public
final
class
CommandValidator
{
public
final
class
SetCommandValidator
implements
Validatable
{
private
static
final
CommandValidator
INSTANCE
=
new
CommandValidator
();
private
static
final
SetCommandValidator
INSTANCE
=
new
Set
CommandValidator
();
private
CommandValidator
()
{
private
Set
CommandValidator
()
{
}
}
public
static
CommandValidator
getInstance
()
{
public
static
Set
CommandValidator
getInstance
()
{
return
INSTANCE
;
return
INSTANCE
;
}
}
public
boolean
validateSetCommand
(
List
<
String
>
args
)
{
@Override
public
boolean
isValid
(
List
<
String
>
args
)
{
if
(
args
==
null
||
args
.
size
()
<
2
)
{
if
(
args
==
null
||
args
.
size
()
<
2
)
{
return
false
;
return
false
;
}
}
...
@@ -63,16 +64,4 @@ public final class CommandValidator {
...
@@ -63,16 +64,4 @@ public final class CommandValidator {
return
true
;
return
true
;
}
}
public
boolean
validateGetCommand
(
List
<
String
>
args
)
{
return
args
!=
null
&&
args
.
size
()
==
1
;
}
public
boolean
validateInfoCommand
(
List
<
String
>
args
)
{
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/validation/Validatable.java
0 → 100644
View file @
49e510a1
package
command
.
validation
;
import
java.util.List
;
public
interface
Validatable
{
boolean
isValid
(
List
<
String
>
args
);
}
src/factory/CommandFactory.java
View file @
49e510a1
...
@@ -7,7 +7,7 @@ import server.SendToReplica;
...
@@ -7,7 +7,7 @@ import server.SendToReplica;
import
java.io.OutputStream
;
import
java.io.OutputStream
;
import
java.util.List
;
import
java.util.List
;
public
final
class
CommandFactory
implements
Factory
{
public
final
class
CommandFactory
implements
Executables
Factory
{
private
static
final
class
FactoryHolder
{
private
static
final
class
FactoryHolder
{
private
static
final
CommandFactory
factory
=
new
CommandFactory
();
private
static
final
CommandFactory
factory
=
new
CommandFactory
();
...
...
src/factory/Factory.java
→
src/factory/
Executables
Factory.java
View file @
49e510a1
...
@@ -5,6 +5,6 @@ import model.Command;
...
@@ -5,6 +5,6 @@ import model.Command;
import
java.util.List
;
import
java.util.List
;
public
interface
Factory
{
public
interface
Executables
Factory
{
CommandExecutable
<?>
getCommand
(
Command
command
,
List
<
String
>
args
);
CommandExecutable
<?>
getCommand
(
Command
command
,
List
<
String
>
args
);
}
}
src/factory/replica/ReplicaCommandFactory.java
View file @
49e510a1
...
@@ -4,12 +4,12 @@ import command.CommandExecutable;
...
@@ -4,12 +4,12 @@ import command.CommandExecutable;
import
command.replica.ReplicaFullRsyncCommand
;
import
command.replica.ReplicaFullRsyncCommand
;
import
command.replica.ReplicaReplConfCommand
;
import
command.replica.ReplicaReplConfCommand
;
import
command.replica.ReplicaSetCommand
;
import
command.replica.ReplicaSetCommand
;
import
factory.Factory
;
import
factory.
Executables
Factory
;
import
model.Command
;
import
model.Command
;
import
java.util.List
;
import
java.util.List
;
public
final
class
ReplicaCommandFactory
implements
Factory
{
public
final
class
ReplicaCommandFactory
implements
Executables
Factory
{
private
static
final
class
ReplicaFactoryHolder
{
private
static
final
class
ReplicaFactoryHolder
{
private
static
final
ReplicaCommandFactory
factory
=
new
ReplicaCommandFactory
();
private
static
final
ReplicaCommandFactory
factory
=
new
ReplicaCommandFactory
();
}
}
...
...
src/handlers/ClientCommandHandler.java
View file @
49e510a1
...
@@ -3,6 +3,7 @@ package handlers;
...
@@ -3,6 +3,7 @@ package handlers;
import
command.CommandExecutable
;
import
command.CommandExecutable
;
import
command.CommandInvoker
;
import
command.CommandInvoker
;
import
command.UnknownCommand
;
import
command.UnknownCommand
;
import
command.validation.Validatable
;
import
factory.CommandFactory
;
import
factory.CommandFactory
;
import
model.Command
;
import
model.Command
;
import
parser.CommandParser
;
import
parser.CommandParser
;
...
@@ -46,6 +47,7 @@ public final class ClientCommandHandler {
...
@@ -46,6 +47,7 @@ public final class ClientCommandHandler {
byte
[]
response
=
result
.
execute
();
byte
[]
response
=
result
.
execute
();
writeResponse
(
response
);
writeResponse
(
response
);
}
}
List
<
String
>
replicaCommand
=
createReplicaCommand
(
commands
);
List
<
String
>
replicaCommand
=
createReplicaCommand
(
commands
);
byte
[]
result
=
executeCommand
(
command
);
byte
[]
result
=
executeCommand
(
command
);
sendReplicaCommand
(
replicaCommand
);
sendReplicaCommand
(
replicaCommand
);
...
@@ -57,8 +59,8 @@ public final class ClientCommandHandler {
...
@@ -57,8 +59,8 @@ public final class ClientCommandHandler {
}
}
private
byte
[]
executeCommand
(
Command
command
)
throws
IOException
{
private
byte
[]
executeCommand
(
Command
command
)
throws
IOException
{
CommandExecutable
<
byte
[]>
commandProcessor
=
factory
.
getCommand
(
command
,
commands
.
subList
(
1
,
commands
.
size
()),
sendToReplica
,
os
);
CommandExecutable
<
byte
[]>
executable
=
factory
.
getCommand
(
command
,
commands
.
subList
(
1
,
commands
.
size
()),
sendToReplica
,
os
);
return
CommandInvoker
.
invoke
(
commandProcessor
);
return
CommandInvoker
.
invoke
(
executable
);
}
}
private
void
sendReplicaCommand
(
List
<
String
>
replicaCommand
)
{
private
void
sendReplicaCommand
(
List
<
String
>
replicaCommand
)
{
...
...
src/model/RdbFile.java
View file @
49e510a1
package
model
;
package
model
;
public
record
RdbFile
(
String
path
,
String
fileName
)
{
public
record
RdbFile
(
String
path
,
String
fileName
)
{
}
}
src/server/ReplicaConnectionService.java
View file @
49e510a1
...
@@ -37,8 +37,7 @@ public final class ReplicaConnectionService implements AutoCloseable {
...
@@ -37,8 +37,7 @@ public final class ReplicaConnectionService implements AutoCloseable {
}
}
ConnectionHandler
connectionHandler
=
new
ConnectionHandler
(
socket
,
commandParser
,
port
);
ConnectionHandler
connectionHandler
=
new
ConnectionHandler
(
socket
,
commandParser
,
port
);
BufferedReader
bufferedReader
=
connectionHandler
.
handleConnection
();
try
(
BufferedReader
bufferedReader
=
connectionHandler
.
handleConnection
())
{
try
{
logger
.
info
(
"Ending handshake"
);
logger
.
info
(
"Ending handshake"
);
Client
client
=
new
ReplicaClient
(
bufferedReader
,
socket
);
Client
client
=
new
ReplicaClient
(
bufferedReader
,
socket
);
executorService
.
submit
(
client:
:
run
);
executorService
.
submit
(
client:
:
run
);
...
...
src/server/SendToReplica.java
View file @
49e510a1
...
@@ -39,22 +39,23 @@ public final class SendToReplica implements Closeable {
...
@@ -39,22 +39,23 @@ public final class SendToReplica implements Closeable {
private
void
processCommands
()
{
private
void
processCommands
()
{
while
(
true
)
{
while
(
true
)
{
String
command
=
commands
.
poll
();
if
(
command
==
null
)
{
continue
;
}
byte
[]
commandBytes
=
command
.
getBytes
();
String
command
=
commands
.
poll
();
connectedReplicas
.
forEach
(
replica
->
{
if
(
command
==
null
)
{
try
{
continue
;
OutputStream
outputStream
=
replica
.
os
();
outputStream
.
write
(
commandBytes
);
outputStream
.
flush
();
}
catch
(
IOException
e
)
{
logger
.
log
(
Level
.
SEVERE
,
"Failed to send command to replica "
,
e
);
connectedReplicas
.
remove
(
replica
);
}
}
});
byte
[]
commandBytes
=
command
.
getBytes
();
connectedReplicas
.
forEach
(
replica
->
{
try
{
OutputStream
outputStream
=
replica
.
os
();
outputStream
.
write
(
commandBytes
);
outputStream
.
flush
();
}
catch
(
IOException
e
)
{
logger
.
log
(
Level
.
SEVERE
,
"Failed to send command to replica "
,
e
);
connectedReplicas
.
remove
(
replica
);
}
});
}
}
}
}
...
...
src/server/ServerBuilder.java
View file @
49e510a1
...
@@ -12,7 +12,7 @@ public final class ServerBuilder {
...
@@ -12,7 +12,7 @@ public final class ServerBuilder {
private
int
port
=
6379
;
private
int
port
=
6379
;
private
String
role
=
"master"
;
private
String
role
=
"master"
;
private
String
[]
masterPortAndHost
;
private
String
[]
masterPortAndHost
;
private
final
Serv
erInfo
server
Info
;
private
final
Serv
iceInfo
service
Info
;
private
final
RdbFileInfo
rdbFileInfo
;
private
final
RdbFileInfo
rdbFileInfo
;
private
final
Map
<
String
,
String
>
parameters
;
private
final
Map
<
String
,
String
>
parameters
;
private
ReplicaConnectionService
replicaConnectionService
;
private
ReplicaConnectionService
replicaConnectionService
;
...
@@ -21,7 +21,7 @@ public final class ServerBuilder {
...
@@ -21,7 +21,7 @@ public final class ServerBuilder {
logger
.
info
(
"Initializing ServerBuilder"
);
logger
.
info
(
"Initializing ServerBuilder"
);
this
.
parameters
=
Settings
.
extractArgs
(
args
);
this
.
parameters
=
Settings
.
extractArgs
(
args
);
this
.
port
=
Settings
.
extractPort
(
parameters
,
port
);
this
.
port
=
Settings
.
extractPort
(
parameters
,
port
);
this
.
serv
erInfo
=
Server
Info
.
getInstance
();
this
.
serv
iceInfo
=
Service
Info
.
getInstance
();
this
.
rdbFileInfo
=
RdbFileInfo
.
getInstance
();
this
.
rdbFileInfo
=
RdbFileInfo
.
getInstance
();
initializeFromParameters
();
initializeFromParameters
();
}
}
...
@@ -53,8 +53,8 @@ public final class ServerBuilder {
...
@@ -53,8 +53,8 @@ public final class ServerBuilder {
private
void
initializeFromParameters
()
{
private
void
initializeFromParameters
()
{
logger
.
info
(
"Initializing from parameters"
);
logger
.
info
(
"Initializing from parameters"
);
rdbFileInfo
.
setFile
(
parameters
);
rdbFileInfo
.
setFile
(
parameters
);
this
.
masterPortAndHost
=
serv
er
Info
.
findRole
(
parameters
);
this
.
masterPortAndHost
=
serv
ice
Info
.
findRole
(
parameters
);
this
.
role
=
serv
er
Info
.
getRole
();
this
.
role
=
serv
ice
Info
.
getRole
();
logger
.
info
(
"Initialized with role: "
+
role
);
logger
.
info
(
"Initialized with role: "
+
role
);
}
}
}
}
src/server/Serv
er
Info.java
→
src/server/Serv
ice
Info.java
View file @
49e510a1
...
@@ -4,23 +4,24 @@ package server;
...
@@ -4,23 +4,24 @@ package server;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.ConcurrentHashMap
;
public
final
class
Serv
er
Info
{
public
final
class
Serv
ice
Info
{
private
static
Serv
erInfo
server
Info
;
private
static
Serv
iceInfo
service
Info
;
private
final
Map
<
String
,
String
>
info
=
new
ConcurrentHashMap
<>();
private
final
Map
<
String
,
String
>
info
=
new
ConcurrentHashMap
<>();
private
Serv
er
Info
()
{
private
Serv
ice
Info
()
{
info
.
put
(
"role"
,
"master"
);
info
.
put
(
"role"
,
"master"
);
info
.
put
(
"cachePolicyName"
,
"caffeine"
);
}
}
public
static
Serv
er
Info
getInstance
()
{
public
static
Serv
ice
Info
getInstance
()
{
if
(
serv
er
Info
==
null
)
{
if
(
serv
ice
Info
==
null
)
{
serv
erInfo
=
new
Server
Info
();
serv
iceInfo
=
new
Service
Info
();
}
}
return
serv
er
Info
;
return
serv
ice
Info
;
}
}
public
String
getRole
()
{
public
String
getRole
()
{
return
serv
er
Info
.
info
.
get
(
"role"
);
return
serv
ice
Info
.
info
.
get
(
"role"
);
}
}
public
String
[]
findRole
(
Map
<
String
,
String
>
parameters
)
{
public
String
[]
findRole
(
Map
<
String
,
String
>
parameters
)
{
...
...
src/storage/Cacheable.java
View file @
49e510a1
...
@@ -5,4 +5,5 @@ public interface Cacheable<K, V> {
...
@@ -5,4 +5,5 @@ public interface Cacheable<K, V> {
void
save
(
K
key
,
V
value
,
Long
expirationTime
);
void
save
(
K
key
,
V
value
,
Long
expirationTime
);
V
get
(
K
key
);
V
get
(
K
key
);
void
delete
(
K
key
);
void
delete
(
K
key
);
void
runCachePolicy
();
}
}
src/storage/CaffeineCachePolicy.java
View file @
49e510a1
package
storage
;
package
storage
;
import
com.github.benmanes.caffeine.cache.Cache
;
import
com.github.benmanes.caffeine.cache.Cache
;
import
com.github.benmanes.caffeine.cache.Caffeine
;
import
com.github.benmanes.caffeine.cache.Caffeine
;
import
com.github.benmanes.caffeine.cache.RemovalCause
;
import
com.github.benmanes.caffeine.cache.RemovalCause
;
...
@@ -16,7 +15,7 @@ public class CaffeineCachePolicy<K, V> implements CachePolicy<K, V> {
...
@@ -16,7 +15,7 @@ public class CaffeineCachePolicy<K, V> implements CachePolicy<K, V> {
public
CaffeineCachePolicy
(
int
maxCapacity
)
{
public
CaffeineCachePolicy
(
int
maxCapacity
)
{
this
.
cache
=
Caffeine
.
newBuilder
()
this
.
cache
=
Caffeine
.
newBuilder
()
.
maximumSize
(
maxCapacity
)
.
maximumSize
(
maxCapacity
)
.
expireAfterAccess
(
60
,
TimeUnit
.
MINUTE
S
)
.
expireAfterAccess
(
60
,
TimeUnit
.
SECOND
S
)
.
evictionListener
((
K
key
,
V
value
,
RemovalCause
cause
)
->
.
evictionListener
((
K
key
,
V
value
,
RemovalCause
cause
)
->
logger
.
info
(
"Evicted key: "
+
key
+
", Value: "
+
value
+
", Reason: "
+
cause
))
logger
.
info
(
"Evicted key: "
+
key
+
", Value: "
+
value
+
", Reason: "
+
cause
))
.
build
();
.
build
();
...
...
src/storage/RdbFileReader.java
View file @
49e510a1
...
@@ -8,7 +8,6 @@ import java.io.IOException;
...
@@ -8,7 +8,6 @@ import java.io.IOException;
import
java.io.InputStream
;
import
java.io.InputStream
;
import
java.nio.ByteBuffer
;
import
java.nio.ByteBuffer
;
import
java.nio.ByteOrder
;
import
java.nio.ByteOrder
;
import
java.nio.charset.StandardCharsets
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Map
;
...
@@ -85,10 +84,6 @@ public class RdbFileReader<K, V> {
...
@@ -85,10 +84,6 @@ public class RdbFileReader<K, V> {
byte
[]
version
=
new
byte
[
4
];
byte
[]
version
=
new
byte
[
4
];
fis
.
read
(
redis
);
fis
.
read
(
redis
);
fis
.
read
(
version
);
fis
.
read
(
version
);
out
.
println
(
"Magic String = "
+
new
String
(
redis
,
StandardCharsets
.
UTF_8
));
out
.
println
(
"Version = "
+
new
String
(
version
,
StandardCharsets
.
UTF_8
));
int
b
;
int
b
;
header:
header:
while
((
b
=
fis
.
read
())
!=
-
1
)
{
while
((
b
=
fis
.
read
())
!=
-
1
)
{
...
@@ -116,8 +111,6 @@ public class RdbFileReader<K, V> {
...
@@ -116,8 +111,6 @@ public class RdbFileReader<K, V> {
break
;
break
;
}
}
}
}
out
.
println
(
"header done"
);
b
=
fis
.
read
();
b
=
fis
.
read
();
while
((
b
=
fis
.
read
())
!=
-
1
)
{
while
((
b
=
fis
.
read
())
!=
-
1
)
{
out
.
println
(
"value-type = "
+
b
);
out
.
println
(
"value-type = "
+
b
);
...
@@ -132,7 +125,6 @@ public class RdbFileReader<K, V> {
...
@@ -132,7 +125,6 @@ public class RdbFileReader<K, V> {
if
(!
Integer
.
toBinaryString
(
b
).
equals
(
"0"
))
{
if
(!
Integer
.
toBinaryString
(
b
).
equals
(
"0"
))
{
break
;
break
;
}
}
out
.
println
(
"reading keys"
);
key
=
getKey
(
fis
,
b
);
key
=
getKey
(
fis
,
b
);
out
.
println
(
key
);
out
.
println
(
key
);
String
value
=
getValue
(
fis
);
String
value
=
getValue
(
fis
);
...
...
src/storage/Storage.java
View file @
49e510a1
...
@@ -3,14 +3,14 @@ package storage;
...
@@ -3,14 +3,14 @@ package storage;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.ConcurrentHashMap
;
public
class
Storage
{
public
class
Storage
implements
Cacheable
<
String
,
String
>
{
private
final
int
capacity
=
1000000
;
private
final
int
capacity
=
1000000
;
private
final
CachePolicy
<
String
,
String
>
storage
;
private
final
CachePolicy
<
String
,
String
>
storage
;
private
final
Map
<
String
,
Long
>
timeToExpiration
=
new
ConcurrentHashMap
<>(
capacity
);
private
final
Map
<
String
,
Long
>
timeToExpiration
=
new
ConcurrentHashMap
<>(
capacity
);
private
final
Map
<
String
,
Long
>
currentTimeForKey
=
new
ConcurrentHashMap
<>(
capacity
);
private
final
Map
<
String
,
Long
>
currentTimeForKey
=
new
ConcurrentHashMap
<>(
capacity
);
private
Storage
()
{
private
Storage
()
{
this
.
storage
=
new
CaffeineCachePolicy
<>
(
capacity
);
this
.
storage
=
CachePolicyFactory
.
getPolicy
(
capacity
);
RdbFileReader
<
String
,
String
>
reader
=
new
RdbFileReader
<>();
RdbFileReader
<
String
,
String
>
reader
=
new
RdbFileReader
<>();
Map
<
String
,
Long
>
stringStringMap
=
reader
.
getKeysExpiration
();
Map
<
String
,
Long
>
stringStringMap
=
reader
.
getKeysExpiration
();
this
.
timeToExpiration
.
putAll
(
stringStringMap
);
this
.
timeToExpiration
.
putAll
(
stringStringMap
);
...
@@ -20,23 +20,26 @@ public class Storage {
...
@@ -20,23 +20,26 @@ public class Storage {
private
static
final
Storage
instance
=
new
Storage
();
private
static
final
Storage
instance
=
new
Storage
();
}
}
public
static
Storage
getInstance
()
{
public
static
Cacheable
<
String
,
String
>
getInstance
()
{
return
StorageHolder
.
instance
;
return
StorageHolder
.
instance
;
}
}
@Override
public
void
save
(
String
key
,
String
value
)
{
public
void
save
(
String
key
,
String
value
)
{
storage
.
add
(
key
,
value
);
storage
.
add
(
key
,
value
);
}
}
@Override
public
void
save
(
String
key
,
String
value
,
Long
expirationTime
)
{
public
void
save
(
String
key
,
String
value
,
Long
expirationTime
)
{
currentTimeForKey
.
put
(
key
,
System
.
currentTimeMillis
());
currentTimeForKey
.
put
(
key
,
System
.
currentTimeMillis
());
timeToExpiration
.
put
(
key
,
expirationTime
);
timeToExpiration
.
put
(
key
,
expirationTime
);
save
(
key
,
value
);
save
(
key
,
value
);
}
}
@Override
public
String
get
(
String
key
)
{
public
String
get
(
String
key
)
{
if
(
isExpired
(
key
))
{
if
(
isExpired
(
key
))
{
remov
e
(
key
);
delet
e
(
key
);
return
""
;
return
""
;
}
}
return
storage
.
retrieve
(
key
);
return
storage
.
retrieve
(
key
);
...
@@ -52,13 +55,14 @@ public class Storage {
...
@@ -52,13 +55,14 @@ public class Storage {
return
false
;
return
false
;
}
}
private
void
remove
(
String
key
)
{
@Override
public
void
delete
(
String
key
)
{
storage
.
delete
(
key
);
storage
.
delete
(
key
);
timeToExpiration
.
remove
(
key
);
timeToExpiration
.
remove
(
key
);
currentTimeForKey
.
remove
(
key
);
currentTimeForKey
.
remove
(
key
);
}
}
@Override
void
runCachePolicy
()
{
public
void
runCachePolicy
()
{
storage
.
runMaintenance
();
storage
.
runMaintenance
();
}
}
}
}
\ No newline at end of file
src/storage/StorageManager.java
View file @
49e510a1
...
@@ -7,7 +7,7 @@ import java.util.logging.Level;
...
@@ -7,7 +7,7 @@ import java.util.logging.Level;
import
java.util.logging.Logger
;
import
java.util.logging.Logger
;
public
class
StorageManager
{
public
class
StorageManager
{
private
final
Storage
storage
;
private
final
Cacheable
<
String
,
String
>
storage
;
private
final
ScheduledExecutorService
scheduler
;
private
final
ScheduledExecutorService
scheduler
;
private
static
final
Logger
logger
=
Logger
.
getLogger
(
StorageManager
.
class
.
getName
());
private
static
final
Logger
logger
=
Logger
.
getLogger
(
StorageManager
.
class
.
getName
());
...
...
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