Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions extras/tests/scripts/testSuffixComparator.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash
set -euo pipefail

repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
build_dir="$(mktemp -d)"
trap 'rm -rf "${build_dir}"' EXIT

"${CXX:-g++}" \
-std=c++11 -Wall -Wextra -fsanitize=address,undefined \
-I"${repo_dir}/source" \
"${repo_dir}/extras/tests/testSuffixComparator.cpp" \
"${repo_dir}/source/funCompareUintAndSuffixesMemcmp.cpp" \
-o "${build_dir}/testSuffixComparator"

ASAN_OPTIONS=detect_leaks=0 "${build_dir}/testSuffixComparator"
52 changes: 52 additions & 0 deletions extras/tests/testSuffixComparator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include "funCompareUintAndSuffixesMemcmp.h"

#include <cstdint>
#include <iostream>
#include <limits>
#include <vector>

namespace {

struct Entry {
uint64_t insertionPoint;
uint64_t suffix;
};

bool expectSign(const Entry &left, const Entry &right, int expectedSign, const char *label)
{
int result=funCompareUintAndSuffixesMemcmp(&left, &right);
int resultSign=(result>0)-(result<0);
if (resultSign!=expectedSign)
{
std::cerr << label << ": expected sign " << expectedSign << ", observed " << resultSign << '\n';
return false;
};
return true;
}

}

int main()
{
std::vector<char> sequence={0,1,3,5, 0,1,2,5, 0,1,3,5, 2,2,2,5};
g_funCompareUintAndSuffixesMemcmp_G=sequence.data();
g_funCompareUintAndSuffixesMemcmp_N=sequence.size()-1;
g_funCompareUintAndSuffixesMemcmp_L=std::numeric_limits<uint64_t>::max();

Entry a={7,0};
Entry b={7,4};
Entry sameSuffix={7,8};
Entry earlierBucket={6,12};

bool ok=true;
ok &= expectSign(a, b, 1, "suffix order");
ok &= expectSign(b, a, -1, "reverse suffix order");
ok &= expectSign(a, sameSuffix, -1, "identical suffix tie break");
ok &= expectSign(a, a, 0, "self comparison");
ok &= expectSign(earlierBucket, a, -1, "insertion point order");

g_funCompareUintAndSuffixesMemcmp_L=2;
ok &= expectSign(a, b, -1, "finite prefix tie break");

return ok ? 0 : 1;
}
42 changes: 30 additions & 12 deletions source/funCompareUintAndSuffixesMemcmp.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#include "funCompareUintAndSuffixesMemcmp.h"
#include <string.h> //for memcmp
#include "IncludeDefine.h"

char* g_funCompareUintAndSuffixesMemcmp_G;
uint64_t g_funCompareUintAndSuffixesMemcmp_N;
uint64_t g_funCompareUintAndSuffixesMemcmp_L;

int funCompareUintAndSuffixesMemcmp ( const void *a, const void *b)
{
uint64_t* va= ((uint64_t*) a);
uint64_t* vb= ((uint64_t*) b);
const uint64_t* va=static_cast<const uint64_t*>(a);
const uint64_t* vb=static_cast<const uint64_t*>(b);

if (va[0]>vb[0])
{
Expand All @@ -17,17 +18,34 @@ int funCompareUintAndSuffixesMemcmp ( const void *a, const void *b)
return -1;
} else
{//compare suffixes
// char *p5=(char*) memchr(g_funCompareUintAndSuffixesMemcmp_G+va[1],5,g_funCompareUintAndSuffixesMemcmp_L); //first encounter of char=5
// char *p5=g_funCompareUintAndSuffixesMemcmp_G+va[1]+g_funCompareUintAndSuffixesMemcmp_L;
//compare suffixes but only until first char=5
// int comp=memcmp(g_funCompareUintAndSuffixesMemcmp_G+va[1],g_funCompareUintAndSuffixesMemcmp_G+vb[1],p5+1-(g_funCompareUintAndSuffixesMemcmp_G+va[1]));
int comp=memcmp(g_funCompareUintAndSuffixesMemcmp_G+va[1],g_funCompareUintAndSuffixesMemcmp_G+vb[1],g_funCompareUintAndSuffixesMemcmp_L);
const char* ga=g_funCompareUintAndSuffixesMemcmp_G+va[1];
const char* gb=g_funCompareUintAndSuffixesMemcmp_G+vb[1];
uint64_t compareLength=0;
if (va[1]<g_funCompareUintAndSuffixesMemcmp_N && vb[1]<g_funCompareUintAndSuffixesMemcmp_N)
{
compareLength=min(g_funCompareUintAndSuffixesMemcmp_L,
min(g_funCompareUintAndSuffixesMemcmp_N-va[1]+1,
g_funCompareUintAndSuffixesMemcmp_N-vb[1]+1));
const char* sentinel=static_cast<const char*>(memchr(ga, GENOME_spacingChar, compareLength));
if (sentinel!=NULL)
{
compareLength=sentinel-ga+1;
};
};

int comp=memcmp(ga, gb, compareLength);
if (comp!=0)
{
return comp;
};

if (comp==0)
if (va[1]>vb[1])
{
return 1;
} else if (va[1]<vb[1])
{
comp=va[1]>vb[1] ? 1 : -1;
return -1;
};
// int comp=va[1]>vb[1] ? 1 : -1;
return comp;
return 0;
};
};
4 changes: 3 additions & 1 deletion source/funCompareUintAndSuffixesMemcmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
#include <stdint.h>

extern char* g_funCompareUintAndSuffixesMemcmp_G;
extern uint64_t g_funCompareUintAndSuffixesMemcmp_N;
// Maximum number of bases to compare; UINT64_MAX means compare to the sentinel.
extern uint64_t g_funCompareUintAndSuffixesMemcmp_L;
int funCompareUintAndSuffixesMemcmp ( const void *a, const void *b);

#endif
#endif
3 changes: 2 additions & 1 deletion source/insertSeqSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ uint insertSeqSA(PackedArray & SA, PackedArray & SA1, PackedArray & SAi, char *
*/

g_funCompareUintAndSuffixesMemcmp_G=seq1[0];
g_funCompareUintAndSuffixesMemcmp_L=mapGen.pGe.gSuffixLengthMax/sizeof(uint64_t);
g_funCompareUintAndSuffixesMemcmp_N=2*nG1;
g_funCompareUintAndSuffixesMemcmp_L=mapGen.pGe.gSuffixLengthMax;
qsort((void*) indArray, nInd, 2*sizeof(uint64_t), funCompareUintAndSuffixesMemcmp);

// qsort((void*) indArray, nInd, 2*sizeof(uint64), funCompareUint2);
Expand Down