⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gist_sstree.cc

📁 Libgist is an implementation of the Generalized Search Tree, a template index structure that makes i
💻 CC
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////// ss_ext_t::union_bp - generate bounding sphere for collection of predicates//// Description:// 	- SS-tree weighted centroid spheres can be incrementally//        updated because they need not be minimal.  however, the BPs//        resulting from a split are computed using the minimal//        bounding sphere.  this kind of behavior is only possible when//        the definition of the BP type is such that more than one//        adequately accurate BP is possible for a given set of//        predicates.  although some BP accuracy is lost, we incur//        constant insertion cost most of the time and quadratic cost//        1/n of the time.//	- if !bpIsValid, generates bounding sphere from scratch for //	  the page predicates plus pred1/-2//	- if bpIsValid, adds in pred1/-2 incrementally//// Preconditions:// Postconditions:// Notes://///////////////////////////////////////////////////////////////////////voidss_ext_t::union_bp(    const gist_predcursor_t& pcursor, // in    const gist_p& page, // in    const vec_t& pred1, // in    const vec_t& pred2, // in    vec_t& bp, // in/out    bool& bpChanged, // out    bool bpIsValid) // in    const{    int level = page.level();    void* bpPtr = bp.ptr(0);    int bpLen = bp.len(0);    int d; // dimension of predicates    if (!bpIsValid) {	d = convFcts[level > 1][rt_dim](pcursor.elems[0].keyLen);	bpLen = convFcts[1][rt_size](d); // size of BP	bp.set(bpPtr, bpLen);	bpChanged = true; // we're generating a new one    } else {	// if a BP is given, we know it's an internal node predicate	// (i.e., level > 1 == true)	d = convFcts[1][rt_dim](bpLen);	bpChanged = false;    }    rt_pred* newBp = NULL;    if (!bpIsValid) {	// create the new BP from scratch, also taking the extra	// predicates into account (unlike rtbase_ext_t, which adds them	// in incrementally)	int howmany = pcursor.numElems;	if (pred1.size() != 0) {	    howmany += 1;	}	if (pred2.size() != 0) {	    howmany += 1;	}	double** inCenter = new double*[howmany];	double* inCenters = new double[d * howmany];	double* inRadii = (double*) new double[howmany];	rt_centroid_sphere* sBp = NULL;	double nrec = 0;	for (int i = 0; i < howmany; ++i) {	    // assign pred. to newBp ('preserve' param is false)	    if (i < pcursor.numElems) {		newBp = expandFcts[level > 1](newBp, pcursor.elems[i].key,		    pcursor.elems[i].keyLen, false);	    } else if (i == pcursor.numElems) {		newBp = expandFcts[level > 1](newBp, pred1.ptr(0), pred1.len(0), false);	    } else {		newBp = expandFcts[level > 1](newBp, pred2.ptr(0), pred2.len(0), false);	    }	    sBp = (rt_centroid_sphere*) newBp;	    inCenter[i] = inCenters + i * d;	    for (int j = 0; j < d; ++j) {		inCenter[i][j] = sBp->center.co(j);	    }	    inRadii[i] = sBp->radius();	    nrec += sBp->rank.nrec();	}	assert(sBp != NULL);	EnclosingBall(d, howmany,	    inCenter, (level > 1) ? inRadii : (double*) NULL,	    sBp->center.coords(), sBp->radius());	sBp->rank.nrec() = nrec;	delete [] inCenter;	delete [] inCenters;	delete [] inRadii;    } else {        // add in pred1/-2 incrementally 	newBp = expandFcts[1](NULL, bpPtr, bpLen, false); // make copy of existing BP	if (pred1.len(0) != 0) {	    newBp = expandFcts[level > 1](newBp, pred1.ptr(0), pred1.len(0), true);	}	if (pred2.len(0) != 0) {	    newBp = expandFcts[level > 1](newBp, pred2.ptr(0), pred2.len(0), true);	}    }    // flag whether or not we need to change the stored BP    if (bpIsValid) {	bpChanged = !bpCmpFcts[rt_bpequal](bpPtr, bpLen, *newBp);    }    if (bpChanged) {	(void) memcpy(bpPtr, newBp->coords(), bpLen);    }    delete newBp;}typedef struct {    double coord;    int itemNo;} ssSort;static int ssSortCmp(const void* a, const void* b){    ssSort* l = (ssSort*) a;    ssSort* r = (ssSort*) b;    return((l->coord < r->coord) ? -1 : ((l->coord > r->coord) ? 1 : 0));}// returns the variance of 'coords'static doublessVariance(const double* coords, const int n){    double mean = 0.0;    int i;    for (i = 0; i < n; ++i) {	mean += coords[i];    }    mean /= (double) n;    double sum = 0.0;    for (i = 0; i < n; ++i) {	double diff = coords[i] - mean;	sum += diff * diff;    }    return(sum / (double) n);}voidss_ext_t::pickSplit(    gist_predcursor_t &pcursor,    const gist_p& page,    int rightEntries[] /*out*/,    int &numRight /*out*/,    const void *oldBp,    int oldLen,    void *leftBp /*out*/,    int &leftLen /*in/out*/,    void *rightBp /*out*/,    int &rightLen /*in/out*/) const{    int level = page.level();    int itemCnt = pcursor.numElems;	// # of items on the page    if (itemCnt < 2) {			// we can't split with fewer entries!	// XXX nicer error-handling goes here.	assert(0);    }    int nDims = convFcts[level > 1][rt_dim](pcursor.elems[0].keyLen);    leftLen = rightLen = convFcts[1][rt_size](nDims);    int i, j;    // copy all of the necessary coordinates out of the BPs (we need    // dimension vectors to pass into ssVariance).    rt_point* tmpPt = NULL;    double* vals = new double[nDims * itemCnt];    for (i = 0; i < itemCnt; ++i) {	tmpPt = (rt_point*) centerFcts[level > 1](tmpPt, pcursor.elems[i].key,	    pcursor.elems[i].keyLen);	for (j = 0; j < nDims; ++j) {	    vals[j * itemCnt + i] = tmpPt->co(j);	}    }    delete tmpPt;    // determine the axis with the highest variance; we will use this    // as the split axis.    int split = -1;    double maxVar = -1.0;    for (j = 0; j < nDims; ++j) {	double var = ssVariance(&(vals[j * itemCnt]), itemCnt);	if (var > maxVar) {	    maxVar = var;	    split = j;	}    }    // sort the points by their split axis coordinates.    ssSort* which = new ssSort[itemCnt];    for (i = 0; i < itemCnt; ++i) {	which[i].itemNo = i;	which[i].coord = vals[split * itemCnt + i];    }    qsort(which, itemCnt, sizeof(ssSort), ssSortCmp);    delete [] vals;    // now, find the split position that minimizes the total variance    // of both clusters.  the minimum acceptable space utilization    // usually restricts the positions that can be chosen.  'spos' is    // the array index of the rightmost item that must be in the left    // cluster and 'epos' is the array index of the leftmost item that    // must be in the right cluster.  (this code assumes that each    // cluster must contain at least one item.)    double* axis = new double[itemCnt];    for (i = 0; i < itemCnt; ++i) {	axis[i] = which[i].coord;    }    int sPos = (int) (MINSPLITUTIL * itemCnt), ePos = itemCnt - (sPos + 1);    int best = -1;    double minVarSum = MAXDOUBLE;    for (i = sPos; i < ePos; ++i) {	double lVar = ssVariance(axis, i + 1);	double rVar = ssVariance(axis + (i + 1), itemCnt - (i + 1));	double varSum = lVar + rVar;	if (varSum < minVarSum) {	    minVarSum = varSum;	    best = i;	}    }    delete [] axis;    // we're done.  copy everything into the out parameters.    numRight = 0;    vec_t dummyPred;    bool dummy;    gist_predcursor_t rCursor;    for (i = best + 1; i < itemCnt; ++i) {	int item = which[i].itemNo;	assert(item >= 0 && item < itemCnt);	rCursor.add(pcursor.elems[item].key, pcursor.elems[item].keyLen);	rightEntries[numRight] = item;	++numRight;    }    vec_t rVec(rightBp, rightLen);    union_bp(rCursor, page, dummyPred, dummyPred, rVec, dummy, false);    gist_predcursor_t lCursor;    for (i = 0; i <= best; ++i) {	int item = which[i].itemNo;	assert(item >= 0 && item < itemCnt);	lCursor.add(pcursor.elems[item].key, pcursor.elems[item].keyLen);    }    vec_t lVec(leftBp, leftLen);    union_bp(lCursor, page, dummyPred, dummyPred, lVec, dummy, false);    delete [] which;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -