sclass FilesBasedStringMap extends AbstractMap { File dir; *() {} *(File *dir) {} public S get(O a) { ret dropFirstLine(loadGZTextFile(fileForKey(a))); } public synchronized Set> entrySet() { Set> set = new HashSet; for (File f : listFiles(dir)) { S md5 = md5FromUniqueFile(f); if (md5 == null) continue; fS key = unquote(firstLineFromFile(f)); set.add(new Map.Entry() { public S getKey() { ret key; } public S getValue() { ret get(key); } public S setValue(S s) { S old = get(key); put(key, s); ret old; } public bool equals(O o) { if (!(o instanceof Map.Entry)) false; Map.Entry e = (Map.Entry) o; ret eq(getKey(), e.getKey()) && eq(getValue(), e.getValue()); } public int hashCode() { S s = getValue(); ret (getKey()==null ? 0 : getKey().hashCode()) ^ (s == null ? 0 : s.hashCode()); } }); } ret set; } public S put(S a, S b) { S old = get(a); saveGZTextfile(fileForKey(a), quote(a) + "\n" + b); ret old; } public S remove(O a) { if (!isString(a)) null; ret put((S) a, null); } File fileForKey(O key) { if (!isString(key)) null; ret new File(assertNotNull(dir), uniqueFileNameUsingMD5_80((S) key)); } }