Algorithm-PageRank-XS
view release on metacpan or search on metacpan
p->dim_map = newHV();
p->rev_map = newHV();
p->num_elements = 0;
}
static size_t get_dim_map(pTHX_ pagerank p, SV * value) {
STRLEN len;
SV * retval;
SV ** hvret;
size_t result;
char *val = SvPV(value, len);
if (hv_exists(p->dim_map, val, len)) {
hvret = hv_fetch(p->dim_map, val, len, 0);
if (hvret != NULL) {
if (SvIOKp(*hvret)) {
return SvIV(*hvret);
}
}
}
/* Not in the map, continue adding it. */
result = p->num_elements++;
retval = sv_newmortal();
SvREFCNT_inc(retval);
sv_setiv(retval, result);
hv_store(p->dim_map, val, len, retval, 0);
SvREFCNT_inc(value);
val = SvPV(retval, len);
hv_store(p->rev_map, val, len, value, 0);
return result;
}
MODULE = Algorithm::PageRank::XS PACKAGE = Algorithm::PageRank::XS
PROTOTYPES: ENABLE
SV *
new(char *class, ...)
PREINIT:
pagerank p;
I32 i;
CODE:
if (items % 2 == 0) croak("Odd number of elements in options");
New(__LINE__, p, 1, struct pagerank);
p->alpha = 0.85;
p->max_tries = 200;
p->convergence = 0.001;
p->num_elements = 0;
RETVAL = sv_newmortal();
sv_setref_pv(RETVAL, class, (void *) p);
for (i=1; i < items; i += 2)
option(aTHX_ p, ST(i), ST(i + 1));
p->dim_map = newHV();
p->rev_map = newHV();
p->main_table = table_init();
SvREFCNT_inc(RETVAL);
OUTPUT:
RETVAL
void
add_arc(pagerank p, ...)
PREINIT:
SV *from_, *to_;
size_t from, to;
I32 i;
Array * tmp;
CODE:
if (items % 2 == 0) croak("Odd number of elements to describe arcs");
for (i = 1; i < items; i += 2) {
from_ = ST(i);
to_ = ST(i + 1);
from = get_dim_map(aTHX_ p, from_);
to = get_dim_map(aTHX_ p, to_);
if ((tmp = table_get(p->main_table, to)) == NULL)
table_add(p->main_table, to, array_init(from));
else
array_push(tmp, from);
}
void
from_file(pagerank p, SV * file)
PREINIT:
FILE * file_;
STRLEN len, lenb;
char * buffer, *t;
I32 i;
SV * tmp1;
size_t from, to;
Array * tmp;
IO * io;
CODE:
clear(aTHX_ p);
New(__LINE__, buffer, 1024, char);
if (SvROK(file) && SvTYPE(SvRV(file)) == SVt_PVGV &&
(io = GvIO(SvRV(file)))) {
/* We have a GLOB */
file_ = fdopen(PerlIO_fileno(IoIFP(io)), "r");
if (file_ == NULL)
croak("Could not read from passed file reference");
}
else if (SvPOK(file)) {
/* We have a file */
t = SvPV(file, len);
if (len == 0) {
Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
"file is empty, using stdin as default.");
file_ = stdin;
}
else {
file_ = fopen(t, "r");
if (file_ == NULL)
croak("Could not open file for reading.");
}
to_ = *tmp2;
from = get_dim_map(aTHX_ p, from_);
to = get_dim_map(aTHX_ p, to_);
if ((tmp = table_get(p->main_table, to)) == NULL)
table_add(p->main_table, to, array_init(from));
else
array_push(tmp, from);
}
void
iterate(SV * num)
CODE:
Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
"iterate() is not supported by Algorithm::PageRank::XS.");
SV *
result(pagerank p)
PREINIT:
HV * results;
SV * curkey, * curval;
int i;
char * reskey;
STRLEN len;
Array * result;
SV ** res;
INIT:
results = (AV *)sv_2mortal((SV *)newAV());
CODE:
if (p->num_elements < 2)
croak("Only one element in pagerank table.");
result = page_rank(p->main_table, p->num_elements, p->alpha, p->convergence,
p->max_tries);
if (!result) {
/* To prevent us from running twice. */
clear(aTHX_ p);
croak("pageRank calculation failed.");
}
results = newHV();
curkey = sv_newmortal();
for (i = 0; i < array_len(result); i++) {
sv_setuv(curkey, i);
reskey = SvPV(curkey, len);
res = hv_fetch(p->rev_map, reskey, len, 0);
if (res == NULL) {
clear(aTHX_ p);
croak("pageRank calculation failed -- couldn't find label");
}
reskey = SvPV(*res, len);
curval = newSVnv(array_get(result, i));
hv_store(results, reskey, len, curval, 0);
}
array_delete(result);
RETVAL = newRV((SV *)results);
clear(aTHX_ p);
OUTPUT:
RETVAL
void
DESTROY(pagerank p)
PREINIT:
SV *x;
PPCODE:
hv_undef(p->dim_map);
hv_undef(p->rev_map);
table_delete(p->main_table);
Safefree(p);
BOOT:
if (MAX_SIZE < 0) croak("signed size_t?");
( run in 0.491 second using v1.01-cache-2.11-cpan-13bb782fe5a )