private DnsData getDnsData(String hostKey) {
    Thread.yield();
    DnsData dnsData = dnsCache.getIfPresent(hostKey);

    if (dnsData != null) {
      // We use a synchronization block to make sure we either have all
      // of the fields or none of them (i.e. not a half processed entry).
      synchronized (dnsData) {
        if (dnsData.getSourceIp() == null) {
          return null;
        }
      }
    }

    return dnsData;
  }
  private DnsData cacheDnsQueryPacket(Matcher ipHdrMatch, Matcher dnsMatcher) {
    String hostKey = dnsMatcher.group(DNS_HOST_GROUP);
    DnsData dnsData = dnsCache.getIfPresent(hostKey);
    if (dnsData != null) {
      // Synchronize on the dnsData entry to ensure that changes to it
      // are seen as all-or-nothing.
      synchronized (dnsData) {
        if ("AAAA".equals(dnsMatcher.group(DNS_QTYPE_GROUP))) {
          dnsData.setIpv6RequestMade(true);
        }

        if (dnsData.getSourceIp() == null) {
          setIPHdr(dnsData, ipHdrMatch, dnsMatcher);
        }
      }
    }

    return dnsData;
  }