mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
Changes to FilePerKeyMap made after testing on Linux.
This commit is contained in:
@@ -29,6 +29,7 @@ import java.util.stream.Stream;
|
||||
public class FilePerKeyMap implements Map<String, String> {
|
||||
private final Path dirPath;
|
||||
private final Map<File, Long> lastModifiedByProgram = new ConcurrentHashMap<>();
|
||||
private final Map<File, String> lastUpdate = new ConcurrentHashMap<>();
|
||||
private final List<Consumer<FPMEvent>> listeners = new ArrayList<>();
|
||||
private final FPMWatcher fileFpmWatcher = new FPMWatcher();
|
||||
|
||||
@@ -147,7 +148,7 @@ public class FilePerKeyMap implements Map<String, String> {
|
||||
String existingValue = null;
|
||||
if(Files.exists(path)) {
|
||||
try {
|
||||
existingValue = Files.readAllLines(path).stream().collect(Collectors.joining());
|
||||
existingValue = Files.readAllLines(path).stream().collect(Collectors.joining("\n"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -242,21 +243,24 @@ public class FilePerKeyMap implements Map<String, String> {
|
||||
try {
|
||||
key = watcher.take();
|
||||
for (WatchEvent<?> event : key.pollEvents()) {
|
||||
// get event type
|
||||
WatchEvent.Kind<?> kind = event.kind();
|
||||
|
||||
// get file name
|
||||
WatchEvent<Path> ev = (WatchEvent<Path>) event;
|
||||
Path fileName = ev.context();
|
||||
|
||||
String mapKey = fileName.toString();
|
||||
|
||||
if(mapKey.startsWith(".")){
|
||||
//this avoids temporary files being added to the map
|
||||
continue;
|
||||
}
|
||||
|
||||
if (kind == StandardWatchEventKinds.OVERFLOW) {
|
||||
continue;
|
||||
} else if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
|
||||
Path p = dirPath.resolve(fileName);
|
||||
String mapVal = getFileContents(p);
|
||||
lastUpdate.put(p.toFile(), mapVal);
|
||||
if(isProgrammaticUpdate(p.toFile())){
|
||||
fireEvent(new FPMEvent(FPMEvent.EventType.NEW, true, mapKey,mapVal));
|
||||
}else {
|
||||
@@ -264,15 +268,25 @@ public class FilePerKeyMap implements Map<String, String> {
|
||||
}
|
||||
} else if (kind == StandardWatchEventKinds.ENTRY_DELETE) {
|
||||
Path p = dirPath.resolve(fileName);
|
||||
lastUpdate.remove(p.toFile());
|
||||
if(isProgrammaticUpdate(p.toFile())){
|
||||
fireEvent(new FPMEvent(FPMEvent.EventType.DELETE, true, mapKey, null));
|
||||
lastModifiedByProgram.remove(p.toFile());
|
||||
}else {
|
||||
fireEvent(new FPMEvent(FPMEvent.EventType.DELETE, false, mapKey, null));
|
||||
}
|
||||
} else if (kind == StandardWatchEventKinds.ENTRY_MODIFY) {
|
||||
Path p = dirPath.resolve(fileName);
|
||||
String mapVal = getFileContents(p);
|
||||
String lastVal = null;
|
||||
if(mapVal != null) {
|
||||
lastVal = lastUpdate.put(p.toFile(), mapVal);
|
||||
}
|
||||
|
||||
if(lastVal != null && lastVal.equals(mapVal)){
|
||||
//Nothing has changed don't fire an event
|
||||
continue;
|
||||
}
|
||||
|
||||
if(isProgrammaticUpdate(p.toFile())){
|
||||
fireEvent(new FPMEvent(FPMEvent.EventType.UPDATE, true, mapKey,mapVal));
|
||||
}else {
|
||||
@@ -287,7 +301,7 @@ public class FilePerKeyMap implements Map<String, String> {
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package net.openhft.chronicle.map;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
@@ -13,17 +12,18 @@ import static org.junit.Assert.*;
|
||||
* JUnit test class to support {@link FilePerKeyMapTest}
|
||||
*/
|
||||
public class FilePerKeyMapTest {
|
||||
private static FilePerKeyMap map;
|
||||
@BeforeClass
|
||||
public static void createMap(){
|
||||
map = new FilePerKeyMap("/tmp/filepermaptests");
|
||||
//just in case it hasn't been cleared up last time
|
||||
map.clear();
|
||||
}
|
||||
/**
|
||||
* Testing all the methods of the map with simple tests.
|
||||
*/
|
||||
@Test
|
||||
public void testMapMethods() {
|
||||
//There are no entries in the map so null should be returned
|
||||
FilePerKeyMap map = new FilePerKeyMap("/tmp/filepermaptests");
|
||||
|
||||
//just in case it hasn't been cleared up last time
|
||||
map.clear();
|
||||
|
||||
String val = map.put("one", "test1");
|
||||
assertEquals(val, null);
|
||||
|
||||
@@ -103,25 +103,11 @@ public class FilePerKeyMapTest {
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(3000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
map.clear();
|
||||
map.close();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void perfTest(){
|
||||
//There are no entries in the map so null should be returned
|
||||
FilePerKeyMap map = new FilePerKeyMap("/tmp/filepermaptests");
|
||||
|
||||
//just in case it hasn't been cleared up last time
|
||||
map.clear();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < 2_000_000; i++) {
|
||||
sb.append('x');
|
||||
@@ -139,32 +125,46 @@ public class FilePerKeyMapTest {
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
map.put("big file", value);
|
||||
}
|
||||
System.out.println("Time to update "+ iterations + " iterations " + (System.currentTimeMillis()-time));
|
||||
System.out.println("Time to update " + iterations + " iterations " + (System.currentTimeMillis() - time));
|
||||
|
||||
map.clear();
|
||||
map.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void eventTest() {
|
||||
//There are no entries in the map so null should be returned
|
||||
FilePerKeyMap map = new FilePerKeyMap("/tmp/filepermaptests");
|
||||
final List<FPMEvent> events = new ArrayList<>();
|
||||
|
||||
//just in case it hasn't been cleared up last time
|
||||
map.clear();
|
||||
|
||||
map.registerForEvents(e -> System.out.println(e));
|
||||
Consumer<FPMEvent> fpmEventConsumer = (FPMEvent e) -> {
|
||||
System.out.println(e);
|
||||
events.add(e);
|
||||
};
|
||||
map.registerForEvents(fpmEventConsumer);
|
||||
|
||||
map.put("one", "one");
|
||||
map.put("one", "two");
|
||||
map.remove("one");
|
||||
map.put("one", "one");
|
||||
|
||||
try {
|
||||
Thread.sleep(3000);
|
||||
//Allow all events to be played through
|
||||
Thread.sleep(1000);
|
||||
//Check the events
|
||||
assertEquals(4, events.size());
|
||||
|
||||
assertEquals(FPMEvent.EventType.NEW,events.get(0).getEventType());
|
||||
assertEquals(FPMEvent.EventType.UPDATE, events.get(1).getEventType());
|
||||
assertEquals(FPMEvent.EventType.DELETE, events.get(2).getEventType());
|
||||
assertEquals(FPMEvent.EventType.NEW, events.get(3).getEventType());
|
||||
|
||||
assertEquals(true, events.get(0).isProgrammatic());
|
||||
assertEquals(true, events.get(1).isProgrammatic());
|
||||
assertEquals(true, events.get(2).isProgrammatic());
|
||||
assertEquals(true, events.get(3).isProgrammatic());
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
map.unregisterForEvents(fpmEventConsumer);
|
||||
map.clear();
|
||||
map.close();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user