MountTableResolver implements FileSubclusterResolver, StateStoreCache { @VisibleForTesting public void refreshEntries(final Collection<MountTable> entries) { writeLock.lock(); try { Map<String, MountTable> newEntries = new ConcurrentHashMap<>(); for (MountTable entry : entries) { String srcPath = entry.getSourcePath(); newEntries.put(srcPath, entry); } Set<String> oldEntries = new TreeSet<>(Collections.reverseOrder()); for (MountTable entry : getTreeValues("/")) { String srcPath = entry.getSourcePath(); oldEntries.add(srcPath); } for (String srcPath : oldEntries) { if (!newEntries.containsKey(srcPath)) { this.tree.remove(srcPath); invalidateLocationCache(srcPath); LOG.info("Removed stale mount point {} from resolver", srcPath); } } for (MountTable entry : entries) { String srcPath = entry.getSourcePath(); if (!oldEntries.contains(srcPath)) { this.tree.put(srcPath, entry); invalidateLocationCache(srcPath); LOG.info("Added new mount point {} to resolver", srcPath); } else { MountTable existingEntry = this.tree.get(srcPath); if (existingEntry != null && !existingEntry.equals(entry)) { LOG.info("Entry has changed from \"{}\" to \"{}\"", existingEntry, entry); this.tree.put(srcPath, entry); invalidateLocationCache(srcPath); LOG.info("Updated mount point {} in resolver", srcPath); } } } } finally { writeLock.unlock(); } this.init = true; } @VisibleForTesting  MountTableResolver(Configuration conf);  MountTableResolver(Configuration conf, Router routerService);  MountTableResolver(Configuration conf, StateStoreService store);  MountTableResolver(Configuration conf, Router routerService,
      StateStoreService store); void addEntry(final MountTable entry); void removeEntry(final String srcPath); @VisibleForTesting void refreshEntries(final Collection<MountTable> entries); @Override boolean loadCache(boolean force); void clear(); @Override PathLocation getDestinationForPath(final String path); PathLocation lookupLocation(final String str); MountTable getMountPoint(final String path); @Override List<String> getMountPoints(final String str); List<MountTable> getMounts(final String path); @Override String toString(); @Override String getDefaultNamespace(); @VisibleForTesting String getDefaultNameService(); @VisibleForTesting void setDefaultNameService(String defaultNameService); @VisibleForTesting boolean isDefaultNSEnable(); @VisibleForTesting void setDefaultNSEnable(boolean defaultNSRWEnable); @VisibleForTesting void setDisabled(boolean disable);  }
@Test public void testRefreshEntries() throws UnsupportedOperationException, IOException { testDestination(); assertEquals(10, mountTable.getMounts("/").size()); List<MountTable> records = new ArrayList<>(); Map<String, String> map1 = getMountTableEntry("1", "/"); records.add(MountTable.newInstance("/1", map1)); Map<String, String> map2 = getMountTableEntry("2", "/"); records.add(MountTable.newInstance("/2", map2)); mountTable.refreshEntries(records); PathLocation destination1 = mountTable.getDestinationForPath("/1"); RemoteLocation defaultLoc1 = destination1.getDefaultLocation(); assertEquals("1", defaultLoc1.getNameserviceId()); PathLocation destination2 = mountTable.getDestinationForPath("/2"); RemoteLocation defaultLoc2 = destination2.getDefaultLocation(); assertEquals("2", defaultLoc2.getNameserviceId()); assertEquals(2, mountTable.getMounts("/").size()); boolean assertionThrown = false; try { testDestination(); fail(); } catch (AssertionError e) { assertionThrown = true; } assertTrue(assertionThrown); }