[serialize] Fix hb_hashmap_t<> for pointers and use in packed_map
authorBehdad Esfahbod <behdad@behdad.org>
Wed, 3 Apr 2019 02:27:02 +0000 (19:27 -0700)
committerBehdad Esfahbod <behdad@behdad.org>
Wed, 3 Apr 2019 02:30:22 +0000 (19:30 -0700)
src/hb-array.hh
src/hb-map.hh
src/hb-serialize.hh
src/hb-vector.hh

index 4e8933f..9382db3 100644 (file)
@@ -79,6 +79,7 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
   operator hb_array_t<const Type> () { return hb_array_t<const Type> (arrayZ, length); }
   template <typename T> operator T * () const { return arrayZ; }
 
+  bool operator == (const hb_array_t &o) const;
   uint32_t hash () const;
 
   /*
@@ -276,6 +277,15 @@ hb_sorted_array (T (&array_)[length_])
 { return hb_sorted_array_t<T> (array_); }
 
 template <typename T>
+bool hb_array_t<T>::operator == (const hb_array_t<T> &o) const
+{
+  return length == o.length &&
+  + hb_zip (*this, o)
+  | hb_map ([] (hb_pair_t<T&, T&> &&_) -> bool { return _.first == _.second; })
+  | hb_all
+  ;
+}
+template <typename T>
 uint32_t hb_array_t<T>::hash () const
 {
   return
@@ -288,7 +298,7 @@ uint32_t hb_array_t<T>::hash () const
 typedef hb_array_t<const char> hb_bytes_t;
 typedef hb_array_t<const unsigned char> hb_ubytes_t;
 
-/* TODO Specialize hashing for hb_bytes_t and hb_ubytes_t. */
+/* TODO Specialize opeator==/hash() for hb_bytes_t and hb_ubytes_t. */
 //template <>
 //uint32_t hb_array_t<const char>::hash () const { return 0; }
 
index f5c9991..d760839 100644 (file)
@@ -57,8 +57,10 @@ struct hb_hashmap_t
     K key;
     V value;
 
-    bool operator== (K o) { return hb_deref_pointer (key) == hb_deref_pointer (o); }
-    bool operator== (const item_t &o) { return *this == o.key; }
+    void clear () { key = kINVALID; value = vINVALID; }
+
+    bool operator == (K o) { return hb_deref_pointer (key) == hb_deref_pointer (o); }
+    bool operator == (const item_t &o) { return *this == o.key; }
     bool is_unused () const    { return key == kINVALID; }
     bool is_tombstone () const { return key != kINVALID && value == vINVALID; }
   };
@@ -98,9 +100,7 @@ struct hb_hashmap_t
 
   void reset ()
   {
-    /* TODO Keep array? */
-    fini_shallow ();
-    init_shallow ();
+    clear ();
   }
 
   bool in_error () const { return !successful; }
@@ -117,7 +117,9 @@ struct hb_hashmap_t
       successful = false;
       return false;
     }
-    memset (new_items, 0xFF, (size_t) new_size * sizeof (item_t));
+    + hb_iter (new_items, new_size)
+    | hb_apply ([] (item_t &_) { _.clear (); }) /* TODO make pointer-to-methods invokable. */
+    ;
 
     unsigned int old_size = mask + 1;
     item_t *old_items = items;
@@ -168,7 +170,7 @@ struct hb_hashmap_t
   {
     if (unlikely (!items)) return vINVALID;
     unsigned int i = bucket_for (key);
-    return items[i] == key ? items[i].value : vINVALID;
+    return !items[i].is_unused () && items[i] == key ? items[i].value : vINVALID;
   }
 
   void del (K key) { set (key, vINVALID); }
@@ -183,7 +185,11 @@ struct hb_hashmap_t
 
   void clear ()
   {
-    if (items) memset (items, 0xFF, ((size_t) mask + 1) * sizeof (item_t));
+    if (items)
+      + hb_iter (items, mask + 1)
+      | hb_apply ([] (item_t &_) { _.clear (); }) /* TODO make pointer-to-methods invokable. */
+      ;
+
     population = occupancy = 0;
   }
 
index 18be276..d800c70 100644 (file)
@@ -54,9 +54,9 @@ struct hb_serialize_context_t
     bool operator == (const object_t &o) const
     {
       return (tail - head == o.tail - o.head)
-         && (links.length != o.links.length)
-         && 0 == memcmp (head, o.head, tail - head)
-         && 0 == memcmp (&links, &o.links, links.get_size ());
+         && (links.length == o.links.length)
+         && 0 == hb_memcmp (head, o.head, tail - head)
+         && links.as_bytes () == o.links.as_bytes ();
     }
     uint32_t hash () const
     {
@@ -197,7 +197,6 @@ struct hb_serialize_context_t
 
     objidx = packed.length - 1;
 
-    if (0) // XXX
     packed_map.set (key, objidx);
 
     return objidx;
@@ -217,7 +216,6 @@ struct hb_serialize_context_t
     while (packed.length > 1 &&
           packed.tail ().head < tail)
     {
-      if (0) // XXX
       packed_map.del (&packed.tail ());
       packed.pop ();
     }
index b5ac738..959df80 100644 (file)
@@ -103,6 +103,7 @@ struct hb_vector_t
   hb_bytes_t as_bytes () const { return hb_bytes_t ((const char *) arrayZ_,
                                                    length * item_size); }
 
+  bool operator == (const hb_vector_t &o) const { return as_bytes () == o.as_bytes (); }
   uint32_t hash () const { return as_bytes ().hash (); }
 
   const Type * arrayZ () const { return arrayZ_; }