Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory storage #68

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 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
16 changes: 16 additions & 0 deletions .github/workflows/java-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@ jobs:
matrix:
java: [ '8', '11', '17']
name: JDK ${{ matrix.Java }} build

services:
# Label used to access the service container
redis:
# Docker Hub image
image: redis
# Set health checks to wait until redis has started
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
# Maps port 6379 on service container to the host
- 6379:6379

steps:
- uses: actions/[email protected]
- name: Set up Java
Expand Down
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.10.1'
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
api 'io.lettuce:lettuce-core:6.3.2.RELEASE'

}

Expand Down
108 changes: 108 additions & 0 deletions src/main/java/br/unicamp/cst/memorystorage/ExternalTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package br.unicamp.cst.memorystorage;

import br.unicamp.cst.core.entities.MemoryObject;
import br.unicamp.cst.core.entities.Mind;
import io.lettuce.core.RedisClient;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;

/**
* Code created to test the communication of CST-Java Memory Storage with other instances.
* At the moment, it must be executed manually.
*/
public class ExternalTest {

private static final long SLEEP_TIME = (long) (0.75 * 1000);

public static void main(String[] args){
EltonCN marked this conversation as resolved.
Show resolved Hide resolved
RedisClient redisClient = RedisClient.create("redis://localhost");
StatefulRedisConnection<String, String> connection = redisClient.connect();
RedisAsyncCommands<String, String> commands = connection.async();
try {
commands.flushall().get();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}

Mind mind = new Mind();
MemoryObject memory1 = mind.createMemoryObject("Memory1", false);
MemoryStorageCodelet ms;
try{
ms = new MemoryStorageCodelet(mind);
ms.setTimeStep(100);
} catch(Exception e)
{
e.printStackTrace();
System.exit(1);
return;
}

long lastTimestamp = memory1.getTimestamp();

mind.insertCodelet(ms);
mind.start();


try{
boolean valid = false;

for(int i = 0; i<30; i++)
{
Thread.sleep(100);

if (lastTimestamp != memory1.getTimestamp()) {
boolean info = (boolean) memory1.getI();
if(info)
{
valid = true;
break;
}
}
}

if(!valid)
{
System.err.print("Could not communicate with the other CST node");
System.exit(1);
}

memory1.setI("JAVA_INFO");

Thread.sleep(SLEEP_TIME);

String stringInfo = (String) memory1.getI();
assert stringInfo.equals("OTHER_INFO");

memory1.setI(1);
Thread.sleep(SLEEP_TIME);

Long longInfo = (Long) memory1.getI();
assert longInfo == -1;

memory1.setI(1.0);

Thread.sleep(SLEEP_TIME);

Double doubleInfo = (Double) memory1.getI();
assert doubleInfo == 5.0;

//while (true) {
// if (lastTimestamp != memory1.getTimestamp()) {
// System.out.println();
// System.out.println(memory1);
//
// lastTimestamp = memory1.getTimestamp();
// }
//}
} catch(Exception e)
{
e.printStackTrace();
System.exit(1);
return;
}


}

}
89 changes: 89 additions & 0 deletions src/main/java/br/unicamp/cst/memorystorage/LamportTime.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package br.unicamp.cst.memorystorage;

/**
* Logical time implementation using Lamport times.
*/
public class LamportTime implements LogicalTime {

private int time;

/**
* LamportTime constructor.
*
* @param initialTime time to start the clock.
*/
public LamportTime(int initialTime)
{
this.time = initialTime;
}

/**
* LamportTime constructor.
*/
public LamportTime()
{
this(0);
}

/**
* Get the clock internal time.
* @return clock internal time.
*/
public int getTime()
{
return this.time;
}

@Override
public LamportTime increment() {
return new LamportTime(this.time+1);
}

public static LamportTime fromString(String string)
{
return new LamportTime(Integer.parseInt(string));
}

public String toString()
{
return Integer.toString(time);
}


public static LamportTime synchronize(LogicalTime time0, LogicalTime time1) {
if(!(LogicalTime.class.isInstance(time0) && LogicalTime.class.isInstance(time1))){
throw new IllegalArgumentException("LamportTime can only synchonize LamportTime instances");
}

LamportTime lamportTime0 = (LamportTime) time0;
LamportTime lamportTime1 = (LamportTime) time1;

int newTime = 0;
if(time0.lessThan(time1)){
newTime = lamportTime1.getTime();
}
else{
newTime = lamportTime0.getTime();
}

newTime += 1;

return new LamportTime(newTime);

}

@Override
public boolean lessThan(Object o) {
LamportTime otherTime = (LamportTime) o;

return this.time < otherTime.getTime();
}

@Override
public boolean equals(Object o)
{
LamportTime otherTime = (LamportTime) o;
return this.time == otherTime.getTime();
EltonCN marked this conversation as resolved.
Show resolved Hide resolved
}

}
44 changes: 44 additions & 0 deletions src/main/java/br/unicamp/cst/memorystorage/LogicalTime.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package br.unicamp.cst.memorystorage;

/**
* A logical time for distributed communication.
*/
public interface LogicalTime {

/**
* Returns a time with the self time incremented by one.
*
* @return incremented time.
*/
public abstract LogicalTime increment();

/**
* Creates a instance from a string.
*
* @param string String to create time, generated with LogicalTime.toString().
* @return Created time.
*/
public static LogicalTime fromString(String string)
{
throw new IllegalStateException("fromString not implemented in the subclass");
}

@Override
public abstract String toString();

/**
* Compares two times, and return the current time.
*
* @param time0 first time to compare.
* @param time1 second time to compare.
* @return current time.
*/
public static LogicalTime synchronize(LogicalTime time0, LogicalTime time1)
{
throw new IllegalStateException("synchronize not implemented in the subclass");
}

@Override
public abstract boolean equals(Object o);
public abstract boolean lessThan(Object o);
}
56 changes: 56 additions & 0 deletions src/main/java/br/unicamp/cst/memorystorage/MemoryEncoder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package br.unicamp.cst.memorystorage;

import java.util.HashMap;
import java.util.Map;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.ToNumberPolicy;

import br.unicamp.cst.core.entities.Memory;

/**
* Encodes and decodes Memories.
*/
public class MemoryEncoder {
static Gson gson = new GsonBuilder().setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE).create();

private MemoryEncoder() {

}

/**
* Encodes a memory to a Map.
*
* @param memory memory to encode.
* @return the encoded memory.
*/
public static Map<String, String> toDict(Memory memory) {
Map<String, String> data = new HashMap<>();

data.put("name", memory.getName());
data.put("evaluation", memory.getEvaluation().toString());
data.put("id", memory.getId().toString());
data.put("timestamp", memory.getTimestamp().toString());

data.put("I", gson.toJson(memory.getI()));

return data;
}

/**
* Load a memory from a Map.
*
* @param memory memory to store the loaded info.
* @param memoryDict map encoded memory.
*/
public static void loadMemory(Memory memory, Map<String, String> memoryDict) {
memory.setEvaluation(Double.parseDouble(memoryDict.get("evaluation")));
memory.setId(Long.parseLong(memoryDict.get("id")));

String infoJSON = memoryDict.get("I");
Object info = gson.fromJson(infoJSON, Object.class);
memory.setI(info);
}

}
Loading
Loading