package edu.stanford.nlp.sempre.cache; import java.io.*; import java.net.*; import fig.basic.LogInfo; /** * Cache backed by a remote service (see StringCacheServer). * * @author Percy Liang */ public class RemoteStringCache implements StringCache { public static final int NUM_TRIES = 5; private Socket socket; private PrintWriter out; private BufferedReader in; // Cache things locally. private FileStringCache local = new FileStringCache(); public RemoteStringCache(String path, String host, int port) { try { LogInfo.begin_track("RemoteStringCache: connecting to %s:%s to access %s", host, port, path); this.socket = new Socket(host, port); this.out = new PrintWriter(socket.getOutputStream(), true); this.in = new BufferedReader(new InputStreamReader(socket.getInputStream())); String response = makeRequest("open", path, null); LogInfo.logs("Using cache path=%s, host=%s, port=%s", path, host, port); if (!response.equals("OK")) { throw new RuntimeException(response); } LogInfo.end_track(); } catch (UnknownHostException e) { LogInfo.end_track(); throw new RuntimeException(e); } catch (IOException e) { LogInfo.end_track(); throw new RuntimeException(e); } } public String makeRequest(String method, String key, String value) { try { if (value == null) out.println(method + "\t" + key); else out.println(method + "\t" + key + "\t" + value); out.flush(); for (int i = 0; i < NUM_TRIES; i++) { try { String result = in.readLine(); if (result.equals(StringCacheServer.nullString)) result = null; return result; } catch (NullPointerException e) { LogInfo.logs("RemoteStringCache.makeRequest(%s, %s, %s) failed", method, key, value); } } throw new NullPointerException(); } catch (SocketTimeoutException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } } public String get(String key) { // First check the local cache. String value = local.get(key); if (value == null) value = makeRequest("get", key, null); return value; } public void put(String key, String value) { local.put(key, value); makeRequest("put", key, value); } public int size() { return local.size(); } }