ObjStore
view release on metacpan or search on metacpan
API/osperl.c view on Meta::CPAN
{ conflict = thru; }
void osp_pathexam::no_conflict()
{
assert(target);
if (conflict) {
croak("Attempt to add %s(0x%p) '%s' to multiple indices using the same indexing key '%s'",
target->os_class(&PL_na), target, kv_string(), conflict);
}
}
// NOTE: An index conflict is only a problem if we are actually going
// to add the record to the index. If the record is already added,
// setting lots of index flags isn't going to matter because they
// are already set. OTOH, if the record fails the pathexam half
// way through we should back-out all the index flags that were
// set. This doesn't happen yet, so the flags could become set
// unnecessarily and permenantly. This could be construed as a bug
// but getting the right behavior is a hassel. It's almost not
// worth it. Perhaps the current behavior should be documented? XXX
// THE WORK-AROUND IS TO GET THE KEYS TWICE; THE FIRST TIME JUST
// TO SEE IF IT WORKS; THE SECOND TIME TO SET THE INDEX FLAGS. YUCK.
int osp_pathexam::load_target(char _mode, OSSVPV *pv)
{
if (!pathcnt) croak("no path loaded");
keycnt = 0;
conflict = 0;
tmpkey = 0;
target = pv;
if (pv->is_OSPV_Ref2())
pv = ((OSPV_Ref2*)pv)->focus();
for (int xa=0; xa < pathcnt; xa++) {
OSSV *kv = path_2key(xa, pv, _mode);
if (!kv || !kv->is_set()) return 0; //need to undo flag changes; yuck XXX
keys[xa] = kv;
++keycnt;
}
return 1;
}
OSSV *osp_pathexam::mod_ossv(OSSV *sv)
{
if (sv && !OSvREADONLY(sv) && sv->is_set()) {
if (get_mode() == 's') {
if (OSvINDEXED(sv)) {
set_conflict();
DEBUG_pathexam(warn("conflict %s", get_thru()));
}
else OSvINDEXED_on(sv);
} else if (get_mode() == 'u') {
OSvINDEXED_off(sv);
}
}
return sv;
}
// This API is a bit strange because we need to read off
// the perl stack (which can be relocated). See XSUB.h.
void osp_pathexam::load_args(int ax, int items)
{
int args = items - 1;
if (args > OSP_PATHEXAM_MAXKEYS) {
warn("Too many keys (%d) in load_args -- truncated to %d keys",
args, OSP_PATHEXAM_MAXKEYS);
args = OSP_PATHEXAM_MAXKEYS;
}
keycnt = 0;
conflict = 0;
for (int xa=0; xa < args; xa++) {
tmpkeys[xa] = ST(1+xa);
keys[xa] = &tmpkeys[xa];
++keycnt;
}
}
char *osp_pathexam::kv_string()
{
char buf[64]; //XXX danger!
SV *kv = newSVpvn("",0);
SAVEFREESV(kv);
int maxcnt = pathcnt > keycnt? pathcnt : keycnt;
for (int p1=0; p1 < maxcnt; p1++) {
if (p1 < pathcnt) {
OSSVPV *path = pcache[p1];
int plen = path->FETCHSIZE();
for (int p2=0; p2 < plen; p2++) {
sv_catpv(kv, path->avx(p2)->stringify(buf));
if (p2 < plen-1) sv_catpv(kv, "/");
}
}
if (p1 < keycnt) {
if (p1 < pathcnt) sv_catpv(kv,"=");
sv_catpv(kv, keys[p1]->stringify(buf));
}
if (p1 < maxcnt-1) sv_catpv(kv, ", ");
}
return SvPV(kv, PL_na);
}
void osp_pathexam::push_keys()
{
SV *sv[OSP_PATHEXAM_MAXKEYS];
for (int kx=0; kx < keycnt; kx++) {
sv[kx] = osp_thr::ossv_2sv(get_key(kx));
}
dSP;
EXTEND(SP, get_keycnt());
for (kx=0; kx < get_keycnt(); kx++)
PUSHs(sv[kx]);
PUTBACK;
}
int osp_pathexam::compare(osp_keypack1 &kpk, int partial)
{
if (!pathcnt) croak("no path loaded");
int cmp;
for (int kx=0; kx < pathcnt; kx++) {
if (kx >= keycnt) {
( run in 1.743 second using v1.01-cache-2.11-cpan-71847e10f99 )