Browse Source

feat(hash_map): move pair class out of hash_map

greatbridf 2 years ago
parent
commit
44a9b33979
6 changed files with 122 additions and 35 deletions
  1. 1 0
      CMakeLists.txt
  2. 2 2
      include/kernel/process.hpp
  3. 14 1
      include/types/cplusplus.hpp
  4. 9 28
      include/types/hash_map.hpp
  5. 92 0
      include/types/pair.hpp
  6. 4 4
      src/kernel/vfs.cpp

+ 1 - 0
CMakeLists.txt

@@ -95,6 +95,7 @@ set(KERNEL_MAIN_SOURCES src/fs/fat.cpp
                         include/types/buffer.h
                         include/types/elf.hpp
                         include/types/hash_map.hpp
+                        include/types/pair.hpp
                         include/types/types.h
                         include/types/size.h
                         include/types/status.h

+ 2 - 2
include/kernel/process.hpp

@@ -126,11 +126,11 @@ public:
     constexpr iterator_type emplace(Args&&... args)
     {
         auto iter = m_procs.emplace_back(types::forward<Args>(args)...);
-        m_idx.insert(iter->pid, iter);
+        m_idx.emplace(iter->pid, iter);
 
         auto children = m_child_idx.find(iter->ppid);
         if (!children) {
-            m_child_idx.insert(iter->ppid, {});
+            m_child_idx.emplace(iter->ppid, types::list<pid_t> {});
             children = m_child_idx.find(iter->ppid);
         }
 

+ 14 - 1
include/types/cplusplus.hpp

@@ -65,6 +65,19 @@ struct remove_cv<const volatile T> {
     using type = T;
 };
 
+template <typename T>
+struct add_const {
+    using type = const T;
+};
+template <typename T>
+struct add_const<const T> {
+    using type = const T;
+};
+template <>
+struct add_const<void> {
+    using type = void;
+};
+
 template <typename T>
 struct is_pointer : false_type {
 };
@@ -76,7 +89,7 @@ struct is_pointer<T*> : true_type {
 template <typename T>
 struct decay {
 private:
-    using U = remove_reference<T>;
+    using U = typename remove_reference<T>::type;
 
 public:
     using type = typename remove_cv<U>::type;

+ 9 - 28
include/types/hash_map.hpp

@@ -3,6 +3,7 @@
 #include <types/allocator.hpp>
 #include <types/cplusplus.hpp>
 #include <types/list.hpp>
+#include <types/pair.hpp>
 #include <types/stdint.h>
 #include <types/string.hpp>
 #include <types/types.h>
@@ -89,40 +90,23 @@ concept Hasher = requires(Value&& val, uint32_t bits)
 template <typename Key, typename Value, Hasher<Key> _Hasher, template <typename _T> class Allocator = types::kernel_allocator>
 class hash_map {
 public:
-    struct pair;
     template <typename Pointer>
     class iterator;
 
-    using key_type = Key;
+    using key_type = typename traits::add_const<Key>::type;
     using value_type = Value;
-    using pair_type = pair;
+    using pair_type = pair<key_type, value_type>;
     using size_type = size_t;
     using difference_type = ssize_t;
     using iterator_type = iterator<pair_type*>;
     using const_iterator_type = iterator<const pair_type*>;
 
-    using bucket_type = list<pair, Allocator>;
+    using bucket_type = list<pair_type, Allocator>;
     using bucket_array_type = vector<bucket_type, Allocator>;
 
     static constexpr size_type INITIAL_BUCKETS_ALLOCATED = 64;
 
 public:
-    struct pair {
-        const key_type key;
-        value_type value;
-
-        constexpr pair(void) = delete;
-        constexpr pair(const key_type _key, value_type _val)
-            : key(_key)
-            , value(_val)
-        {
-        }
-        constexpr bool operator==(const pair& p)
-        {
-            return key == p.key;
-        }
-    };
-
     template <typename Pointer>
     class iterator {
     public:
@@ -226,19 +210,16 @@ public:
         buckets.clear();
     }
 
-    constexpr void insert(const pair& p)
-    {
-        auto hash_value = _Hasher::hash(p.key, hash_length());
-        buckets.at(hash_value).push_back(p);
-    }
-    constexpr void insert(pair&& p)
+    constexpr void emplace(pair_type&& p)
     {
         auto hash_value = _Hasher::hash(p.key, hash_length());
         buckets.at(hash_value).push_back(move(p));
     }
-    constexpr void insert(const key_type& key, const value_type& val)
+
+    template <typename _key_type, typename _value_type>
+    constexpr void emplace(_key_type&& key, _value_type&& value)
     {
-        insert(pair { key, val });
+        emplace(make_pair(forward<_key_type>(key), forward<_value_type>(value)));
     }
 
     constexpr void remove(const key_type& key)

+ 92 - 0
include/types/pair.hpp

@@ -0,0 +1,92 @@
+#pragma once
+
+#include <types/cplusplus.hpp>
+
+namespace types {
+
+template <typename Key, typename Value>
+struct pair {
+    using key_type = Key;
+    using value_type = Value;
+
+    key_type key;
+    value_type value;
+
+    constexpr pair(void) = delete;
+    constexpr ~pair()
+    {
+    }
+
+    template <typename _key_type, typename _value_type>
+    constexpr pair(_key_type&& _key, _value_type&& _value)
+        : key(forward<_key_type>(_key))
+        , value(forward<_value_type>(_value))
+    {
+    }
+
+    template <typename _key_type, typename _value_type>
+    constexpr pair(const pair<_key_type, _value_type>& val)
+        : key(val.key)
+        , value(val.value)
+    {
+        static_assert(is_same<typename traits::decay<_key_type>::type, typename traits::decay<key_type>::type>::value);
+        static_assert(is_same<typename traits::decay<_value_type>::type, typename traits::decay<value_type>::type>::value);
+    }
+    template <typename _key_type, typename _value_type>
+    constexpr pair(pair<_key_type, _value_type>&& val)
+        : key(move(val.key))
+        , value(move(val.value))
+    {
+        static_assert(is_same<typename traits::decay<_key_type>::type, typename traits::decay<key_type>::type>::value);
+        static_assert(is_same<typename traits::decay<_value_type>::type, typename traits::decay<value_type>::type>::value);
+    }
+    constexpr pair(const pair& val)
+        : key(val.key)
+        , value(val.value)
+    {
+    }
+    constexpr pair(pair&& val)
+        : key(move(val.key))
+        , value(move(val.value))
+    {
+    }
+    constexpr pair& operator=(const pair& val)
+    {
+        key = val.key;
+        value = val.vaule;
+    }
+    constexpr pair& operator=(pair&& val)
+    {
+        key = move(val.key);
+        value = move(val.value);
+    }
+
+    constexpr bool key_eq(const pair& p)
+    {
+        return key == p.key;
+    }
+
+    constexpr bool value_eq(const pair& p)
+    {
+        return value == p.value;
+    }
+
+    constexpr bool operator==(const pair& p)
+    {
+        return key_eq(p) && value_eq(p);
+    }
+
+    constexpr bool operator!=(const pair& p)
+    {
+        return !this->operator==(p);
+    }
+};
+
+template <typename T1, typename T2>
+constexpr pair<typename traits::decay<T1>::type, typename traits::decay<T2>::type>
+make_pair(T1&& t1, T2&& t2)
+{
+    return pair<typename traits::decay<T1>::type, typename traits::decay<T2>::type> { forward<T1>(t1), forward<T2>(t2) };
+}
+
+} // namespace types

+ 4 - 4
src/kernel/vfs.cpp

@@ -65,13 +65,13 @@ fs::vfs::dentry::~dentry()
 fs::vfs::dentry* fs::vfs::dentry::append(inode* ind, const name_type& name)
 {
     auto iter = children->emplace_back(this, ind, name);
-    idx_children->insert(iter->name, &iter);
+    idx_children->emplace(iter->name, &iter);
     return &iter;
 }
 fs::vfs::dentry* fs::vfs::dentry::append(inode* ind, name_type&& name)
 {
     auto iter = children->emplace_back(this, ind, types::move(name));
-    idx_children->insert(iter->name, &iter);
+    idx_children->emplace(iter->name, &iter);
     return &iter;
 }
 fs::vfs::dentry* fs::vfs::dentry::find(const name_type& name)
@@ -113,7 +113,7 @@ fs::ino_t fs::vfs::_assign_inode_id(void)
 fs::inode* fs::vfs::cache_inode(inode_flags flags, uint32_t perm, size_t size, void* impl_data)
 {
     auto iter = _inodes.emplace_back(inode { flags, perm, impl_data, _assign_inode_id(), this, size });
-    _idx_inodes.insert(iter->ino, &iter);
+    _idx_inodes.emplace(iter->ino, &iter);
     return &iter;
 }
 fs::inode* fs::vfs::get_inode(ino_t ino)
@@ -148,7 +148,7 @@ int fs::vfs::mount(dentry* mnt, vfs* new_fs)
     new_ent->name = mnt->name;
 
     auto* orig_ent = mnt->replace(new_ent);
-    _mount_recover_list.insert(new_ent, orig_ent);
+    _mount_recover_list.emplace(new_ent, orig_ent);
 
     new_ent->ind->flags.in.mount_point = 1;