POPCOUNT=$(shell grep -q popcnt /proc/cpuinfo && echo 1)
ifeq ($(POPCOUNT), 1)
- POPCOUNT_FLAG=-DHAS_NATIVE_POPCOUNT
+ POPCOUNT_FLAG=-DHAS_NATIVE_POPCOUNT -mpopcnt -mtune=corei7 -march=corei7
else
#POPCOUNT_FLAG=-DHAS_POPCOUNT_TABLE
POPCOUNT_FLAG=
ifeq ($(DEBUG), true)
OPT_FLAGS=-O0 -g $(POPCOUNT_FLAG) -static
else
- OPT_FLAGS=-O4 $(POPCOUNT_FLAG) -static -flto
+ OPT_FLAGS=-O3 $(POPCOUNT_FLAG) -static -flto
endif
+ifeq ($(PROFILE), true)
+ PROF_FLAGS=-pg -g
+else
+ PROF_FLAGS=
+endif
+
INC_FLAGS=-I.
-CFLAGS= $(INC_FLAGS) $(OPT_FLAGS)
-CXXFLAGS= $(INC_FLAGS) $(OPT_FLAGS)
+CFLAGS= $(INC_FLAGS) $(OPT_FLAGS) $(PROF_FLAGS)
+CXXFLAGS= $(INC_FLAGS) $(OPT_FLAGS) $(PROF_FLAGS)
CC=g++
while (j>0) {
w = (x >> (D-ETW)) & ((1<<ETW)-1);
if (rel >= -ETW && rel <= ETW) {
- r = fwdtbl[((rel+ETW)<<ETW)+w];
- if (r<ETW && r<j) {
- if (i+r >= n) return NOTFOUND;
- return i+r;
- }
+ r = fwdtbl[((rel+ETW)<<ETW)+w];
+ if (r<ETW && r<j) {
+ if (i+r >= n) return NOTFOUND;
+ return i+r;
+ }
}
r = min(j,ETW);
rel -= 2*popcount(w)-r;
w = (x >> (D-ETW)) & ((1<<ETW)-1);
w2 = 0;
if (j < ETW || il-i < ETW) {
- r = max(ETW-j,ETW-(il-i));
- w2 = (1<<r)-1;
+ r = max(ETW-j,ETW-(il-i));
+ w2 = (1<<r)-1;
}
v = minmaxtbl_v[0][w | w2];
if (d + v < rel) {
- if (ith > 0) {
+ if (ith > 0) {
#if 0
- for (r = 0; r < ETW; r++) {
- if (w & 0x80) {
- d++;
- } else {
- d--;
- if (d < rel) break;
- if (d == rel) {
- ith--;
- if (ith == 0) {
- *ans = i + r;
- return FOUND;
- }
- }
- }
- w <<= 1;
- }
- return NOTFOUND;
+ for (r = 0; r < ETW; r++) {
+ if (w & 0x80) {
+ d++;
+ } else {
+ d--;
+ if (d < rel) break;
+ if (d == rel) {
+ ith--;
+ if (ith == 0) {
+ *ans = i + r;
+ return FOUND;
+ }
+ }
+ }
+ w <<= 1;
+ }
+ return NOTFOUND;
#else
- r = childtbl2[rel-d+ETW][ith-1][w];
- if (r >= 0) {
- *ans = i + r;
- return FOUND;
- }
- return NOTFOUND;
+ r = childtbl2[rel-d+ETW][ith-1][w];
+ if (r >= 0) {
+ *ans = i + r;
+ return FOUND;
+ }
+ return NOTFOUND;
#endif
- }
- r = ETW-1-minmaxtbl_i[0][w | w2];
- w2 = (1<<r)-1;
- deg += degtbl2[((rel-d+ETW)<<ETW) + (w & (~w2))];
- *ans = deg;
- return END;
+ }
+ r = ETW-1-minmaxtbl_i[0][w | w2];
+ w2 = (1<<r)-1;
+ deg += degtbl2[((rel-d+ETW)<<ETW) + (w & (~w2))];
+ *ans = deg;
+ return END;
}
if (d + v == rel) {
- r = degtbl[w | w2];
- deg += r;
- if (ith > 0) {
- if (ith <= r) {
- *ans = i + childtbl[((ith-1)<<ETW) + (w | w2)];
- return FOUND;
- }
- ith -= r;
- }
+ r = degtbl[w | w2];
+ deg += r;
+ if (ith > 0) {
+ if (ith <= r) {
+ *ans = i + childtbl[((ith-1)<<ETW) + (w | w2)];
+ return FOUND;
+ }
+ ith -= r;
+ }
}
r = min(j,ETW);
if (m < td) {
r = degree_SB(b,i,n,td-d,°tmp,ith);
if (ith > 0) {
- if (r == NOTFOUND) return NOTFOUND;
- *ans = degtmp;
- return FOUND;
+ if (r == NOTFOUND) return NOTFOUND;
+ *ans = degtmp;
+ return FOUND;
} else {
- *ans = deg + degtmp;
- return END;
+ *ans = deg + degtmp;
+ return END;
}
}
if (m == td) {
if (ith > 0) {
- if (ith <= b->sd[SBid(i)]) break;
- ith -= b->sd[SBid(i)];
+ if (ith <= b->sd[SBid(i)]) break;
+ ith -= b->sd[SBid(i)];
}
deg += b->sd[SBid(i)];
}
if (ith > 0) {
if (r == NOTFOUND) return NOTFOUND;
if (r == FOUND) {
- *ans = degtmp;
- return FOUND;
+ *ans = degtmp;
+ return FOUND;
}
} else {
deg += degtmp;
while (s <= t) {
if (s & h) {
if (s+h-1 <= t) {
- printf("[%d,%d] ",s,s+h-1);
- s += h;
+ printf("[%d,%d] ",s,s+h-1);
+ s += h;
}
} else {
if (s+h > t) break;
} else {
deg += degtmp;
if (d == END) {
- return deg;
+ return deg;
}
}
}
}
if (b->mm[i] == td) {
if (ith > 0) {
- if (ith <= b->md[i]) break;
- ith -= b->md[i];
+ if (ith <= b->md[i]) break;
+ ith -= b->md[i];
}
deg += b->md[i];
}
while (sm <= tm) {
if (sm & h) {
if (sm+h-1 <= tm) {
- //printf("[%d,%d] ",sm,sm+h-1);
- j = sm / h;
- if (b->mm[j] < td) {
- h >>= 1;
- break;
- }
- if (b->mm[j] == td) {
- if (ith > 0) {
- if (ith <= b->md[j]) {
- h >>= 1;
- break;
- }
- ith -= b->md[j];
- }
- deg += b->md[j];
- }
- sm += h;
+ //printf("[%d,%d] ",sm,sm+h-1);
+ j = sm / h;
+ if (b->mm[j] < td) {
+ h >>= 1;
+ break;
+ }
+ if (b->mm[j] == td) {
+ if (ith > 0) {
+ if (ith <= b->md[j]) {
+ h >>= 1;
+ break;
+ }
+ ith -= b->md[j];
+ }
+ deg += b->md[j];
+ }
+ sm += h;
}
} else {
if (sm+h > tm) break;
//printf("[%d,%d] ",sm,sm+h-1);
j = sm / h;
if (ith > 0) {
- if (b->mm[j] >= td) {
- if (b->mm[j] == td) {
- if (ith > b->md[j]) {
- ith -= b->md[j];
- sm += h;
- } else {
- deg += b->md[j];
- }
- } else {
- sm += h;
- }
- }
+ if (b->mm[j] >= td) {
+ if (b->mm[j] == td) {
+ if (ith > b->md[j]) {
+ ith -= b->md[j];
+ sm += h;
+ } else {
+ deg += b->md[j];
+ }
+ } else {
+ sm += h;
+ }
+ }
} else {
- if (b->mm[j] >= td) {
- if (b->mm[j] == td) {
- deg += b->md[j];
- }
- sm += h;
- }
+ if (b->mm[j] >= td) {
+ if (b->mm[j] == td) {
+ deg += b->md[j];
+ }
+ sm += h;
+ }
}
}
h >>= 1;
while (j>0) {
w = x & ((1<<ETW)-1);
if (rel >= -ETW && rel <= ETW) {
- r = bwdtbl[((rel+ETW)<<ETW)+w];
- if (r<ETW && r<j) {
- if (i-r < 0) return NOTFOUND;
- return i-r-1;
- }
+ r = bwdtbl[((rel+ETW)<<ETW)+w];
+ if (r<ETW && r<j) {
+ if (i-r < 0) return NOTFOUND;
+ return i-r-1;
+ }
}
r = min(j,ETW);
rel += 2*popcount(w)-r;
w = (x >> (D-ETW)) & ((1<<ETW)-1);
w2 = 0;
if (j < ETW || t-i < ETW-1) {
- r = max(ETW-j,ETW-1-(t-i));
- w2 = (1<<r)-1;
+ r = max(ETW-j,ETW-1-(t-i));
+ w2 = (1<<r)-1;
}
if (op & OPT_MAX) {
- v = minmaxtbl_v[op][w & (~w2)];
- if (d + v + lr > ds) {
- ds = d + v;
- is = i + minmaxtbl_i[op][w & (~w2)];
- }
+ v = minmaxtbl_v[op][w & (~w2)];
+ if (d + v + lr > ds) {
+ ds = d + v;
+ is = i + minmaxtbl_i[op][w & (~w2)];
+ }
} else {
- v = minmaxtbl_v[op][w | w2];
- if (d + v < ds +lr) {
- ds = d + v;
- is = i + minmaxtbl_i[op][w | w2];
- }
+ v = minmaxtbl_v[op][w | w2];
+ if (d + v < ds +lr) {
+ ds = d + v;
+ is = i + minmaxtbl_i[op][w | w2];
+ }
}
r = min(j,ETW);
if (bp_getbit(b->B,i)==OP) {
d++;
if (op & OPT_MAX) {
- if (d + lr > ds) {
- ds = d; is = i;
- }
+ if (d + lr > ds) {
+ ds = d; is = i;
+ }
}
} else {
d--;
if (!(op & OPT_MAX)) {
- if (d < ds + lr) {
- ds = d; is = i;
- }
+ if (d < ds + lr) {
+ ds = d; is = i;
+ }
}
}
i++;
if (opt & OPT_MAX) {
m = d + b->sM[i] - 1;
if (m + lr > md) {
- md = m; mi = i;
+ md = m; mi = i;
}
} else {
m = d + b->sm[i] - SB;
if (m < md + lr) {
- md = m; mi = i;
+ md = m; mi = i;
}
}
}
for (i=sm; i<=tm; i++) {
if (opt & OPT_MAX) {
if (b->mM[i] + lr > ds) {
- ds = b->mM[i]; is = i - m_ofs; ys = 2;
+ ds = b->mM[i]; is = i - m_ofs; ys = 2;
}
} else {
if (b->mm[i] < ds + lr) {
- ds = b->mm[i]; is = i - m_ofs; ys = 2;
+ ds = b->mm[i]; is = i - m_ofs; ys = 2;
}
}
}
if (opt & OPT_MAX) {
if (b->mM[sm] + lr > ds) {
- ds = b->mM[sm]; is = sm; ys = 2;
+ ds = b->mM[sm]; is = sm; ys = 2;
}
for (i=0; i<=h-2; i++) {
- j = sm>>i;
- if ((j&1) == 0) {
- if (b->mM[j+1] + lr > ds) {
- ds = b->mM[j+1]; is = j+1; ys = 2;
- }
- }
+ j = sm>>i;
+ if ((j&1) == 0) {
+ if (b->mM[j+1] + lr > ds) {
+ ds = b->mM[j+1]; is = j+1; ys = 2;
+ }
+ }
}
for (i=h-2; i>=0; i--) {
- j = tm>>i;
- if ((j&1)==1) {
- if (b->mM[j-1] + lr > ds) {
- ds = b->mM[j-1]; is = j-1; ys = 2;
- }
- }
+ j = tm>>i;
+ if ((j&1)==1) {
+ if (b->mM[j-1] + lr > ds) {
+ ds = b->mM[j-1]; is = j-1; ys = 2;
+ }
+ }
}
if (b->mM[tm] + lr > ds) {
- ds = b->mM[tm]; is = tm; ys = 2;
+ ds = b->mM[tm]; is = tm; ys = 2;
}
if (ys == 2) {
- while (is < m_ofs) {
- is <<= 1;
- if (b->mM[is+1] + lr > b->mM[is]) is++;
- }
- is -= m_ofs;
+ while (is < m_ofs) {
+ is <<= 1;
+ if (b->mM[is+1] + lr > b->mM[is]) is++;
+ }
+ is -= m_ofs;
}
} else { // MIN
if (b->mm[sm] < ds + lr) {
- ds = b->mm[sm]; is = sm; ys = 2;
+ ds = b->mm[sm]; is = sm; ys = 2;
}
for (i=0; i<=h-2; i++) {
- j = sm>>i;
- if ((j&1) == 0) {
- if (b->mm[j+1] < ds + lr) {
- ds = b->mm[j+1]; is = j+1; ys = 2;
- }
- }
+ j = sm>>i;
+ if ((j&1) == 0) {
+ if (b->mm[j+1] < ds + lr) {
+ ds = b->mm[j+1]; is = j+1; ys = 2;
+ }
+ }
}
for (i=h-2; i>=0; i--) {
- j = tm>>i;
- if ((j&1)==1) {
- if (b->mm[j-1] < ds + lr) {
- ds = b->mm[j-1]; is = j-1; ys = 2;
- }
- }
+ j = tm>>i;
+ if ((j&1)==1) {
+ if (b->mm[j-1] < ds + lr) {
+ ds = b->mm[j-1]; is = j-1; ys = 2;
+ }
+ }
}
if (b->mm[tm] < ds + lr) {
- ds = b->mm[tm]; is = tm; ys = 2;
+ ds = b->mm[tm]; is = tm; ys = 2;
}
if (ys == 2) {
- while (is < m_ofs) {
- is <<= 1;
- if (b->mm[is+1] < b->mm[is] + lr) is++;
- }
- is -= m_ofs;
+ while (is < m_ofs) {
+ is <<= 1;
+ if (b->mm[is+1] < b->mm[is] + lr) is++;
+ }
+ is -= m_ofs;
}
}
}
\r
static int selecttbl[8*256];\r
static int selecttbl_init = 0;\r
+static void prbin(unsigned int x)\r
+{\r
+ int i;\r
+ // for(i = 31; i >= 0; i--){\r
+ for (i = 0 ; i < 32; i ++) {\r
+ fprintf(stderr,"%.1u", (x >> i)&1);\r
+ if (i % 4 == 3)\r
+ fprintf(stderr, " ");\r
+ }\r
+\r
+}\r
+int clz(unsigned int x)\r
+{\r
+ if (x == 0)\r
+ return -1;\r
+ else\r
+ __builtin_clz(x);\r
+}\r
\r
static void make_selecttbl(void)\r
{\r
int i,x,r;\r
pb buf[1];\r
+ unsigned int mask;\r
if (selecttbl_init) return;\r
\r
selecttbl_init = 1;\r
r = 0;\r
for (i=0; i<8; i++) {\r
if (bp_getbit(buf,i)) {\r
+ // fprintf(stderr, "Init: setting %i to %i (r= %i, x = %i)\n", (r<<8)+x, i, r, x);\r
selecttbl[(r<<8)+x] = i;\r
r++;\r
}\r
}\r
}\r
+ /*\r
+ fprintf(stderr, "Select table:\n");\r
+ for (i = 0; i < 8 * 256; i++){\r
+ mask = i / 256 + 1;\r
+ x = __builtin_clz((i + (i << 8)));\r
+ prbin(i);\r
+ fprintf(stderr, " (%.4i): %08i, %08i\n", i, selecttbl[i], x);\r
+ };\r
+ */\r
}\r
\r
\r
void bp_darray_free(darray *da);
int bp_darray_select(darray *da, int i,int f);
+
static int bp_darray_rank(darray *da, int i)
{
int r,j,i_rr, i_rrr;
#define RRR (1<<logRRR)
-
-
-
#include <stdlib.h>
-
+#ifdef __GNUC__
+#define UNUSED __attribute__((unused))
+#else
+#define UNUSED
+#endif
#ifdef HAS_NATIVE_POPCOUNT
-static inline unsigned int popcount(unsigned int n){
+static inline UNUSED unsigned int popcount(unsigned int n){
asm ("popcnt %1, %0" : "=r" (n) : "0" (n));
return n;
}
-static inline unsigned int popcount8(unsigned int n) {
+static inline UNUSED unsigned int popcount8(unsigned int n) {
return popcount(n & 0xff);
}
extern unsigned char popCount[256];
-static unsigned int popcount8(unsigned int x)
+static UNUSED unsigned int popcount8(unsigned int x)
{
return (unsigned int) popCount[x & 0xff];
}
-static unsigned int popcount(unsigned int x)
+static UNUSED unsigned int popcount(unsigned int x)
{
return popcount8(x) +
popcount8((x >> 8)) +
#else
-static unsigned int popcount8(unsigned int x)
+static UNUSED unsigned int popcount8(unsigned int x)
{
unsigned int r;
r = x;
return r;
}
-static inline unsigned int popcount(unsigned int x)
+static inline UNUSED unsigned int popcount(unsigned int x)
{
unsigned int m1 = 0x55555555;
unsigned int m2 = 0xc30c30c3;
#include "bp.h"
+#include <unistd.h>
//#define CHECK
#define RANDOM
if (bp_getbit(buf,i)==OP) {
r++;
if (r > M) {
- M = r;
+ M = r;
//maxtbl_li[x] = i; maxtbl_lv[x] = r;
minmaxtbl_i[OPT_MAX | OPT_LEFT][x] = i;
minmaxtbl_v[OPT_MAX | OPT_LEFT][x] = r;
if (bp_getbit(buf,i)==OP) {
r++;
if (r >= M) {
- M = r;
+ M = r;
//maxtbl_ri[x] = i; maxtbl_rv[x] = r;
minmaxtbl_i[OPT_MAX | OPT_RIGHT][x] = i;
minmaxtbl_v[OPT_MAX | OPT_RIGHT][x] = r;
}
}
+static ssize_t uwrite(int fd, const void* buff, size_t count)
+{
+ ssize_t written;
+ char *p = (char *) buff;
+ do {
+ written = write(fd, p, count);
+ p += written;
+ count -= written;
+ } while (written > 0);
+
+ return (written == -1);
+}
+
+static ssize_t uread(int fd, const void* buff, size_t count)
+{
+ ssize_t loaded;
+ char *p = (char *) buff;
+ do {
+ loaded = read(fd, p, count);
+ p += loaded;
+ count -= loaded;
+ } while (loaded > 0);
+
+ return (loaded == -1);
+}
+
+int bp_save(bp *b, int fd)
+{
+ if (uwrite(fd, &b->n, sizeof(int))) return 1;
+ if (uwrite(fd, b->B, sizeof(pb) * (b->n+D-1)/D)) return 1;
+ if (uwrite(fd, &b->opt, sizeof(int))) return 1;
+ return 0;
+}
+
+bp* bp_load(int fd)
+{
+ pb *B;
+ int n, opt;
+ if (uread(fd, &n, sizeof(int))) return NULL;
+ bp_xmalloc(B, (n+D-1)/D);
+
+ if (B == NULL) return NULL;
+
+ if (uread(fd, B, sizeof(pb) * (n+D-1)/D)) {
+ free(B);
+ return NULL;
+ };
+
+ if (uread(fd, &opt, sizeof(int))){
+ free(B);
+ return NULL;
+ };
+
+ return bp_construct(n, B, opt);
+}
+
+
// loadTree: load parentheses data structure from file
// By Diego Arroyuelo
bp * loadTree(FILE *fp) {
exit(1);
}
- return bp_construct(n, B, opt);
+ return bp_construct(n, B, opt);
}
} else {
return bp_naive_child(b,s,d);
}
-
+
}
///////////////////////////////////////////
static inline int bp_parent(bp *b, int s)
{
- int r = bp_bwd_excess(b,s,-2);
+ int r;
+ if (bp_getbit(b->B, s - 1) == OP) return s - 1;
+ r = bp_bwd_excess(b,s,-2);
return (r >= -1) ? r+1 : -1;
}
static inline int bp_next_sibling(bp *b, int s)
{
int t;
- t = bp_find_close(b,s) + 1;
+ t = bp_find_close(b, s) + 1;
return (bp_inspect(b, t) == CP) ? -1 : t;
}
// new functions for persistence purposes, added by Diego Arroyuelo
void saveTree(bp *b, FILE *fp);
bp * loadTree(FILE *fp);
+
+//0: success 1: failure (errno)
+int bp_save(bp *b, int fd);
+
+//non-null: sucess, null: failure (errno)
+
+bp * bp_load(int fd);
void bp_delete(bp *b);