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
a16f4887
Commit
a16f4887
authored
Aug 13, 2024
by
amir.yosef
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adding LRU Strategy
parent
eb57815b
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
147 additions
and
30 deletions
+147
-30
Main.java
src/Main.java
+3
-2
CommandFactory.java
src/factory/CommandFactory.java
+0
-1
Server.java
src/server/Server.java
+15
-6
CachePolicy.java
src/storage/CachePolicy.java
+8
-0
LRUCachePolicy.java
src/storage/LRUCachePolicy.java
+61
-0
Storage.java
src/storage/Storage.java
+24
-21
StorageManager.java
src/storage/StorageManager.java
+36
-0
No files found.
src/Main.java
View file @
a16f4887
...
@@ -9,7 +9,8 @@ public class Main {
...
@@ -9,7 +9,8 @@ public class Main {
ServerBuilder
builder
=
new
ServerBuilder
();
ServerBuilder
builder
=
new
ServerBuilder
();
director
.
buildMaster
(
builder
);
director
.
buildMaster
(
builder
);
builder
.
port
(
16379
);
builder
.
port
(
16379
);
Server
server
=
builder
.
build
();
try
(
Server
server
=
builder
.
build
())
{
server
.
start
();
server
.
start
();
}
}
}
}
}
\ No newline at end of file
src/factory/CommandFactory.java
View file @
a16f4887
...
@@ -12,7 +12,6 @@ public class CommandFactory implements Factory {
...
@@ -12,7 +12,6 @@ public class CommandFactory implements Factory {
}
}
public
CommandFactory
()
{
public
CommandFactory
()
{
}
}
public
static
CommandFactory
getInstance
()
{
public
static
CommandFactory
getInstance
()
{
...
...
src/server/Server.java
View file @
a16f4887
...
@@ -2,6 +2,7 @@ package server;
...
@@ -2,6 +2,7 @@ package server;
import
client.Client
;
import
client.Client
;
import
client.primary.MasterClient
;
import
client.primary.MasterClient
;
import
storage.StorageManager
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.net.ServerSocket
;
import
java.net.ServerSocket
;
...
@@ -9,12 +10,13 @@ import java.net.Socket;
...
@@ -9,12 +10,13 @@ import java.net.Socket;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.Executors
;
public
class
Server
{
public
class
Server
implements
AutoCloseable
{
private
final
int
PORT
;
private
final
int
PORT
;
private
final
ExecutorService
executor
;
private
final
ExecutorService
executor
;
private
final
String
role
;
private
final
String
role
;
StorageManager
manager
=
new
StorageManager
();
private
static
Server
instance
;
private
static
volatile
Server
instance
;
Server
(
int
port
,
String
role
)
{
Server
(
int
port
,
String
role
)
{
PORT
=
port
;
PORT
=
port
;
...
@@ -22,9 +24,11 @@ public class Server {
...
@@ -22,9 +24,11 @@ public class Server {
this
.
executor
=
Executors
.
newVirtualThreadPerTaskExecutor
();
this
.
executor
=
Executors
.
newVirtualThreadPerTaskExecutor
();
}
}
public
static
synchronized
Server
getInstance
(
int
PORT
,
String
role
)
throws
IOException
{
public
static
Server
getInstance
(
int
PORT
,
String
role
)
throws
IOException
{
if
(
role
.
equalsIgnoreCase
(
"master"
))
{
if
(
instance
==
null
)
{
if
(
instance
==
null
)
{
instance
=
new
Server
(
PORT
,
role
);
instance
=
new
Server
(
PORT
,
role
);
}
}
}
return
instance
;
return
instance
;
}
}
...
@@ -51,4 +55,9 @@ public class Server {
...
@@ -51,4 +55,9 @@ public class Server {
task
.
run
();
task
.
run
();
});
});
}
}
@Override
public
void
close
()
{
manager
.
shutdown
();
}
}
}
src/storage/CachePolicy.java
0 → 100644
View file @
a16f4887
package
storage
;
public
interface
CachePolicy
<
K
,
V
>
{
void
add
(
K
key
,
V
value
);
V
retrieve
(
K
key
);
void
delete
(
K
key
);
void
runMaintenance
();
}
\ No newline at end of file
src/storage/LRUCachePolicy.java
0 → 100644
View file @
a16f4887
package
storage
;
import
java.util.Map
;
import
java.util.Queue
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.ConcurrentLinkedQueue
;
public
class
LRUCachePolicy
<
K
,
V
>
implements
CachePolicy
<
K
,
V
>
{
private
final
int
maxCapacity
;
private
final
Map
<
K
,
V
>
cacheMap
;
private
final
Queue
<
K
>
accessOrder
;
public
LRUCachePolicy
(
int
maxCapacity
)
{
this
.
maxCapacity
=
maxCapacity
;
this
.
cacheMap
=
new
ConcurrentHashMap
<>(
maxCapacity
);
this
.
accessOrder
=
new
ConcurrentLinkedQueue
<>();
}
@Override
public
void
add
(
K
key
,
V
value
)
{
cacheMap
.
put
(
key
,
value
);
updateAccessOrder
(
key
);
}
@Override
public
V
retrieve
(
K
key
)
{
V
value
=
cacheMap
.
get
(
key
);
if
(
value
!=
null
)
{
updateAccessOrder
(
key
);
}
return
value
;
}
@Override
public
void
delete
(
K
key
)
{
cacheMap
.
remove
(
key
);
accessOrder
.
remove
(
key
);
}
@Override
public
void
runMaintenance
()
{
while
(
cacheMap
.
size
()
>
maxCapacity
)
{
evictLeastRecentlyUsed
();
}
}
private
void
updateAccessOrder
(
K
key
)
{
accessOrder
.
remove
(
key
);
accessOrder
.
offer
(
key
);
}
private
void
evictLeastRecentlyUsed
()
{
while
(!
accessOrder
.
isEmpty
())
{
K
leastRecentKey
=
accessOrder
.
poll
();
if
(
cacheMap
.
containsKey
(
leastRecentKey
))
{
delete
(
leastRecentKey
);
break
;
}
}
}
}
\ No newline at end of file
src/storage/Storage.java
View file @
a16f4887
package
storage
;
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
{
private
final
Map
<
String
,
String
>
storage
=
new
ConcurrentHashMap
<>(
10000
)
;
private
final
int
capacity
=
10000
;
private
final
Map
<
String
,
Long
>
timeToExpiration
=
new
ConcurrentHashMap
<>(
10000
)
;
private
final
CachePolicy
<
String
,
String
>
storage
;
private
final
Map
<
String
,
Long
>
currentTimeForKey
=
new
ConcurrentHashMap
<>(
10000
);
private
final
Map
<
String
,
Long
>
timeToExpiration
=
new
ConcurrentHashMap
<>(
capacity
);
private
final
Map
<
String
,
Long
>
currentTimeForKey
=
new
ConcurrentHashMap
<>(
capacity
);
private
Storage
()
{
private
Storage
()
{
// RdbFileReader reader = new RdbFileReader();
this
.
storage
=
new
LRUCachePolicy
<>(
capacity
);
//Map<String, String> stringStringMap = reader.readFile();
// storage.putAll(stringStringMap);
//Map<String, Long> keysExpiration = reader.getKeysExpiration();
// timeToExpiration.putAll(keysExpiration);
}
}
private
static
final
class
StorageHolder
{
private
static
final
class
StorageHolder
{
private
static
final
Storage
storag
e
=
new
Storage
();
private
static
final
Storage
instanc
e
=
new
Storage
();
}
}
public
static
Storage
getInstance
()
{
public
static
Storage
getInstance
()
{
return
StorageHolder
.
storag
e
;
return
StorageHolder
.
instanc
e
;
}
}
public
void
save
(
String
key
,
String
value
)
{
public
void
save
(
String
key
,
String
value
)
{
storage
.
put
(
key
,
value
);
storage
.
add
(
key
,
value
);
}
}
public
void
save
(
String
key
,
String
value
,
Long
time
)
{
public
void
save
(
String
key
,
String
value
,
Long
expirationTime
)
{
System
.
out
.
println
(
"SAVE Storage: "
+
key
);
currentTimeForKey
.
put
(
key
,
System
.
currentTimeMillis
());
currentTimeForKey
.
put
(
key
,
System
.
currentTimeMillis
());
timeToExpiration
.
put
(
key
,
t
ime
);
timeToExpiration
.
put
(
key
,
expirationT
ime
);
save
(
key
,
value
);
save
(
key
,
value
);
}
}
public
String
get
(
String
key
)
{
public
String
get
(
String
key
)
{
if
(
isExpired
(
key
))
return
""
;
if
(
isExpired
(
key
))
{
return
storage
.
get
(
key
);
remove
(
key
);
return
""
;
}
return
storage
.
retrieve
(
key
);
}
}
private
boolean
isExpired
(
String
key
)
{
private
boolean
isExpired
(
String
key
)
{
...
@@ -61,5 +57,12 @@ public class Storage {
...
@@ -61,5 +57,12 @@ public class Storage {
return
false
;
return
false
;
}
}
private
void
remove
(
String
key
)
{
storage
.
delete
(
key
);
timeToExpiration
.
remove
(
key
);
currentTimeForKey
.
remove
(
key
);
}
void
runCachePolicy
()
{
storage
.
runMaintenance
();
}
}
}
\ No newline at end of file
src/storage/StorageManager.java
0 → 100644
View file @
a16f4887
package
storage
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.ScheduledExecutorService
;
import
java.util.concurrent.TimeUnit
;
public
class
StorageManager
{
private
final
Storage
storage
;
private
final
ScheduledExecutorService
scheduler
;
public
StorageManager
()
{
this
.
storage
=
Storage
.
getInstance
();
this
.
scheduler
=
Executors
.
newSingleThreadScheduledExecutor
();
scheduler
.
scheduleAtFixedRate
(
this
::
performMaintenance
,
5
,
5
,
TimeUnit
.
MINUTES
);
}
public
Storage
getStorage
()
{
return
storage
;
}
private
void
performMaintenance
()
{
storage
.
runCachePolicy
();
System
.
out
.
println
(
"Maintenance performed at: "
+
System
.
currentTimeMillis
());
}
public
void
shutdown
()
{
scheduler
.
shutdown
();
try
{
if
(!
scheduler
.
awaitTermination
(
60
,
TimeUnit
.
SECONDS
))
{
scheduler
.
shutdownNow
();
}
}
catch
(
InterruptedException
e
)
{
scheduler
.
shutdownNow
();
}
}
}
\ No newline at end of file
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