package edu.umn.cs.recsys.dao; import it.unimi.dsi.fastutil.longs.LongSet; import it.unimi.dsi.fastutil.objects.Object2LongMap; import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; import org.grouplens.lenskit.collections.LongUtils; import org.grouplens.lenskit.cursors.Cursor; import org.grouplens.lenskit.data.dao.DataAccessException; import org.grouplens.lenskit.util.DelimitedTextCursor; import javax.inject.Inject; import java.io.File; import java.io.FileNotFoundException; /** * @author <a href="http://www.grouplens.org">GroupLens Research</a> */ public class MOOCUserDAO implements UserNameDAO { private final File userFile; private transient volatile Object2LongMap<String> nameCache; private transient volatile LongSet userIds; @Inject public MOOCUserDAO(@UserFile File file) { userFile = file; } private void ensureNameCache() { if (nameCache == null) { synchronized (this) { if (nameCache == null) { nameCache = loadNameCache(); userIds = LongUtils.packedSet(nameCache.values()); } } } } private Object2LongMap<String> loadNameCache() { Object2LongMap<String> cache = new Object2LongOpenHashMap<String>(); // make the cache return -1 for missing users cache.defaultReturnValue(-1); Cursor<String[]> lines = null; try { lines = new DelimitedTextCursor(userFile, ","); } catch (FileNotFoundException e) { throw new DataAccessException("cannot open file", e); } try { for (String[] line: lines) { long uid = Long.parseLong(line[0]); cache.put(line[1], uid); } } finally { lines.close(); } return cache; } @Override public LongSet getUserIds() { ensureNameCache(); return userIds; } @Override public long getUserByName(String name) { ensureNameCache(); return nameCache.get(name); } }