Rework hashing, use a more extensible framework similar to n3876 proposal
std::hash specialization is a pain to work with, stop using that, and just specialize a 'size_t hash_value(const T&)' free function.
This commit is contained in:
parent
dbd7bd41bb
commit
ebecd60eb8
|
@ -3,8 +3,7 @@
|
|||
|
||||
#include "safe_ptr.hh"
|
||||
#include "string.hh"
|
||||
|
||||
#include <unordered_map>
|
||||
#include "unordered_map.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
@ -24,7 +23,7 @@ private:
|
|||
AliasRegistry() {}
|
||||
|
||||
safe_ptr<AliasRegistry> m_parent;
|
||||
std::unordered_map<String, String> m_aliases;
|
||||
UnorderedMap<String, String> m_aliases;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
23
src/color.hh
23
src/color.hh
|
@ -1,6 +1,8 @@
|
|||
#ifndef color_hh_INCLUDED
|
||||
#define color_hh_INCLUDED
|
||||
|
||||
#include "hash.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
|
@ -32,13 +34,19 @@ struct Color
|
|||
Color(Colors c) : color{c}, r{0}, g{0}, b{0} {}
|
||||
Color(unsigned char r, unsigned char g, unsigned char b)
|
||||
: color{Colors::RGB}, r{r}, g{g}, b{b} {}
|
||||
|
||||
bool operator==(Color c) const
|
||||
{ return color == c.color and r == c.r and g == c.g and b == c.b; }
|
||||
bool operator!=(Color c) const
|
||||
{ return color != c.color or r != c.r or g != c.g or b != c.b; }
|
||||
};
|
||||
|
||||
inline bool operator==(Color lhs, Color rhs)
|
||||
{
|
||||
return lhs.color == rhs.color and
|
||||
lhs.r == rhs.r and lhs.g == rhs.g and lhs.b == rhs.b;
|
||||
}
|
||||
|
||||
inline bool operator!=(Color lhs, Color rhs)
|
||||
{
|
||||
return not (lhs == rhs);
|
||||
}
|
||||
|
||||
Color str_to_color(StringView color);
|
||||
String color_to_str(Color color);
|
||||
|
||||
|
@ -47,6 +55,11 @@ void option_from_string(StringView str, Color& color);
|
|||
|
||||
bool is_color_name(StringView color);
|
||||
|
||||
inline size_t hash_value(const Color& val)
|
||||
{
|
||||
return hash_values(val.color, val.r, val.g, val.b);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // color_hh_INCLUDED
|
||||
|
|
|
@ -189,7 +189,7 @@ Token parse_percent_token(StringView line, ByteCount& pos)
|
|||
type_name + "'"};
|
||||
|
||||
Token::Type type = token_type<throw_on_unterminated>(type_name);
|
||||
static const std::unordered_map<char, char> matching_delimiters = {
|
||||
static const UnorderedMap<char, char> matching_delimiters = {
|
||||
{ '(', ')' }, { '[', ']' }, { '{', '}' }, { '<', '>' }
|
||||
};
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
#include "parameters_parser.hh"
|
||||
#include "string.hh"
|
||||
#include "utils.hh"
|
||||
#include "unordered_map.hh"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
|
||||
|
@ -88,7 +88,7 @@ private:
|
|||
CommandFlags flags;
|
||||
CommandCompleter completer;
|
||||
};
|
||||
using CommandMap = std::unordered_map<String, CommandDescriptor>;
|
||||
using CommandMap = UnorderedMap<String, CommandDescriptor>;
|
||||
CommandMap m_commands;
|
||||
|
||||
CommandMap::const_iterator find_command(const Context& context,
|
||||
|
|
16
src/coord.hh
16
src/coord.hh
|
@ -2,6 +2,7 @@
|
|||
#define coord_hh_INCLUDED
|
||||
|
||||
#include "units.hh"
|
||||
#include "hash.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
@ -92,6 +93,11 @@ struct ByteCoord : LineAndColumn<ByteCoord, LineCount, ByteCount>
|
|||
: LineAndColumn(line, column) {}
|
||||
};
|
||||
|
||||
inline size_t hash_value(const ByteCoord& val)
|
||||
{
|
||||
return hash_values(val.line, val.column);
|
||||
}
|
||||
|
||||
struct CharCoord : LineAndColumn<CharCoord, LineCount, CharCount>
|
||||
{
|
||||
[[gnu::always_inline]]
|
||||
|
@ -99,6 +105,11 @@ struct CharCoord : LineAndColumn<CharCoord, LineCount, CharCount>
|
|||
: LineAndColumn(line, column) {}
|
||||
};
|
||||
|
||||
inline size_t hash_value(const CharCoord& val)
|
||||
{
|
||||
return hash_values(val.line, val.column);
|
||||
}
|
||||
|
||||
struct ByteCoordAndTarget : ByteCoord
|
||||
{
|
||||
[[gnu::always_inline]]
|
||||
|
@ -112,6 +123,11 @@ struct ByteCoordAndTarget : ByteCoord
|
|||
CharCount target;
|
||||
};
|
||||
|
||||
inline size_t hash_value(const ByteCoordAndTarget& val)
|
||||
{
|
||||
return hash_values(val.line, val.column, val.target);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // coord_hh_INCLUDED
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
#ifndef env_vars_hh_INCLUDED
|
||||
#define env_vars_hh_INCLUDED
|
||||
|
||||
#include <unordered_map>
|
||||
#include "unordered_map.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
class String;
|
||||
using EnvVarMap = std::unordered_map<String, String>;
|
||||
using EnvVarMap = UnorderedMap<String, String>;
|
||||
|
||||
EnvVarMap get_env_vars();
|
||||
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
#include "face.hh"
|
||||
#include "utils.hh"
|
||||
#include "completion.hh"
|
||||
|
||||
#include <unordered_map>
|
||||
#include "unordered_map.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
@ -30,7 +29,7 @@ private:
|
|||
FaceOrAlias(Face face = Face{}) : face(face) {}
|
||||
};
|
||||
|
||||
std::unordered_map<String, FaceOrAlias> m_aliases;
|
||||
UnorderedMap<String, FaceOrAlias> m_aliases;
|
||||
};
|
||||
|
||||
inline Face get_face(const String& facedesc)
|
||||
|
|
|
@ -356,7 +356,7 @@ std::vector<String> complete_command(StringView prefix, ByteCount cursor_pos)
|
|||
TimeSpec mtime = {};
|
||||
std::vector<String> commands;
|
||||
};
|
||||
static std::unordered_map<String, CommandCache> command_cache;
|
||||
static UnorderedMap<String, CommandCache> command_cache;
|
||||
|
||||
std::vector<StringView> path;
|
||||
if (dir_end != -1)
|
||||
|
|
68
src/hash.cc
Normal file
68
src/hash.cc
Normal file
|
@ -0,0 +1,68 @@
|
|||
#include "hash.hh"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
[[gnu::always_inline]]
|
||||
static inline uint32_t rotl(uint32_t x, int8_t r)
|
||||
{
|
||||
return (x << r) | (x >> (32 - r));
|
||||
}
|
||||
|
||||
[[gnu::always_inline]]
|
||||
static inline uint32_t fmix(uint32_t h)
|
||||
{
|
||||
h ^= h >> 16;
|
||||
h *= 0x85ebca6b;
|
||||
h ^= h >> 13;
|
||||
h *= 0xc2b2ae35;
|
||||
h ^= h >> 16;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
// murmur3 hash, based on https://github.com/PeterScott/murmur3
|
||||
size_t hash_data(const char* input, size_t len)
|
||||
{
|
||||
const uint8_t* data = reinterpret_cast<const uint8_t*>(input);
|
||||
uint32_t hash = 0x1235678;
|
||||
constexpr uint32_t c1 = 0xcc9e2d51;
|
||||
constexpr uint32_t c2 = 0x1b873593;
|
||||
|
||||
const int nblocks = len / 4;
|
||||
const uint32_t* blocks = reinterpret_cast<const uint32_t*>(data + nblocks*4);
|
||||
|
||||
for (int i = -nblocks; i; ++i)
|
||||
{
|
||||
uint32_t key = blocks[i];
|
||||
key *= c1;
|
||||
key = rotl(key, 15);
|
||||
key *= c2;
|
||||
|
||||
hash ^= key;
|
||||
hash = rotl(hash, 13);
|
||||
hash = hash * 5 + 0xe6546b64;
|
||||
}
|
||||
|
||||
const uint8_t* tail = data + nblocks * 4;
|
||||
uint32_t key = 0;
|
||||
switch (len & 3)
|
||||
{
|
||||
case 3: key ^= tail[2] << 16;
|
||||
case 2: key ^= tail[1] << 8;
|
||||
case 1: key ^= tail[0];
|
||||
key *= c1;
|
||||
key = rotl(key,15);
|
||||
key *= c2;
|
||||
hash ^= key;
|
||||
}
|
||||
|
||||
hash ^= len;
|
||||
hash = fmix(hash);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
}
|
57
src/hash.hh
Normal file
57
src/hash.hh
Normal file
|
@ -0,0 +1,57 @@
|
|||
#ifndef hash_hh_INCLUDED
|
||||
#define hash_hh_INCLUDED
|
||||
|
||||
#include <type_traits>
|
||||
#include <functional>
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
size_t hash_data(const char* data, size_t len);
|
||||
|
||||
template<typename Type>
|
||||
typename std::enable_if<not std::is_enum<Type>::value, size_t>::type
|
||||
hash_value(const Type& val)
|
||||
{
|
||||
return std::hash<Type>()(val);
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
typename std::enable_if<std::is_enum<Type>::value, size_t>::type
|
||||
hash_value(const Type& val)
|
||||
{
|
||||
return hash_value((typename std::underlying_type<Type>::type)val);
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
size_t hash_values(Type&& t)
|
||||
{
|
||||
return hash_value(std::forward<Type>(t));
|
||||
}
|
||||
|
||||
template<typename Type, typename... RemainingTypes>
|
||||
size_t hash_values(Type&& t, RemainingTypes&&... rt)
|
||||
{
|
||||
size_t seed = hash_values(std::forward<RemainingTypes>(rt)...);
|
||||
return seed ^ (hash_value(std::forward<Type>(t)) + 0x9e3779b9 +
|
||||
(seed << 6) + (seed >> 2));
|
||||
}
|
||||
|
||||
template<typename T1, typename T2>
|
||||
size_t hash_value(const std::pair<T1, T2>& val)
|
||||
{
|
||||
return hash_values(val.first, val.second);
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
struct Hash
|
||||
{
|
||||
size_t operator()(const Type& val) const
|
||||
{
|
||||
return hash_value(val);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // hash_hh_INCLUDED
|
|
@ -9,22 +9,6 @@
|
|||
|
||||
#include <functional>
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
||||
template<>
|
||||
struct hash<Kakoune::ByteCoord>
|
||||
{
|
||||
size_t operator()(const Kakoune::ByteCoord& val) const
|
||||
{
|
||||
size_t seed = std::hash<int>()((int)val.line);
|
||||
return seed ^ (std::hash<int>()((int)val.column) + 0x9e3779b9 +
|
||||
(seed << 6) + (seed >> 2));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
|
|
|
@ -1017,7 +1017,7 @@ private:
|
|||
{
|
||||
size_t timestamp = 0;
|
||||
std::vector<RegionMatches> matches;
|
||||
std::unordered_map<BufferRange, RegionList> regions;
|
||||
UnorderedMap<BufferRange, RegionList> regions;
|
||||
};
|
||||
BufferSideCache<Cache> m_cache;
|
||||
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
#define hook_manager_hh_INCLUDED
|
||||
|
||||
#include "id_map.hh"
|
||||
|
||||
#include <unordered_map>
|
||||
#include "unordered_map.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
@ -29,7 +28,7 @@ private:
|
|||
friend class Scope;
|
||||
|
||||
HookManager* m_parent;
|
||||
std::unordered_map<String, id_map<HookFunc>> m_hook;
|
||||
UnorderedMap<String, id_map<HookFunc>> m_hook;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -9,12 +9,11 @@
|
|||
#include "normal.hh"
|
||||
#include "regex.hh"
|
||||
#include "register_manager.hh"
|
||||
#include "unordered_map.hh"
|
||||
#include "user_interface.hh"
|
||||
#include "utf8.hh"
|
||||
#include "window.hh"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
|
@ -736,10 +735,10 @@ private:
|
|||
bool m_autoshowcompl;
|
||||
Mode m_mode = Mode::Default;
|
||||
|
||||
static std::unordered_map<String, std::vector<String>> ms_history;
|
||||
static UnorderedMap<String, std::vector<String>> ms_history;
|
||||
std::vector<String>::iterator m_history_it;
|
||||
};
|
||||
std::unordered_map<String, std::vector<String>> Prompt::ms_history;
|
||||
UnorderedMap<String, std::vector<String>> Prompt::ms_history;
|
||||
|
||||
class NextKey : public InputMode
|
||||
{
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
|
||||
#include "string.hh"
|
||||
#include "utils.hh"
|
||||
|
||||
#include <unordered_map>
|
||||
#include "unordered_map.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
@ -20,7 +19,7 @@ private:
|
|||
void acquire(size_t slot);
|
||||
void release(size_t slot) noexcept;
|
||||
|
||||
std::unordered_map<StringView, size_t> m_slot_map;
|
||||
UnorderedMap<StringView, size_t> m_slot_map;
|
||||
std::vector<size_t> m_free_slots;
|
||||
using DataAndRefCount = std::pair<std::vector<char>, int>;
|
||||
std::vector<DataAndRefCount> m_storage;
|
||||
|
@ -118,18 +117,11 @@ private:
|
|||
size_t m_slot = -1;
|
||||
};
|
||||
|
||||
inline size_t hash_value(const Kakoune::InternedString& str)
|
||||
{
|
||||
return hash_data(str.data(), (int)str.length());
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<>
|
||||
struct hash<Kakoune::InternedString>
|
||||
{
|
||||
size_t operator()(const Kakoune::InternedString& str) const
|
||||
{
|
||||
return Kakoune::hash_data(str.data(), (int)str.length());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // interned_string_hh_INCLUDED
|
||||
|
|
|
@ -1,19 +1,7 @@
|
|||
#include "keymap_manager.hh"
|
||||
|
||||
#include "memoryview.hh"
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
||||
template<> struct hash<Kakoune::KeymapMode>
|
||||
{
|
||||
size_t operator()(Kakoune::KeymapMode val) const
|
||||
{
|
||||
return hash<int>{}((int)val);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
#include "assert.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
#define keymap_manager_hh_INCLUDED
|
||||
|
||||
#include "keys.hh"
|
||||
#include "utils.hh"
|
||||
#include "hash.hh"
|
||||
#include "unordered_map.hh"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace Kakoune
|
||||
|
@ -43,7 +43,8 @@ private:
|
|||
KeymapManager* m_parent;
|
||||
|
||||
using KeyList = std::vector<Key>;
|
||||
using Keymap = std::unordered_map<std::pair<Key, KeymapMode>, KeyList>;
|
||||
using KeyAndMode = std::pair<Key, KeymapMode>;
|
||||
using Keymap = UnorderedMap<KeyAndMode, KeyList>;
|
||||
Keymap m_mapping;
|
||||
};
|
||||
|
||||
|
|
18
src/keys.hh
18
src/keys.hh
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "unicode.hh"
|
||||
#include "flags.hh"
|
||||
#include "hash.hh"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
@ -11,7 +12,7 @@ namespace Kakoune
|
|||
|
||||
struct Key
|
||||
{
|
||||
enum class Modifiers
|
||||
enum class Modifiers : int
|
||||
{
|
||||
None = 0,
|
||||
Control = 1 << 0,
|
||||
|
@ -78,21 +79,8 @@ constexpr Key alt(Codepoint key) { return { Key::Modifiers::Alt, key }; }
|
|||
constexpr Key ctrl(Codepoint key) { return { Key::Modifiers::Control, key }; }
|
||||
constexpr Key ctrlalt(Codepoint key) { return { Key::Modifiers::ControlAlt, key }; }
|
||||
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
||||
template<>
|
||||
struct hash<Kakoune::Key>
|
||||
{
|
||||
size_t operator()(Kakoune::Key key) const
|
||||
{
|
||||
return static_cast<size_t>(key.modifiers) * 1024 + key.key;
|
||||
}
|
||||
};
|
||||
inline size_t hash_value(const Key& key) { return hash_values(key.modifiers, key.key); }
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // keys_hh_INCLUDED
|
||||
|
|
|
@ -166,7 +166,7 @@ static int nc_color(Color color)
|
|||
static int get_color_pair(const Face& face)
|
||||
{
|
||||
using ColorPair = std::pair<Color, Color>;
|
||||
static std::map<ColorPair, int> colorpairs;
|
||||
static UnorderedMap<ColorPair, int> colorpairs;
|
||||
static int next_pair = 1;
|
||||
|
||||
ColorPair colors{face.fg, face.bg};
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
#define normal_hh_INCLUDED
|
||||
|
||||
#include "keys.hh"
|
||||
#include "unordered_map.hh"
|
||||
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
@ -23,7 +23,7 @@ struct NormalCmdDesc
|
|||
std::function<void (Context& context, NormalParams params)> func;
|
||||
};
|
||||
|
||||
using KeyMap = std::unordered_map<Key, NormalCmdDesc>;
|
||||
using KeyMap = UnorderedMap<Key, NormalCmdDesc>;
|
||||
extern KeyMap keymap;
|
||||
|
||||
}
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
#include "units.hh"
|
||||
#include "coord.hh"
|
||||
#include "memoryview.hh"
|
||||
#include "unordered_map.hh"
|
||||
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
@ -68,7 +68,7 @@ bool option_add(std::vector<T>& opt, const std::vector<T>& vec)
|
|||
}
|
||||
|
||||
template<typename Key, typename Value>
|
||||
String option_to_string(const std::unordered_map<Key, Value>& opt)
|
||||
String option_to_string(const UnorderedMap<Key, Value>& opt)
|
||||
{
|
||||
String res;
|
||||
for (auto it = begin(opt); it != end(opt); ++it)
|
||||
|
@ -83,7 +83,7 @@ String option_to_string(const std::unordered_map<Key, Value>& opt)
|
|||
}
|
||||
|
||||
template<typename Key, typename Value>
|
||||
void option_from_string(StringView str, std::unordered_map<Key, Value>& opt)
|
||||
void option_from_string(StringView str, UnorderedMap<Key, Value>& opt)
|
||||
{
|
||||
opt.clear();
|
||||
std::vector<String> elems = split(str, list_separator, '\\');
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
#include "register.hh"
|
||||
#include "utils.hh"
|
||||
#include "unordered_map.hh"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
|
@ -21,7 +21,7 @@ public:
|
|||
void register_dynamic_register(char reg, RegisterRetriever function);
|
||||
|
||||
protected:
|
||||
std::unordered_map<char, std::unique_ptr<Register>> m_registers;
|
||||
UnorderedMap<char, std::unique_ptr<Register>> m_registers;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ public:
|
|||
}
|
||||
|
||||
template<typename Key, typename Val>
|
||||
void write(const std::unordered_map<Key, Val>& map)
|
||||
void write(const UnorderedMap<Key, Val>& map)
|
||||
{
|
||||
write<uint32_t>(map.size());
|
||||
for (auto& val : map)
|
||||
|
@ -230,10 +230,10 @@ DisplayBuffer read<DisplayBuffer>(int socket)
|
|||
}
|
||||
|
||||
template<typename Key, typename Val>
|
||||
std::unordered_map<Key, Val> read_map(int socket)
|
||||
UnorderedMap<Key, Val> read_map(int socket)
|
||||
{
|
||||
uint32_t size = read<uint32_t>(socket);
|
||||
std::unordered_map<Key, Val> res;
|
||||
UnorderedMap<Key, Val> res;
|
||||
while (size--)
|
||||
{
|
||||
auto key = read<Key>(socket);
|
||||
|
|
|
@ -173,64 +173,4 @@ std::vector<StringView> wrap_lines(StringView text, CharCount max_width)
|
|||
return lines;
|
||||
}
|
||||
|
||||
[[gnu::always_inline]]
|
||||
static inline uint32_t rotl(uint32_t x, int8_t r)
|
||||
{
|
||||
return (x << r) | (x >> (32 - r));
|
||||
}
|
||||
|
||||
[[gnu::always_inline]]
|
||||
static inline uint32_t fmix(uint32_t h)
|
||||
{
|
||||
h ^= h >> 16;
|
||||
h *= 0x85ebca6b;
|
||||
h ^= h >> 13;
|
||||
h *= 0xc2b2ae35;
|
||||
h ^= h >> 16;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
// murmur3 hash, based on https://github.com/PeterScott/murmur3
|
||||
size_t hash_data(const char* input, size_t len)
|
||||
{
|
||||
const uint8_t* data = reinterpret_cast<const uint8_t*>(input);
|
||||
uint32_t hash = 0x1235678;
|
||||
constexpr uint32_t c1 = 0xcc9e2d51;
|
||||
constexpr uint32_t c2 = 0x1b873593;
|
||||
|
||||
const int nblocks = len / 4;
|
||||
const uint32_t* blocks = reinterpret_cast<const uint32_t*>(data + nblocks*4);
|
||||
|
||||
for (int i = -nblocks; i; ++i)
|
||||
{
|
||||
uint32_t key = blocks[i];
|
||||
key *= c1;
|
||||
key = rotl(key, 15);
|
||||
key *= c2;
|
||||
|
||||
hash ^= key;
|
||||
hash = rotl(hash, 13);
|
||||
hash = hash * 5 + 0xe6546b64;
|
||||
}
|
||||
|
||||
const uint8_t* tail = data + nblocks * 4;
|
||||
uint32_t key = 0;
|
||||
switch (len & 3)
|
||||
{
|
||||
case 3: key ^= tail[2] << 16;
|
||||
case 2: key ^= tail[1] << 8;
|
||||
case 1: key ^= tail[0];
|
||||
key *= c1;
|
||||
key = rotl(key,15);
|
||||
key *= c2;
|
||||
hash ^= key;
|
||||
}
|
||||
|
||||
hash ^= len;
|
||||
hash = fmix(hash);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "units.hh"
|
||||
#include "utf8.hh"
|
||||
#include "hash.hh"
|
||||
|
||||
#include <string>
|
||||
#include <climits>
|
||||
|
@ -267,29 +268,16 @@ String expand_tabs(StringView line, CharCount tabstop, CharCount col = 0);
|
|||
|
||||
std::vector<StringView> wrap_lines(StringView text, CharCount max_width);
|
||||
|
||||
size_t hash_data(const char* data, size_t len);
|
||||
|
||||
inline size_t hash_value(const Kakoune::String& str)
|
||||
{
|
||||
return hash_data(str.data(), (int)str.length());
|
||||
}
|
||||
|
||||
namespace std
|
||||
inline size_t hash_value(const Kakoune::StringView& str)
|
||||
{
|
||||
template<>
|
||||
struct hash<Kakoune::String> : hash<std::string>
|
||||
{
|
||||
size_t operator()(const Kakoune::String& str) const
|
||||
{
|
||||
return hash<std::string>::operator()(str);
|
||||
}
|
||||
};
|
||||
return hash_data(str.data(), (int)str.length());
|
||||
}
|
||||
|
||||
template<>
|
||||
struct hash<Kakoune::StringView>
|
||||
{
|
||||
size_t operator()(Kakoune::StringView str) const
|
||||
{
|
||||
return Kakoune::hash_data(str.data(), (int)str.length());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // string_hh_INCLUDED
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef units_hh_INCLUDED
|
||||
#define units_hh_INCLUDED
|
||||
|
||||
#include "hash.hh"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace Kakoune
|
||||
|
@ -119,6 +121,8 @@ struct LineCount : public StronglyTypedNumber<LineCount, int>
|
|||
constexpr LineCount(int value = 0) : StronglyTypedNumber<LineCount>(value) {}
|
||||
};
|
||||
|
||||
inline size_t hash_value(LineCount val) { return hash_value((int)val); }
|
||||
|
||||
[[gnu::always_inline]]
|
||||
inline constexpr LineCount operator"" _line(unsigned long long int value)
|
||||
{
|
||||
|
@ -131,6 +135,8 @@ struct ByteCount : public StronglyTypedNumber<ByteCount, int>
|
|||
constexpr ByteCount(int value = 0) : StronglyTypedNumber<ByteCount>(value) {}
|
||||
};
|
||||
|
||||
inline size_t hash_value(ByteCount val) { return hash_value((int)val); }
|
||||
|
||||
[[gnu::always_inline]]
|
||||
inline constexpr ByteCount operator"" _byte(unsigned long long int value)
|
||||
{
|
||||
|
@ -149,6 +155,8 @@ inline constexpr CharCount operator"" _char(unsigned long long int value)
|
|||
return CharCount(value);
|
||||
}
|
||||
|
||||
inline size_t hash_value(CharCount val) { return hash_value((int)val); }
|
||||
|
||||
}
|
||||
|
||||
#endif // units_hh_INCLUDED
|
||||
|
|
17
src/unordered_map.hh
Normal file
17
src/unordered_map.hh
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef unordered_map_hh_INCLUDED
|
||||
#define unordered_map_hh_INCLUDED
|
||||
|
||||
#include "hash.hh"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
template<typename Key, typename Value>
|
||||
using UnorderedMap = std::unordered_map<Key, Value, Hash<Key>>;
|
||||
|
||||
}
|
||||
|
||||
#endif // unordered_map_hh_INCLUDED
|
||||
|
|
@ -2,9 +2,9 @@
|
|||
#define user_interface_hh_INCLUDED
|
||||
|
||||
#include "safe_ptr.hh"
|
||||
#include "unordered_map.hh"
|
||||
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
@ -63,7 +63,7 @@ public:
|
|||
|
||||
virtual void set_input_callback(InputCallback callback) = 0;
|
||||
|
||||
using Options = std::unordered_map<String, String>;
|
||||
using Options = UnorderedMap<String, String>;
|
||||
virtual void set_ui_options(const Options& options) = 0;
|
||||
};
|
||||
|
||||
|
|
17
src/utils.hh
17
src/utils.hh
|
@ -185,21 +185,4 @@ bool is_in_range(const T& val, const T& min, const T& max)
|
|||
|
||||
}
|
||||
|
||||
// std::pair hashing
|
||||
namespace std
|
||||
{
|
||||
|
||||
template<typename T1, typename T2>
|
||||
struct hash<std::pair<T1,T2>>
|
||||
{
|
||||
size_t operator()(const std::pair<T1,T2>& val) const
|
||||
{
|
||||
size_t seed = std::hash<T2>()(val.second);
|
||||
return seed ^ (std::hash<T1>()(val.first) + 0x9e3779b9 +
|
||||
(seed << 6) + (seed >> 2));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // utils_hh_INCLUDED
|
||||
|
|
25
src/value.hh
25
src/value.hh
|
@ -1,11 +1,11 @@
|
|||
#ifndef value_hh_INCLUDED
|
||||
#define value_hh_INCLUDED
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "unordered_map.hh"
|
||||
#include "units.hh"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
|
@ -76,23 +76,10 @@ struct ValueId : public StronglyTypedNumber<ValueId, int>
|
|||
}
|
||||
};
|
||||
|
||||
using ValueMap = std::unordered_map<ValueId, Value>;
|
||||
inline size_t hash_value(ValueId val) { return hash_value((int)val); }
|
||||
|
||||
using ValueMap = UnorderedMap<ValueId, Value>;
|
||||
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
||||
template<>
|
||||
struct hash<Kakoune::ValueId>
|
||||
{
|
||||
size_t operator()(Kakoune::ValueId val) const
|
||||
{
|
||||
return std::hash<int>()((int)val);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // value_hh_INCLUDED
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
UsedChars letters;
|
||||
int refcount;
|
||||
};
|
||||
using WordList = std::unordered_map<InternedString, WordInfo>;
|
||||
using WordList = UnorderedMap<InternedString, WordInfo>;
|
||||
private:
|
||||
using LineToWords = std::vector<std::vector<InternedString>>;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user