Skip to content

Commit

Permalink
Fix NaN value for DATrie float.
Browse files Browse the repository at this point in the history
Currently the nan value we use doesn't work well on i686.
Try to use value same as std::nanf("1") and std::nanf("2").

Fix #4
  • Loading branch information
wengxt committed Aug 23, 2020
1 parent a108d15 commit dff3ea6
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
*.kdev4
*~
build
build*
test/bench.cpp
test/cedarpp.h
*.tar.*
Expand Down
2 changes: 1 addition & 1 deletion src/libime/core/datrie.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ class DATriePrivate {
moved -= 1 + sizeof(value_type); // keep record
}
moved += offset;
for (auto i = offset; i <= moved; i += 1 + sizeof(value_type)) {
for (ssize_t i = offset; i <= moved; i += 1 + sizeof(value_type)) {
if (m_tail0.capacity() == m_tail0.size()) {
auto quota =
m_tail0.capacity() + (m_tail0.size() >= MAX_ALLOC_SIZE
Expand Down
4 changes: 2 additions & 2 deletions src/libime/core/datrie.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ struct NaN {
};
template <>
struct NaN<float> {
static constexpr auto N1 = 0x7f800001;
static constexpr auto N2 = 0x7f800002;
static constexpr auto N1 = 0x7fc00001;
static constexpr auto N2 = 0x7fc00002;
};

/**
Expand Down
2 changes: 2 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ foreach(TESTCASE ${LIBIME_SINGLE_FILE_TEST})
COMMAND ${TESTCASE})
endforeach()

add_dependencies(testdecoder opengram-dict opengram-lm)

add_executable(triebench triebench.cpp)
target_link_libraries(triebench LibIME::Core)

Expand Down
56 changes: 42 additions & 14 deletions test/testtrie.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,52 @@
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "libime/core/datrie.h"
#include <cmath>
#include <cstring>
#include <fcitx-utils/log.h>

using namespace libime;

int main() {
DATrie<int32_t> trie;
trie.set("aaaa", 1);
trie.set("aaab", 1);
trie.set("aaac", 1);
trie.set("aaad", 1);
trie.set("aab", 1);
FCITX_ASSERT(trie.size() == 5);
trie.erase("aaaa");
FCITX_ASSERT(trie.size() == 4);
DATrie<int32_t>::position_type pos = 0;
auto result = trie.traverse("aaa", pos);
FCITX_ASSERT(trie.isNoValue(result));
trie.erase(pos);
FCITX_ASSERT(trie.size() == 4);
{
DATrie<int32_t> trie;
trie.set("aaaa", 1);
trie.set("aaab", 1);
trie.set("aaac", 1);
trie.set("aaad", 1);
trie.set("aab", 1);
FCITX_ASSERT(trie.size() == 5);
trie.erase("aaaa");
FCITX_ASSERT(trie.size() == 4);
DATrie<int32_t>::position_type pos = 0;
auto result = trie.traverse("aaa", pos);
FCITX_ASSERT(trie.isNoValue(result));
trie.erase(pos);
FCITX_ASSERT(trie.size() == 4);
}

{
DATrie<float> trie;
trie.set("aaaa", 1);
trie.set("aaab", 1);
trie.set("aaac", 1);
trie.set("aaad", 1);
trie.set("aab", 1);
FCITX_ASSERT(trie.size() == 5);
trie.erase("aaaa");
FCITX_ASSERT(trie.size() == 4);
DATrie<float>::position_type pos = 0;
auto result = trie.traverse("aaa", pos);
auto nan1 = std::nanf("1");
auto nan2 = std::nanf("2");
// NaN != NaN, we must use memcmp to do this.
FCITX_ASSERT(memcmp(&nan1, &result, sizeof(float)) == 0);
FCITX_ASSERT(trie.isNoValue(result));
result = trie.traverse("aaae", pos);
FCITX_ASSERT(memcmp(&nan2, &result, sizeof(float)) == 0);
FCITX_ASSERT(trie.isNoPath(result));
trie.erase(pos);
FCITX_ASSERT(trie.size() == 4);
}
return 0;
}

0 comments on commit dff3ea6

Please sign in to comment.