package com.codecademy.eventhub.index;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.io.PatternFilenameFilter;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.codecademy.eventhub.list.DmaIdList;
import com.codecademy.eventhub.list.IdList;
import javax.inject.Named;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
public class ShardedEventIndexModule extends AbstractModule {
@Override
protected void configure() {}
@Provides
@Named("eventhub.shardedeventindex.directory")
public String getEventIndexDirectory(
@Named("eventhub.directory") String eventHubDirectory) {
return eventHubDirectory + "/event_index/";
}
@Provides
@Named("eventhub.shardedeventindex.filename")
public String getEventIndexFile(
@Named("eventhub.shardedeventindex.directory") String eventIndexDirectory) {
return eventIndexDirectory + "/event_index.ser";
}
@Provides
@Named("eventhub.shardedeventindex.datedeventindex.filename")
public String getDatedEventIndexFile(
@Named("eventhub.shardedeventindex.directory") String eventIndexDirectory) {
return eventIndexDirectory + "/dated_event_index.ser";
}
@Provides
public EventIndex.Factory getEventIndexFactory(
final @Named("eventhub.shardedeventindex.directory") String shardedEventIndexDirectory,
final @Named("eventhub.eventindex.initialNumEventIdsPerDay") int initialNumEventIdsPerDay,
final DmaIdList.Factory dmaIdListFactory) {
dmaIdListFactory.setDefaultCapacity(initialNumEventIdsPerDay);
return new EventIndex.Factory() {
@Override
public EventIndex build(String eventType) {
String eventIndexDirectory =
String.format("%s/%s/", shardedEventIndexDirectory, eventType);
List<String> dates = Lists.newArrayList();
File[] files = new File(eventIndexDirectory).listFiles(new PatternFilenameFilter("[0-9]{8}\\.ser"));
if (files != null) {
for (File file : files){
dates.add(file.getName().substring(0, 8));
}
}
SortedMap<String, IdList> eventIdListMap = Maps.newTreeMap();
for (String date : dates) {
eventIdListMap.put(date, dmaIdListFactory.build(
EventIndex.getEventIdListFilename(
eventIndexDirectory, date)));
}
return new EventIndex(eventIndexDirectory,
dmaIdListFactory, eventIdListMap);
}
};
}
@Provides
public ShardedEventIndex getShardedEventIndex(
@Named("eventhub.shardedeventindex.filename") String eventIndexFilename,
EventIndex.Factory individualEventIndexFactory) {
File file = new File(eventIndexFilename);
if (file.exists()) {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
@SuppressWarnings("unchecked")
Map<String, Integer> eventTypeIdMap = (Map<String, Integer>) ois.readObject();
Map<String, EventIndex> eventIndexMap = Maps.newHashMap();
for (String eventType : eventTypeIdMap.keySet()) {
eventIndexMap.put(eventType, individualEventIndexFactory.build(eventType));
}
return new ShardedEventIndex(eventIndexFilename, individualEventIndexFactory, eventIndexMap,
eventTypeIdMap);
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
return new ShardedEventIndex(eventIndexFilename, individualEventIndexFactory,
Maps.<String,EventIndex>newHashMap(), Maps.<String, Integer>newHashMap());
}
}