亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? hnsrtreefileobj1.cpp

?? SR-tree is an index structure for high-dimensional nearest neighbor queries
?? CPP
?? 第 1 頁 / 共 3 頁
字號:
/*
 * HnSRTreeFileObj1.cc (dynamic construction methods)
 * Copyright (C) 1997 Norio Katayama
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA
 *
 * 03/20/96 katayama@rd.nacsis.ac.jp
 * $Id: HnSRTreeFileObj1.cc,v 1.5 2002/09/13 03:50:54 katayama Exp $
 */

#include <math.h>
#include <stdio.h>
#ifndef _MSC_VER
#include <unistd.h>
#include <sys/types.h>
#endif
#include "HnSRTree/HnSRTreeFile.hh"
#include "HnSRTree/HnSRTreeFileObj.hh"
#include "HnSRTree/HnStatistics.hh"

/*
 * Store
 */

void
HnSRTreeFileObj::store(const HnPoint &point, const HnDataItem &dataItem)
{
    if ( point.getDimension() != getDimension() ) {
	HnAbort("mismatch in the dimensions (point: %d, file: %d)",
		point.getDimension(), getDimension());
    }
    if ( dataItem.length() > info.getDataItemSize() ) {
	HnAbort("The size of data item (%d) exceeds the limit (%d).",
		dataItem.length(), info.getDataItemSize());
    }

    reinsertList = new_HnSRTreeReinsertVector();
    reinsertedBlocks = new_HnFTlongVector();

    reinsertList.addElement(new_HnSRTreeReinsert(point, dataItem));

    while ( reinsertList.size() != 0 ) {
	if ( reinsertList[0].getType() == HnSRTreeReinsert::POINT ) {
	    HnPoint point = reinsertList[0].getPoint();
	    HnDataItem dataItem = reinsertList[0].getDataItem();

	    reinsertList.removeElementAt(0);
	    insertPoint(point, dataItem);
	}
	else {
	    long offset = reinsertList[0].getOffset();
	    int level = reinsertList[0].getLevel();

	    reinsertList.removeElementAt(0);
	    insertBlock(offset, level);
	}
    }

    if ( debug ) {
	check();
    }
}

void
HnSRTreeFileObj::insertPoint(const HnPoint &point, const HnDataItem &dataItem)
{
    HnSRTreeStack stack;
    HnSRTreeLeaf leaf;

    stack = chooseLeaf(point);

    leaf = stack.getTopLeaf();

    if ( !leaf.isFull() ) {
	leaf.addElement(point, dataItem);
	writeLeaf(leaf);
	updateCluster(stack);
    }
    else {
	int reinsertCount =
	    (leaf.getCount() + 1) * info.getReinsertFactor() / 100;

	if ( stack.getDepth() == 1 ) {
	    /* leaf is the root node */
	    splitLeaf(stack, point, dataItem);
	}
	else if ( reinsertCount <= 0 ) {
	    /* no entry needs to be reinserted */
	    splitLeaf(stack, point, dataItem);
	}
	else {
	    /* reinsert some of entries */
	    int index = -1;

	    if ( (index = reinsertedBlocks.indexOf(leaf.getOffset())) < 0 ) {
		reinsertedBlocks.addElement(leaf.getOffset());
		reinsertLeaf(stack, point, dataItem);
	    }
	    else {
		reinsertedBlocks.removeElementAt(index);
		splitLeaf(stack, point, dataItem);
	    }
	}
    }
}

void
HnSRTreeFileObj::insertBlock(long offset, int level)
{
    HnSRTreeBlock block = readBlock(offset);
    HnSRTreeCluster cluster;
    HnSRTreeStack stack;
    HnSRTreeNode parent;

    if ( block.isNode() ) {
	HnSRTreeNode node = new_HnSRTreeNode(info, block);
	cluster = node.getCluster();
    }
    else if ( block.isLeaf() ) {
	HnSRTreeLeaf leaf = new_HnSRTreeLeaf(info, block);
	cluster = leaf.getCluster();
    }
    else {
	HnAbort("unexpected block type.");
    }

    stack = chooseNode(cluster.getCentroid(), level);

    parent = stack.getTopNode();

    if ( !parent.isFull() ) {
	parent.addElement(cluster, offset);
	writeNode(parent);
	updateCluster(stack);
    }
    else {
	int reinsertCount =
	    (parent.getCount() + 1) * info.getReinsertFactor() / 100;

	if ( stack.getDepth() == 1 ) {
	    /* parent is the root node */
	    splitNode(stack, cluster, offset);
	}
	else if ( reinsertCount <= 0 ) {
	    /* no entry needs to be reinserted */
	    splitNode(stack, cluster, offset);
	}	    
	else {
	    /* reinsert some of entries */
	    int index = -1;

	    if ( (index = reinsertedBlocks.indexOf(parent.getOffset())) < 0 ) {
		reinsertedBlocks.addElement(parent.getOffset());
		reinsertNode(stack, cluster, offset);
	    }
	    else {
		reinsertedBlocks.removeElementAt(index);
		splitNode(stack, cluster, offset);
	    }
	}
    }
}

HnSRTreeStack
HnSRTreeFileObj::chooseLeaf(const HnPoint &point)
{
    HnSRTreeStack stack = new_HnSRTreeStack();
    HnSRTreeBlock block;
    HnSRTreeNode node;
    HnSRTreeLeaf leaf;
    int index;

    /*
     * NOTE:
     *	    The stack is used for keeping the trace of the access path.
     *	    Cursors indicates which entry is used at each node.
     */

    block = readBlock(info.getRootOffset());

    while ( block.isNode() ) {
	node = new_HnSRTreeNode(info, block);
	index = chooseSubtree(node, point);

	stack.push(node, index);
	block = readBlock(node.getOffsetAt(index));
    }

    leaf = new_HnSRTreeLeaf(info, block);
    stack.push(leaf, -1);

    return stack;
}

int
HnSRTreeFileObj::chooseSubtree(const HnSRTreeNode &node, const HnPoint &point)
{
    struct {
	int index;
	double distance;
    } min, cur;

    min.index = -1;
    min.distance = -1;

    for ( cur.index=0; cur.index<node.getCount(); cur.index++ ) {
	HnSRTreeCluster cluster = node.getClusterAt(cur.index);

	cur.distance = point.getDistance(cluster.getCentroid());

	if ( min.index == -1 ) {
	    min = cur;
	}
	else {
	    if ( cur.distance < min.distance ) {
		min = cur;
	    }
	}
    }

    return min.index;
}

HnSRTreeStack
HnSRTreeFileObj::chooseNode(const HnPoint &centroid, int level)
{
    HnSRTreeStack stack = new_HnSRTreeStack();
    HnSRTreeBlock block;
    HnSRTreeNode node;
    int index;

    /*
     * NOTE:
     *	    The stack is used for keeping the trace of the access path.
     *	    Cursors indicates which entry is used at each node.
     */

    block = readBlock(info.getRootOffset());

    while ( stack.getDepth() != info.getHeight() - level ) {
	node = new_HnSRTreeNode(info, block);
	index = chooseSubtree(node, centroid);

	stack.push(node, index);
	block = readBlock(node.getOffsetAt(index));
    }

    return stack;
}

void
HnSRTreeFileObj::updateCluster(HnSRTreeStack stack)
{
    HnSRTreeCluster cluster;
    HnSRTreeNode parent;
    int cursor;

    if ( stack.getDepth() == 0 ) {
	HnAbort("stack is empty.");
    }

    if ( stack.isTopNode() ) {
	HnSRTreeNode node = stack.getTopNode();
	cluster = node.getCluster();
    }
    else {
	HnSRTreeLeaf leaf = stack.getTopLeaf();
	cluster = leaf.getCluster();
    }
    stack.pop();

    while ( stack.getDepth() > 0 ) {
	parent = stack.getTopNode();
	cursor = stack.getCursor();

	parent.setClusterAt(cluster, cursor);

	cluster = parent.getCluster();

	writeNode(parent);
	stack.pop();
    }
}

/*
 * Reinsert
 */

struct HnSRTreeReinsertionEntry {
    int index;
    double distance;
};

static int
HnSRTreeCompareReinsertionEntries(const void *ptr1, const void *ptr2)
{
    HnSRTreeReinsertionEntry *entry1 = (HnSRTreeReinsertionEntry *)ptr1;
    HnSRTreeReinsertionEntry *entry2 = (HnSRTreeReinsertionEntry *)ptr2;

    if ( entry1->distance == entry2->distance ) {
	return 0;
    }
    else {
	/* entries are compared for descending order */
	if ( entry1->distance < entry2->distance ) {
	    return 1;
	}
	else {
	    return -1;
	}
    }
}

/*
 * Reinsert (leaf)
 */

void
HnSRTreeFileObj::reinsertLeaf(HnSRTreeStack &stack,
			      const HnPoint &newPoint,
			      const HnDataItem &newDataItem)
{
    HnSRTreeLeaf leaf, newLeaf;
    HnPointArray points;
    int i;
    ReinsertFlag *flags;

    leaf = stack.getTopLeaf();

    /* put points into an array */
    points = new_HnPointArray(leaf.getCount() + 1);
    for ( i=0; i<leaf.getCount(); i++ ) {
	points[i] = leaf.getPointAt(i);
    }
    points[i] = newPoint;

    selectPoints(points, &flags);

    newLeaf = new_HnSRTreeLeaf(info, leaf.getOffset());

    for ( i=0; i<leaf.getCount(); i++ ) {
	HnPoint point = leaf.getPointAt(i);
	HnDataItem dataItem = leaf.getDataItemAt(i);

	switch ( flags[i] ) {
	case STAY:
	    newLeaf.addElement(point, dataItem);
	    break;
	case REINSERT:
	    reinsertList.addElement(new_HnSRTreeReinsert(point, dataItem));
	    break;
	default:
	    HnAbort("reinsert flag is incorrectly assigned.");
	}
    }
    switch ( flags[i] ) {
    case STAY:
	newLeaf.addElement(newPoint, newDataItem);
	break;
    case REINSERT:
	reinsertList.addElement(new_HnSRTreeReinsert(newPoint, newDataItem));
	break;
    default:
	HnAbort("reinsert flag is incorrectly assigned.");
    }

    writeLeaf(newLeaf);

    /* replace leaf with newLeaf in the stack */
    stack.pop();
    stack.push(newLeaf);

    updateCluster(stack);
}

void
HnSRTreeFileObj::selectPoints(const HnPointArray &points,
			      ReinsertFlag **flags_return)
{
    static ReinsertFlag *flags = NULL;
    int numPoints = points.length;
    int dimension = info.getDimension();
    int reinsertCount = numPoints * info.getReinsertFactor() / 100;
    HnPoint centroid;
    int i, axis;
    HnSRTreeReinsertionEntry *entries;

    /* initialize flags */
    if ( flags != NULL ) {
	delete[] flags;
    }
    flags = new ReinsertFlag[numPoints];

    for ( i=0; i<numPoints; i++ ) {
	flags[i] = REINSERT_NONE;
    }

    /* calculate centroid */
    centroid = new_HnPoint(dimension);

    for ( axis=0; axis<dimension; axis++ ) {
	double sum = 0;

	for ( i=0; i<numPoints; i++ ) {
	    sum += points[i].getCoordAt(axis);
	}

	centroid.setCoordAt(sum / numPoints, axis);
    }

    /* initialize entries */
    entries = (HnSRTreeReinsertionEntry *)
	HnMalloc(sizeof(HnSRTreeReinsertionEntry) * numPoints);

    for ( i=0; i<numPoints; i++ ) {
	entries[i].index = i;
	entries[i].distance = points[i].getDistance(centroid);
    }

    /* sort points by distance in descent order */
    qsort(entries, numPoints, sizeof(HnSRTreeReinsertionEntry),
	  HnSRTreeCompareReinsertionEntries);

    /* make reinsert flags */
    i=0;
    while ( i<reinsertCount ) {
	flags[entries[i].index] = REINSERT;
	i++;
    }
    while ( i<numPoints ) {
	flags[entries[i].index] = STAY;
	i++;
    }

    if ( debug ) {
	fprintf(stderr, "HnSRTreeFileObj::selectPoints:\n");
	fprintf(stderr, "    REINSERT\n");
	for ( i=0; i<numPoints; i++ ) {
	    if ( flags[i] == REINSERT )
		fprintf(stderr,
			"    points[%d].getDistance(centroid) = %g\n",
			i, points[i].getDistance(centroid));
	}
	fprintf(stderr, "    STAY\n");
	for ( i=0; i<numPoints; i++ ) {
	    if ( flags[i] == STAY )
		fprintf(stderr,
			"    points[%d].getDistance(centroid) = %g\n",
			i, points[i].getDistance(centroid));
	}
    }

    *flags_return = flags;

    HnFree(entries, sizeof(HnSRTreeReinsertionEntry) * numPoints);
}

/*
 * Reinsert (node)
 */

void
HnSRTreeFileObj::reinsertNode(HnSRTreeStack &stack,
			      const HnSRTreeCluster &newCluster,
			      long newOffset)
{
    HnSRTreeNode node, newNode;
    HnSRTreeClusterArray clusters;
    int i, level;
    ReinsertFlag *flags;

    node = stack.getTopNode();
    level = info.getHeight() - stack.getDepth();

    /* put clusters into an array */
    clusters = new_HnSRTreeClusterArray(node.getCount() + 1);
    for ( i=0; i<node.getCount(); i++ ) {
	clusters[i] = node.getClusterAt(i);
    }
    clusters[i] = newCluster;

    /* select clusters */
    selectClusters(clusters, &flags);

    newNode = new_HnSRTreeNode(info, node.getOffset());

    for ( i=0; i<node.getCount(); i++ ) {
	HnSRTreeCluster cluster = node.getClusterAt(i);
	long offset = node.getOffsetAt(i);

	switch ( flags[i] ) {
	case STAY:
	    newNode.addElement(cluster, offset);
	    break;
	case REINSERT:
	    reinsertList.addElement(new_HnSRTreeReinsert(offset, level));
	    break;
	default:
	    HnAbort("reinsert flag is incorrectly assigned.");
	}
    }
    switch ( flags[i] ) {
    case STAY:
	newNode.addElement(newCluster, newOffset);
	break;
    case REINSERT:
	reinsertList.addElement(new_HnSRTreeReinsert(newOffset, level));
	break;
    default:
	HnAbort("reinsert flag is incorrectly assigned.");
    }

    writeNode(newNode);

    /* replace node with newNode in the stack */
    stack.pop();
    stack.push(newNode);

    updateCluster(stack);
}

void
HnSRTreeFileObj::selectClusters(const HnSRTreeClusterArray &clusters,
				ReinsertFlag **flags_return)
{
    static ReinsertFlag *flags = NULL;
    int numClusters = clusters.length;
    int dimension = info.getDimension();

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
另类中文字幕网| 欧美在线观看18| 久久激情综合网| 经典一区二区三区| 韩国成人福利片在线播放| 国产一区二区在线电影| 国产99精品国产| 成人免费视频一区二区| 欧洲精品中文字幕| 日韩欧美一二区| 欧美一区二区三区啪啪| 2024国产精品| 伊人色综合久久天天人手人婷| 国产精品每日更新| 天天影视网天天综合色在线播放| 日本在线不卡视频| 不卡一区二区在线| 成人91在线观看| 日韩美女天天操| 视频一区欧美日韩| 91婷婷韩国欧美一区二区| 欧美日韩国产a| 中文字幕综合网| 亚洲成人资源在线| 色综合久久久久综合体| 亚洲精品在线免费播放| 自拍偷自拍亚洲精品播放| 日韩高清欧美激情| 欧洲精品一区二区三区在线观看| 日韩精品一区二| 午夜成人免费电影| 欧美天堂一区二区三区| 亚洲免费观看高清完整版在线观看 | 不卡视频在线观看| 久久久99久久| 奇米综合一区二区三区精品视频| 欧美性猛片xxxx免费看久爱| 综合自拍亚洲综合图不卡区| 国产精品一区三区| 国产欧美日韩三区| 麻豆91在线观看| 日韩欧美一区电影| 国内精品自线一区二区三区视频| 欧美日韩国产大片| 亚洲午夜精品网| 5858s免费视频成人| 日欧美一区二区| 久久久久97国产精华液好用吗| 国产在线精品一区二区夜色| 日本一区二区视频在线| 91麻豆免费在线观看| 一区二区不卡在线播放 | 人人精品人人爱| 在线免费观看成人短视频| 亚洲一区二区三区爽爽爽爽爽| 91久久精品日日躁夜夜躁欧美| 国产欧美日韩精品在线| 日本韩国欧美一区| 蜜桃免费网站一区二区三区 | 综合久久久久久| 欧美女孩性生活视频| 国产精品一区二区三区99| 亚洲女人****多毛耸耸8| aaa亚洲精品一二三区| 奇米一区二区三区| 一区二区三区精品在线| 国产日韩欧美精品在线| 欧美一三区三区四区免费在线看| 国产一区二区三区在线观看免费| 亚洲国产精品成人久久综合一区| 欧美日韩免费一区二区三区 | 欧美不卡一二三| 色婷婷综合久久久久中文一区二区 | 欧美一级在线免费| 国产一区二区三区四区五区入口| 一区二区三区四区亚洲| 中文一区在线播放| 久久美女艺术照精彩视频福利播放| 欧美日韩国产首页| 欧美性一区二区| 91黄色激情网站| 91在线视频观看| 成人免费毛片aaaaa**| 国产精品资源站在线| 国产在线观看一区二区| 一区二区在线观看免费| 国产精品成人免费| 日韩美女天天操| 欧美日韩国产在线观看| 欧美美女黄视频| 欧美精品成人一区二区三区四区| 欧美无乱码久久久免费午夜一区 | 欧美群妇大交群的观看方式| 91精品办公室少妇高潮对白| 欧美亚洲一区二区在线| 51精品国自产在线| 日韩久久久久久| 久久午夜国产精品| 午夜影视日本亚洲欧洲精品| 国产欧美日韩视频一区二区| 亚洲人成在线播放网站岛国| 日本一区二区电影| 亚洲一区二区三区在线看| 日日噜噜夜夜狠狠视频欧美人| 精品系列免费在线观看| 不卡欧美aaaaa| 制服丝袜日韩国产| 亚洲人成精品久久久久久| 日韩电影在线看| 99久久久久免费精品国产| 日韩精品一区二区在线| 亚洲精品少妇30p| 精品一区二区在线看| 欧美在线色视频| 国产精品传媒入口麻豆| 精品一区二区三区在线观看国产| 日韩和欧美一区二区三区| 麻豆精品在线看| 韩国毛片一区二区三区| 色综合天天综合网国产成人综合天| 欧美电影免费观看完整版| 亚洲国产wwwccc36天堂| 日本精品一区二区三区四区的功能| 日韩欧美成人一区| 日韩精品久久久久久| 欧美精品xxxxbbbb| 午夜精品视频一区| 欧美网站大全在线观看| 亚洲综合成人在线视频| 色94色欧美sute亚洲线路一久| 国产精品久久影院| 欧美优质美女网站| 99久久国产综合色|国产精品| 国产精品99久久久久久似苏梦涵 | 正在播放亚洲一区| 日韩电影在线观看一区| 欧美一区二区女人| 风间由美中文字幕在线看视频国产欧美| 精品美女在线播放| 成人深夜福利app| 亚洲一区二区三区中文字幕在线 | 国产精品美女www爽爽爽| 91亚洲精华国产精华精华液| 亚洲一区日韩精品中文字幕| 91精品久久久久久久久99蜜臂| 日本美女一区二区三区视频| 欧美激情一区二区三区全黄 | 久久久精品2019中文字幕之3| 亚洲欧美一区二区三区孕妇| 欧美体内she精视频| 国产在线播放一区三区四| 亚洲精品成a人| 欧美成人video| 欧美日韩精品欧美日韩精品| 国产精品亚洲一区二区三区在线| 亚洲影院免费观看| 国产日产精品一区| 欧美成人一区二区三区片免费| 91蝌蚪porny九色| 国产美女视频91| 亚洲国产精品久久不卡毛片 | 国产美女视频一区| 蜜桃传媒麻豆第一区在线观看| 一区二区三区在线免费| 国产日韩欧美a| 久久久亚洲午夜电影| 欧美电影精品一区二区| 欧美人妇做爰xxxⅹ性高电影| 一本色道久久综合精品竹菊| 国产传媒一区在线| 国产成+人+日韩+欧美+亚洲| 国产精品18久久久| 大陆成人av片| 不卡av在线免费观看| 99精品视频一区| 欧美伊人精品成人久久综合97| 色菇凉天天综合网| 在线看国产一区| 日韩欧美一级二级| 国产性做久久久久久| 国产精品欧美一区喷水| 一区二区欧美在线观看| 一区二区日韩av| 七七婷婷婷婷精品国产| 激情综合网av| 色噜噜狠狠色综合中国| 在线观看视频欧美| 日韩午夜中文字幕| 亚洲三级在线观看| 韩国成人精品a∨在线观看| www.久久久久久久久| 欧美日韩一区二区欧美激情| 日韩精品一区二区三区视频播放 | 国产 日韩 欧美大片| 欧美日韩一区小说| 国产视频一区二区在线| 亚洲国产综合色| 色伊人久久综合中文字幕| 精品国产亚洲在线| 午夜不卡在线视频|