### Question:
ThriftCacheServer extends FilteredBlurServer { @Override public FetchResult fetchRow(String table, Selector selector) throws BlurException, TException { Selector copy = new Selector(selector); ThriftCacheKey<Selector> key = _thriftCache.getKey(table, getShards(table), copy, Selector.class); Lock lock = getOrCreateLock(key); try { lock.lock(); FetchResult results = _thriftCache.get(key, FetchResult.class); if (results != null) { return results; } return _thriftCache.put(key, super.fetchRow(table, selector)); } finally { lock.unlock(); } } ThriftCacheServer(BlurConfiguration configuration, Iface iface, IndexServer indexServer,
      ThriftCache thriftCache); @Override void loadIndex(String table, List<String> externalIndexPaths); @Override TableStats tableStats(String table); @Override BlurResults query(String table, BlurQuery blurQuery); @Override FetchResult fetchRow(String table, Selector selector); @Override List<FetchResult> fetchRowBatch(String table, List<Selector> selectors);  }### Answer:
@Test public void testFetchRow() throws BlurException, TException { _thriftCache.clear(); assertEquals(0, _thriftCache.getMisses()); assertEquals(0, _thriftCache.getHits()); Selector selector1 = new Selector(); selector1.setLocationId("1"); FetchResult fetchRow1 = _thriftCacheServer.fetchRow(_table, selector1); assertEquals(1, _thriftCache.getMisses()); assertEquals(0, _thriftCache.getHits()); Selector selector2 = new Selector(); selector2.setLocationId("1"); FetchResult fetchRow2 = _thriftCacheServer.fetchRow(_table, selector2); assertEquals(1, _thriftCache.getMisses()); assertEquals(1, _thriftCache.getHits()); assertFalse(fetchRow1 == fetchRow2); assertEquals(fetchRow1, fetchRow2); }