static inline int si_getresult(siread *q, sv *v, int compare) { int rc; if (compare) { rc = sr_compare(q->r->scheme, sv_pointer(v), sv_size(v), q->key, q->keysize); if (ssunlikely(rc != 0)) return 0; } if (q->prefix) { rc = sr_compareprefix(q->r->scheme, q->prefix, q->prefixsize, sv_pointer(v), sv_size(v)); if (ssunlikely(! rc)) return 0; } if (ssunlikely(q->has)) return sv_lsn(v) > q->vlsn; if (ssunlikely(sv_is(v, SVDELETE))) return 2; rc = si_readdup(q, v); if (ssunlikely(rc == -1)) return -1; return 1; }
SrOGLData::SrOGLData ( SrSnShapeBase* s ) { //LOG("SrOGLData constructor"); int i; SrArray<SrSaGlRender::RegData>& rfuncs = SrSaGlRender::_rfuncs; //SR_TRACE2 ( "Initializing render data for "<<s->inst_class_name() ); s->changed ( true ); //LOG("s->changed"); s->set_renderlib_data ( this ); //LOG("s->set_render_lib_data()"); // we could use here a sorted array, but as the number of registered classes // is normally low (<10), the overhead is not worth. for ( i=0; i<rfuncs.size(); i++ ) if ( sr_compare(rfuncs[i].class_name,s->inst_class_name())==0 ) break; //LOG("after sr_compare, rfunc size = %d",rfuncs.size()); if ( i==rfuncs.size() ) { LOG("SrSaGlRender: shape [%s] not registered!",s->inst_class_name()); sr_out.fatal_error("SrSaGlRender: shape [%s] not registered!",s->inst_class_name()); } rfunc = rfuncs[i].rfunc; #if USE_GL_FIXED_PIPELINE list = glGenLists ( 1 ); // creates one list // sr_out<<"is list: "<<glIsList(list)<<srnl; #endif }
int si_nodecmp(sinode *n, void *key, int size, srcomparator *c) { sdindexpage *min = sd_indexmin(&n->self.index); sdindexpage *max = sd_indexmax(&n->self.index); int l = sr_compare(c, sd_indexpage_min(min), min->sizemin, key, size); int r = sr_compare(c, sd_indexpage_max(max), max->sizemin, key, size); /* inside range */ if (l <= 0 && r >= 0) return 0; /* key > range */ if (l == -1) return -1; /* key < range */ assert(r == 1); return 1; }
static int si_redistribute(si *index, sr *r, sdc *c, sinode *node, ssbuf *result) { (void)index; svindex *vindex = si_nodeindex(node); ssiter i; ss_iterinit(sv_indexiter, &i); ss_iteropen(sv_indexiter, &i, r, vindex, SS_GTE, NULL, 0); while (ss_iterhas(sv_indexiter, &i)) { sv *v = ss_iterof(sv_indexiter, &i); int rc = ss_bufadd(&c->b, r->a, &v->v, sizeof(svv**)); if (ssunlikely(rc == -1)) return sr_oom_malfunction(r->e); ss_iternext(sv_indexiter, &i); } if (ssunlikely(ss_bufused(&c->b) == 0)) return 0; ss_iterinit(ss_bufiterref, &i); ss_iteropen(ss_bufiterref, &i, &c->b, sizeof(svv*)); ssiter j; ss_iterinit(ss_bufiterref, &j); ss_iteropen(ss_bufiterref, &j, result, sizeof(sinode*)); sinode *prev = ss_iterof(ss_bufiterref, &j); ss_iternext(ss_bufiterref, &j); while (1) { sinode *p = ss_iterof(ss_bufiterref, &j); if (p == NULL) { assert(prev != NULL); while (ss_iterhas(ss_bufiterref, &i)) { svv *v = ss_iterof(ss_bufiterref, &i); v->next = NULL; sv_indexset(&prev->i0, r, v); ss_iternext(ss_bufiterref, &i); } break; } while (ss_iterhas(ss_bufiterref, &i)) { svv *v = ss_iterof(ss_bufiterref, &i); v->next = NULL; sdindexpage *page = sd_indexmin(&p->self.index); int rc = sr_compare(r->scheme, sv_vpointer(v), v->size, sd_indexpage_min(&p->self.index, page), page->sizemin); if (ssunlikely(rc >= 0)) break; sv_indexset(&prev->i0, r, v); ss_iternext(ss_bufiterref, &i); } if (ssunlikely(! ss_iterhas(ss_bufiterref, &i))) break; prev = p; ss_iternext(ss_bufiterref, &j); } assert(ss_iterof(ss_bufiterref, &i) == NULL); return 0; }
void register_render_function ( const char* class_name, SrSaGlRender::render_function rfunc ) // friend { SrArray<SrSaGlRender::RegData> &rf = SrSaGlRender::_rfuncs; int i; for ( i=0; i<rf.size(); i++ ) { if ( sr_compare(rf[i].class_name,class_name)==0 ) break; } if ( i==rf.size() ) rf.push(); // if not found, push a new position rf[i].class_name = class_name; rf[i].rfunc = rfunc; //LOG("render function %s is set to %d, _rfuncs size = %d",class_name, i, rf.size()); }
int SrHashTableBase::lookup_index ( const char *st ) const { if( !st ) return -1; if( _elements == 0 ) return -1; int id = ::hash ( st, _hash_size ); if ( _table[id].st==0 ) return -1; // empty entry, not found while ( true ) { if ( sr_compare(_table[id].st,st)==0 ) return id; // already there // else check next colliding entry: if ( _table[id].next<0 ) return -1; // no more entries, not found id = _table[id].next; } }
bool SrSaGlRender::shape_apply ( SrSnShapeBase* s ) { // 1. Ensures that render data is initialized //LOG("SrSAGLRender::shape_apply(), s = %d",s); SrOGLData* ogl = (SrOGLData*) s->get_renderlib_data(); //LOG("after s->get_renderlib_data(), ogl = %d", ogl); if ( !ogl ) { ogl = new SrOGLData ( s ); } //LOG("check ogl"); // 2. Render only if needed if ( !s->visible() ) return true; bool isSrModel = sr_compare(s->inst_class_name(),"model") == 0; //LOG("check isSrModel"); // 3. Check if lists are up to date #if USE_GL_FIXED_PIPELINE // no display list for OpenGL ES Rendering if ( !s->haschanged() && !isSrModel) { //SR_TRACE2 ( "Calling list..." ); glCallList ( ogl->list ); return true; } // 4. If the list is not up to date, regenerate it calling the render function //SR_TRACE2 ( "Creating and executing list of SrSn"<<s->inst_class_name()<<"..." ); if (!isSrModel) { glNewList ( ogl->list, GL_COMPILE_AND_EXECUTE ); ogl->rfunc ( s ); glEndList (); s->changed(false); } else #endif { //LOG("ogl->rfunc"); ogl->rfunc(s); } return true; }
bool SrHashTableBase::_insert ( const char *st, void* data, char dynamic ) { if ( !st ) { _last_id=-1; return false; } if ( _hash_size<=0 ) init ( 256 ); // automatic initialization to avoid problems int id = ::hash ( st, _hash_size ); if ( _table[id].st==0 ) // empty entry, just take it { _set_entry ( id, st, data, dynamic ); _elements++; _last_id = id; return true; } while ( true ) { if ( sr_compare(_table[id].st,st)==0 ) // already there { _last_id = id; return false; } // else check next colliding entry: if ( _table[id].next<0 ) // no more entries, add one: { int newid; if ( _free.size()>0 ) { newid = _free.pop(); } else { newid = _table.size(); _table.push(); } _table[id].next = newid; _set_entry ( newid, st, data, dynamic ); _elements++; _last_id = newid; return true; } id = _table[id].next; } }
void* SrHashTableBase::remove ( const char *st ) { if ( !st ) { _last_id=-1; return 0; } int id = ::hash ( st, _hash_size ); if ( _table[id].st==0 ) return 0; // already empty entry int priorid=id; while ( true ) { if ( sr_compare(_table[id].st,st)==0 ) // found: remove it { void* data = _table[id].data; int next = _table[id].next; _clear_entry ( id ); _elements--; // fix links: if ( priorid==id ) // removing first entry { if ( next>=0 ) { _table[id] = _table[next]; _set_entry ( next, 0 /*st*/, 0 /*data*/, 0 /*dynamic*/ ); _free.push() = next; } else { } // nothing to do } else // removing entry in the "linked list" { _table[priorid].next = next; _free.push() = id; } return data; } priorid = id; id = _table[id].next; } }
static inline int si_rangebranch(siread *q, sinode *n, sibranch *b, svmerge *m) { sicachebranch *c = si_cachefollow(q->cache); assert(c->branch == b); /* iterate cache */ if (ss_iterhas(sd_read, &c->i)) { svmergesrc *s = sv_mergeadd(m, &c->i); si_readstat(q, 1, n, 1); s->ptr = c; return 1; } if (c->open) { return 1; } if (q->cache_only) { return 2; } c->open = 1; /* choose compression type */ int compression; ssfilterif *compression_if; if (! si_branchis_root(b)) { compression = q->index->scheme->compression_branch; compression_if = q->index->scheme->compression_branch_if; } else { compression = q->index->scheme->compression; compression_if = q->index->scheme->compression_if; } sdreadarg arg = { .index = &b->index, .buf = &c->buf_a, .buf_xf = &c->buf_b, .buf_read = &q->index->readbuf, .index_iter = &c->index_iter, .page_iter = &c->page_iter, .use_memory = n->in_memory, .use_mmap = q->index->scheme->mmap, .use_mmap_copy = 1, .use_compression = compression, .compression_if = compression_if, .has = 0, .has_vlsn = 0, .o = q->order, .memory = &b->copy, .mmap = &n->map, .file = &n->file, .r = q->r }; ss_iterinit(sd_read, &c->i); int rc = ss_iteropen(sd_read, &c->i, &arg, q->key, q->keysize); int reads = sd_read_stat(&c->i); si_readstat(q, 0, n, reads); if (ssunlikely(rc == -1)) return -1; if (ssunlikely(! ss_iterhas(sd_read, &c->i))) return 0; svmergesrc *s = sv_mergeadd(m, &c->i); s->ptr = c; return 1; } static inline int si_range(siread *q) { assert(q->has == 0); ssiter i; ss_iterinit(si_iter, &i); ss_iteropen(si_iter, &i, q->r, q->index, q->order, q->key, q->keysize); sinode *node; next_node: node = ss_iterof(si_iter, &i); if (ssunlikely(node == NULL)) return 0; si_txtrack(q->x, node); /* prepare sources */ svmerge *m = &q->merge; int count = node->branch_count + 2 + 1; int rc = sv_mergeprepare(m, q->r, count); if (ssunlikely(rc == -1)) { sr_errorreset(q->r->e); return -1; } /* external source (upsert) */ svmergesrc *s; sv upbuf_reserve; ssbuf upbuf; if (ssunlikely(q->upsert_v && q->upsert_v->v)) { ss_bufinit_reserve(&upbuf, &upbuf_reserve, sizeof(upbuf_reserve)); ss_bufadd(&upbuf, NULL, (void*)&q->upsert_v, sizeof(sv*)); s = sv_mergeadd(m, NULL); ss_iterinit(ss_bufiterref, &s->src); ss_iteropen(ss_bufiterref, &s->src, &upbuf, sizeof(sv*)); } /* in-memory indexes */ svindex *second; svindex *first = si_nodeindex_priority(node, &second); if (first->count) { s = sv_mergeadd(m, NULL); ss_iterinit(sv_indexiter, &s->src); ss_iteropen(sv_indexiter, &s->src, q->r, first, q->order, q->key, q->keysize); } if (ssunlikely(second && second->count)) { s = sv_mergeadd(m, NULL); ss_iterinit(sv_indexiter, &s->src); ss_iteropen(sv_indexiter, &s->src, q->r, second, q->order, q->key, q->keysize); } /* cache and branches */ rc = si_cachevalidate(q->cache, node); if (ssunlikely(rc == -1)) { sr_oom(q->r->e); return -1; } sibranch *b = node->branch; while (b) { rc = si_rangebranch(q, node, b, m); if (ssunlikely(rc == -1 || rc == 2)) return rc; b = b->next; } /* merge and filter data stream */ ssiter j; ss_iterinit(sv_mergeiter, &j); ss_iteropen(sv_mergeiter, &j, q->r, m, q->order); ssiter k; ss_iterinit(sv_readiter, &k); ss_iteropen(sv_readiter, &k, q->r, &j, &q->index->u, q->vlsn, 0); sv *v = ss_iterof(sv_readiter, &k); if (ssunlikely(v == NULL)) { sv_mergereset(&q->merge); ss_iternext(si_iter, &i); goto next_node; } rc = 1; /* convert upsert search to SS_EQ */ if (q->upsert_eq) { rc = sr_compare(q->r->scheme, sv_pointer(v), sv_size(v), q->key, q->keysize); rc = rc == 0; } /* do prefix search */ if (q->prefix && rc) { rc = sr_compareprefix(q->r->scheme, q->prefix, q->prefixsize, sv_pointer(v), sv_size(v)); } if (sslikely(rc == 1)) { if (ssunlikely(si_readdup(q, v) == -1)) return -1; } /* skip a possible duplicates from data sources */ ss_iternext(sv_readiter, &k); return rc; }
sx_untrack(v); ss_free(m->asxv, v); } } /* rollback latest reads */ sx_rollback_svp(x, &i, 0); sx_promote(x, SXCOMMIT); sx_end(x); return SXCOMMIT; } ss_rbget(sx_match, sr_compare(scheme, sv_vpointer((sscast(n, sxv, node))->v), (sscast(n, sxv, node))->v->size, key, keysize)) int sx_set(sx *x, sxindex *index, svv *version) { sxmanager *m = x->manager; sr *r = m->r; if (! (version->flags & SVGET)) { x->log_read = -1; } /* allocate mvcc container */ sxv *v = sx_valloc(m->asxv, version); if (ssunlikely(v == NULL)) { ss_quota(r->quota, SS_QREMOVE, sv_vsize(version)); sv_vfree(r, version); return -1;
static inline void si_qrangebranch(siquery *q, sinode *n, sibranch *b, svmerge *m) { sicachebranch *cb = si_cachefollow(q->cache); assert(cb->branch == b); /* iterate cache */ if (ss_iterhas(si_read, &cb->i)) { svmergesrc *s = sv_mergeadd(m, &cb->i); q->index->read_cache++; s->ptr = cb; return; } if (cb->open) { return; } cb->open = 1; sireadarg arg = { .scheme = q->index->scheme, .index = q->index, .n = n, .b = b, .buf = &cb->buf_a, .buf_xf = &cb->buf_b, .buf_read = &q->index->readbuf, .index_iter = &cb->index_iter, .page_iter = &cb->page_iter, .vlsn = q->vlsn, .has = 0, .mmap_copy = 1, .o = q->order, .r = q->r }; ss_iterinit(si_read, &cb->i); int rc = ss_iteropen(si_read, &cb->i, &arg, q->key, q->keysize); if (ssunlikely(rc == -1)) return; if (ssunlikely(! ss_iterhas(si_read, &cb->i))) return; svmergesrc *s = sv_mergeadd(m, &cb->i); s->ptr = cb; } static inline int si_qrange(siquery *q) { ssiter i; ss_iterinit(si_iter, &i); ss_iteropen(si_iter, &i, q->r, q->index, q->order, q->key, q->keysize); sinode *node; next_node: node = ss_iterof(si_iter, &i); if (ssunlikely(node == NULL)) return 0; /* prepare sources */ svmerge *m = &q->merge; int count = node->branch_count + 2 + 1; int rc = sv_mergeprepare(m, q->r, count); if (ssunlikely(rc == -1)) { sr_errorreset(q->r->e); return -1; } /* external source (update) */ svmergesrc *s; sv upbuf_reserve; ssbuf upbuf; if (ssunlikely(q->update_v && q->update_v->v)) { ss_bufinit_reserve(&upbuf, &upbuf_reserve, sizeof(upbuf_reserve)); ss_bufadd(&upbuf, NULL, (void*)&q->update_v, sizeof(sv*)); s = sv_mergeadd(m, NULL); ss_iterinit(ss_bufiterref, &s->src); ss_iteropen(ss_bufiterref, &s->src, &upbuf, sizeof(sv*)); } /* in-memory indexes */ svindex *second; svindex *first = si_nodeindex_priority(node, &second); if (first->count) { s = sv_mergeadd(m, NULL); ss_iterinit(sv_indexiter, &s->src); ss_iteropen(sv_indexiter, &s->src, q->r, first, q->order, q->key, q->keysize); } if (ssunlikely(second && second->count)) { s = sv_mergeadd(m, NULL); ss_iterinit(sv_indexiter, &s->src); ss_iteropen(sv_indexiter, &s->src, q->r, second, q->order, q->key, q->keysize); } /* cache and branches */ rc = si_cachevalidate(q->cache, node); if (ssunlikely(rc == -1)) { sr_oom(q->r->e); return -1; } sibranch *b = node->branch; while (b) { si_qrangebranch(q, node, b, m); b = b->next; } /* merge and filter data stream */ ssiter j; ss_iterinit(sv_mergeiter, &j); ss_iteropen(sv_mergeiter, &j, q->r, m, q->order); ssiter k; ss_iterinit(sv_readiter, &k); ss_iteropen(sv_readiter, &k, q->r, &j, &q->index->u, q->vlsn, 0); sv *v = ss_iterof(sv_readiter, &k); if (ssunlikely(v == NULL)) { sv_mergereset(&q->merge); ss_iternext(si_iter, &i); goto next_node; } rc = 1; /* convert update search to SS_EQ */ if (q->update_eq) { rc = sr_compare(q->r->scheme, sv_pointer(v), sv_size(v), q->key, q->keysize); rc = rc == 0; } /* do prefix search */ if (q->prefix && rc) { rc = sr_compareprefix(q->r->scheme, q->prefix, q->prefixsize, sv_pointer(v), sv_size(v)); } if (sslikely(rc == 1)) { if (ssunlikely(si_querydup(q, v) == -1)) return -1; } /* skip a possible duplicates from data sources */ ss_iternext(sv_readiter, &k); return rc; }