Only do one map lookup instead of two in QuicheLinkedHashMap::insert().

Instead of find() then insert(), use try_emplace().
This change is inspired by cl/163240273.

Also factor out two insert() calls into InsertInternal().

PiperOrigin-RevId: 372947805
diff --git a/common/quiche_linked_hash_map.h b/common/quiche_linked_hash_map.h
index 311e369..a52863e 100644
--- a/common/quiche_linked_hash_map.h
+++ b/common/quiche_linked_hash_map.h
@@ -127,7 +127,8 @@
   iterator erase(iterator position) {
     typename MapType::iterator found = map_.find(position->first);
     QUICHE_CHECK(found->second == position)
-        << "Inconsisent iterator for map and list, or the iterator is invalid.";
+        << "Inconsistent iterator for map and list, or the iterator is "
+           "invalid.";
 
     map_.erase(found);
     return list_.erase(position);
@@ -172,49 +173,12 @@
 
   // Inserts an element into the map
   std::pair<iterator, bool> insert(const std::pair<Key, Value>& pair) {
-    // First make sure the map doesn't have a key with this value.  If it does,
-    // return a pair with an iterator to it, and false indicating that we
-    // didn't insert anything.
-    typename MapType::iterator found = map_.find(pair.first);
-    if (found != map_.end()) {
-      return std::make_pair(found->second, false);
-    }
-
-    // Otherwise, insert into the list first.
-    list_.push_back(pair);
-
-    // Obtain an iterator to the newly added element.  We do -- instead of -
-    // since list::iterator doesn't implement operator-().
-    typename ListType::iterator last = list_.end();
-    --last;
-
-    QUICHE_CHECK(map_.insert(std::make_pair(pair.first, last)).second)
-        << "Map and list are inconsistent";
-
-    return std::make_pair(last, true);
+    return InsertInternal(pair);
   }
 
   // Inserts an element into the map
   std::pair<iterator, bool> insert(std::pair<Key, Value>&& pair) {
-    // First make sure the map doesn't have a key with this value.  If it does,
-    // return a pair with an iterator to it, and false indicating that we
-    // didn't insert anything.
-    typename MapType::iterator found = map_.find(pair.first);
-    if (found != map_.end()) {
-      return std::make_pair(found->second, false);
-    }
-
-    // Otherwise, insert into the list first.
-    list_.push_back(std::move(pair));
-
-    // Obtain an iterator to the newly added element.  We do -- instead of -
-    // since list::iterator doesn't implement operator-().
-    typename ListType::iterator last = list_.end();
-    --last;
-
-    QUICHE_CHECK(map_.insert(std::make_pair(last->first, last)).second)
-        << "Map and list are inconsistent";
-    return std::make_pair(last, true);
+    return InsertInternal(std::move(pair));
   }
 
   // Derive size_ from map_, as list::size might be O(N).
@@ -240,6 +204,24 @@
   }
 
  private:
+  template <typename U>
+  std::pair<iterator, bool> InsertInternal(U&& pair) {
+    auto insert_result = map_.try_emplace(pair.first);
+    auto map_iter = insert_result.first;
+
+    // If the map already contains this key, return a pair with an iterator to
+    // it, and false indicating that we didn't insert anything.
+    if (!insert_result.second) {
+      return {map_iter->second, false};
+    }
+
+    // Otherwise, insert into the list, and set value in map.
+    auto list_iter = list_.insert(list_.end(), std::forward<U>(pair));
+    map_iter->second = list_iter;
+
+    return {list_iter, true};
+  }
+
   // The map component, used for speedy lookups
   MapType map_;