001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 package org.apache.hadoop.net; 019 020 import java.util.ArrayList; 021 import java.util.List; 022 import java.util.Map; 023 import java.util.concurrent.ConcurrentHashMap; 024 025 import org.apache.hadoop.classification.InterfaceAudience; 026 import org.apache.hadoop.classification.InterfaceStability; 027 028 /** 029 * A cached implementation of DNSToSwitchMapping that takes an 030 * raw DNSToSwitchMapping and stores the resolved network location in 031 * a cache. The following calls to a resolved network location 032 * will get its location from the cache. 033 * 034 */ 035 @InterfaceAudience.Public 036 @InterfaceStability.Evolving 037 public class CachedDNSToSwitchMapping implements DNSToSwitchMapping { 038 private Map<String, String> cache = new ConcurrentHashMap<String, String>(); 039 protected DNSToSwitchMapping rawMapping; 040 041 /** 042 * cache a raw DNS mapping 043 * @param rawMapping the raw mapping to cache 044 */ 045 public CachedDNSToSwitchMapping(DNSToSwitchMapping rawMapping) { 046 this.rawMapping = rawMapping; 047 } 048 049 /** 050 * @param names a list of hostnames to probe for being cached 051 * @return the hosts from 'names' that have not been cached previously 052 */ 053 private List<String> getUncachedHosts(List<String> names) { 054 // find out all names without cached resolved location 055 List<String> unCachedHosts = new ArrayList<String>(names.size()); 056 for (String name : names) { 057 if (cache.get(name) == null) { 058 unCachedHosts.add(name); 059 } 060 } 061 return unCachedHosts; 062 } 063 064 /** 065 * Caches the resolved host:rack mappings. The two list 066 * parameters must be of equal size. 067 * 068 * @param uncachedHosts a list of hosts that were uncached 069 * @param resolvedHosts a list of resolved host entries where the element 070 * at index(i) is the resolved value for the entry in uncachedHosts[i] 071 */ 072 private void cacheResolvedHosts(List<String> uncachedHosts, 073 List<String> resolvedHosts) { 074 // Cache the result 075 if (resolvedHosts != null) { 076 for (int i=0; i<uncachedHosts.size(); i++) { 077 cache.put(uncachedHosts.get(i), resolvedHosts.get(i)); 078 } 079 } 080 } 081 082 /** 083 * @param names a list of hostnames to look up (can be be empty) 084 * @return the cached resolution of the list of hostnames/addresses. 085 * or null if any of the names are not currently in the cache 086 */ 087 private List<String> getCachedHosts(List<String> names) { 088 List<String> result = new ArrayList<String>(names.size()); 089 // Construct the result 090 for (String name : names) { 091 String networkLocation = cache.get(name); 092 if (networkLocation != null) { 093 result.add(networkLocation); 094 } else { 095 return null; 096 } 097 } 098 return result; 099 } 100 101 @Override 102 public List<String> resolve(List<String> names) { 103 // normalize all input names to be in the form of IP addresses 104 names = NetUtils.normalizeHostNames(names); 105 106 List <String> result = new ArrayList<String>(names.size()); 107 if (names.isEmpty()) { 108 return result; 109 } 110 111 List<String> uncachedHosts = getUncachedHosts(names); 112 113 // Resolve the uncached hosts 114 List<String> resolvedHosts = rawMapping.resolve(uncachedHosts); 115 //cache them 116 cacheResolvedHosts(uncachedHosts, resolvedHosts); 117 //now look up the entire list in the cache 118 return getCachedHosts(names); 119 120 } 121 }