Changes to FilePerKeyMap made after testing on Linux.

This commit is contained in:
daniel
2015-04-27 12:28:03 +01:00
parent 4743f9b870
commit 17cc8a1f2d
2 changed files with 53 additions and 39 deletions
@@ -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();
}
}