1 /******************************************************************************
2  * Project:  libspatialindex - A C++ library for spatial indexing
3  * Author:   Marios Hadjieleftheriou, mhadji@gmail.com
4  ******************************************************************************
5  * Copyright (c) 2002, Marios Hadjieleftheriou
6  *
7  * All rights reserved.
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a
10  * copy of this software and associated documentation files (the "Software"),
11  * to deal in the Software without restriction, including without limitation
12  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13  * and/or sell copies of the Software, and to permit persons to whom the
14  * Software is furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included
17  * in all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  * DEALINGS IN THE SOFTWARE.
26 ******************************************************************************/
27 
28 // NOTE: Please read README.txt before browsing this code.
29 
30 // include library header file.
31 #include <spatialindex/SpatialIndex.h>
32 
33 using namespace SpatialIndex;
34 
35 #define INSERT 1
36 #define DELETE 0
37 #define QUERY 2
38 
39 class MyDataStream : public IDataStream
40 {
41 public:
MyDataStream(std::string inputFile)42 	MyDataStream(std::string inputFile) : m_pNext(0)
43 	{
44 		m_fin.open(inputFile.c_str());
45 
46 		if (! m_fin)
47 			throw Tools::IllegalArgumentException("Input file not found.");
48 
49 		readNextEntry();
50 	}
51 
~MyDataStream()52 	virtual ~MyDataStream()
53 	{
54 		if (m_pNext != 0) delete m_pNext;
55 	}
56 
getNext()57 	virtual IData* getNext()
58 	{
59 		if (m_pNext == 0) return 0;
60 
61 		RTree::Data* ret = m_pNext;
62 		m_pNext = 0;
63 		readNextEntry();
64 		return ret;
65 	}
66 
hasNext()67 	virtual bool hasNext()
68 	{
69 		return (m_pNext != 0);
70 	}
71 
size()72 	virtual uint32_t size()
73 	{
74 		throw Tools::NotSupportedException("Operation not supported.");
75 	}
76 
rewind()77 	virtual void rewind()
78 	{
79 		if (m_pNext != 0)
80 		{
81 			delete m_pNext;
82 			m_pNext = 0;
83 		}
84 
85 		m_fin.seekg(0, std::ios::beg);
86 		readNextEntry();
87 	}
88 
readNextEntry()89 	void readNextEntry()
90 	{
91 		id_type id;
92 		uint32_t op;
93 		double low[2], high[2];
94 
95 		m_fin >> op >> id >> low[0] >> low[1] >> high[0] >> high[1];
96 
97 		if (m_fin.good())
98 		{
99 			if (op != INSERT)
100 				throw Tools::IllegalArgumentException(
101 					"The data input should contain insertions only."
102 				);
103 
104 			Region r(low, high, 2);
105 			m_pNext = new RTree::Data(sizeof(double), reinterpret_cast<byte*>(low), r, id);
106 				// Associate a bogus data array with every entry for testing purposes.
107 				// Once the data array is given to RTRee:Data a local copy will be created.
108 				// Hence, the input data array can be deleted after this operation if not
109 				// needed anymore.
110 		}
111 	}
112 
113 	std::ifstream m_fin;
114 	RTree::Data* m_pNext;
115 };
116 
main(int argc,char ** argv)117 int main(int argc, char** argv)
118 {
119 	try
120 	{
121 		if (argc != 5)
122 		{
123 			std::cerr << "Usage: " << argv[0] << " input_file tree_file capacity utilization." << std::endl;
124 			return -1;
125 		}
126 
127 		std::string baseName = argv[2];
128 		double utilization = atof(argv[4]);
129 
130 		IStorageManager* diskfile = StorageManager::createNewDiskStorageManager(baseName, 4096);
131 			// Create a new storage manager with the provided base name and a 4K page size.
132 
133 		StorageManager::IBuffer* file = StorageManager::createNewRandomEvictionsBuffer(*diskfile, 10, false);
134 			// applies a main memory random buffer on top of the persistent storage manager
135 			// (LRU buffer, etc can be created the same way).
136 
137 		MyDataStream stream(argv[1]);
138 
139 		// Create and bulk load a new RTree with dimensionality 2, using "file" as
140 		// the StorageManager and the RSTAR splitting policy.
141 		id_type indexIdentifier;
142 		ISpatialIndex* tree = RTree::createAndBulkLoadNewRTree(
143 			RTree::BLM_STR, stream, *file, utilization, atoi(argv[3]), atoi(argv[3]), 2, SpatialIndex::RTree::RV_RSTAR, indexIdentifier);
144 
145 		std::cerr << *tree;
146 		std::cerr << "Buffer hits: " << file->getHits() << std::endl;
147 		std::cerr << "Index ID: " << indexIdentifier << std::endl;
148 
149 		bool ret = tree->isIndexValid();
150 		if (ret == false) std::cerr << "ERROR: Structure is invalid!" << std::endl;
151 		else std::cerr << "The stucture seems O.K." << std::endl;
152 
153 		delete tree;
154 		delete file;
155 		delete diskfile;
156 			// delete the buffer first, then the storage manager
157 			// (otherwise the the buffer will fail trying to write the dirty entries).
158 	}
159 	catch (Tools::Exception& e)
160 	{
161 		std::cerr << "******ERROR******" << std::endl;
162 		std::string s = e.what();
163 		std::cerr << s << std::endl;
164 		return -1;
165 	}
166 
167 	return 0;
168 }
169