Exemplo n.º 1
0
  RTreeLoad(String[] args) {
    try {
      if (args.length != 4) {
        System.err.println(
            "Usage: RTreeLoad input_file tree_file capacity query_type [intersection | 10NN].");
        System.exit(-1);
      }

      LineNumberReader lr = null;

      try {
        lr = new LineNumberReader(new FileReader(args[0]));
      } catch (FileNotFoundException e) {
        System.err.println("Cannot open data file " + args[0] + ".");
        System.exit(-1);
      }

      // Create a disk based storage manager.
      PropertySet ps = new PropertySet();

      Boolean b = new Boolean(true);
      ps.setProperty("Overwrite", b);
      // overwrite the file if it exists.

      ps.setProperty("FileName", args[1]);
      // .idx and .dat extensions will be added.

      Integer i = new Integer(4096);
      ps.setProperty("PageSize", i);
      // specify the page size. Since the index may also contain user defined data
      // there is no way to know how big a single node may become. The storage manager
      // will use multiple pages per node if needed. Off course this will slow down performance.

      IStorageManager diskfile = new DiskStorageManager(ps);

      IBuffer file = new RandomEvictionsBuffer(diskfile, 10, false);
      // applies a main memory random buffer on top of the persistent storage manager
      // (LRU buffer, etc can be created the same way).

      // Create a new, empty, RTree with dimensionality 2, minimum load 70%, using "file" as
      // the StorageManager and the RSTAR splitting policy.
      PropertySet ps2 = new PropertySet();

      Double f = new Double(0.7);
      ps2.setProperty("FillFactor", f);

      i = new Integer(args[2]);
      ps2.setProperty("IndexCapacity", i);
      ps2.setProperty("LeafCapacity", i);
      // Index capacity and leaf capacity may be different.

      i = new Integer(2);
      ps2.setProperty("Dimension", i);

      ISpatialIndex tree = new RTree(ps2, file);

      int count = 0;
      int indexIO = 0;
      int leafIO = 0;
      int id, op;
      double x1, x2, y1, y2;
      double[] f1 = new double[2];
      double[] f2 = new double[2];

      long start = System.currentTimeMillis();
      String line = lr.readLine();

      while (line != null) {
        StringTokenizer st = new StringTokenizer(line);
        op = new Integer(st.nextToken()).intValue();
        id = new Integer(st.nextToken()).intValue();
        x1 = new Double(st.nextToken()).doubleValue();
        y1 = new Double(st.nextToken()).doubleValue();
        x2 = new Double(st.nextToken()).doubleValue();
        y2 = new Double(st.nextToken()).doubleValue();

        if (op == 0) {
          // delete

          f1[0] = x1;
          f1[1] = y1;
          f2[0] = x2;
          f2[1] = y2;
          Region r = new Region(f1, f2);

          if (tree.deleteData(r, id) == false) {
            System.err.println("Cannot delete id: " + id + " , count: " + count + ".");
            System.exit(-1);
          }
        } else if (op == 1) {
          // insert

          f1[0] = x1;
          f1[1] = y1;
          f2[0] = x2;
          f2[1] = y2;
          Region r = new Region(f1, f2);

          String data = r.toString();
          // associate some data with this region. I will use a string that represents the
          // region itself, as an example.
          // NOTE: It is not necessary to associate any data here. A null pointer can be used. In
          // that
          // case you should store the data externally. The index will provide the data IDs of
          // the answers to any query, which can be used to access the actual data from the external
          // storage (e.g. a hash table or a database table, etc.).
          // Storing the data in the index is convinient and in case a clustered storage manager is
          // provided (one that stores any node in consecutive pages) performance will improve
          // substantially,
          // since disk accesses will be mostly sequential. On the other hand, the index will need
          // to
          // manipulate the data, resulting in larger overhead. If you use a main memory storage
          // manager,
          // storing the data externally is highly recommended (clustering has no effect).
          // A clustered storage manager is NOT provided yet.
          // Also you will have to take care of converting you data to and from binary format, since
          // only
          // array of bytes can be inserted in the index (see RTree::Node::load and
          // RTree::Node::store for
          // an example of how to do that).

          // tree.insertData(data.getBytes(), r, id);

          tree.insertData(null, r, id);
          // example of passing a null pointer as the associated data.
        } else if (op == 2) {
          // query

          f1[0] = x1;
          f1[1] = y1;
          f2[0] = x2;
          f2[1] = y2;

          MyVisitor vis = new MyVisitor();

          if (args[3].equals("intersection")) {
            Region r = new Region(f1, f2);
            tree.intersectionQuery(r, vis);
            // this will find all data that intersect with the query range.
          } else if (args[3].equals("10NN")) {
            Point p = new Point(f1);
            tree.nearestNeighborQuery(10, p, vis);
            // this will find the 10 nearest neighbors.
          } else {
            System.err.println("Unknown query type.");
            System.exit(-1);
          }
        }

        if ((count % 1000) == 0) System.err.println(count);

        count++;
        line = lr.readLine();
      }

      long end = System.currentTimeMillis();

      System.err.println("Operations: " + count);
      System.err.println(tree);
      System.err.println("Minutes: " + ((end - start) / 1000.0f) / 60.0f);

      // since we created a new RTree, the PropertySet that was used to initialize the structure
      // now contains the IndexIdentifier property, which can be used later to reuse the index.
      // (Remember that multiple indices may reside in the same storage manager at the same time
      //  and every one is accessed using its unique IndexIdentifier).
      Integer indexID = (Integer) ps2.getProperty("IndexIdentifier");
      System.err.println("Index ID: " + indexID);

      boolean ret = tree.isIndexValid();
      if (ret == false) System.err.println("Structure is INVALID!");

      // flush all pending changes to persistent storage (needed since Java might not call finalize
      // when JVM exits).
      tree.flush();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }