All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bigdata.service.geospatial.ZOrderIndexBigMinAdvancer Maven / Gradle / Ivy

Go to download

Blazegraph(TM) DB Core Platform. It contains all Blazegraph DB dependencies other than Blueprints.

There is a newer version: 2.1.4
Show newest version
/*

Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.

Contact:
     SYSTAP, LLC DBA Blazegraph
     2501 Calvert ST NW #106
     Washington, DC 20008
     [email protected]

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.

This program 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
/*
 * Created on Sep 9, 2015
 */

package com.bigdata.service.geospatial;

import java.util.NoSuchElementException;

import org.apache.log4j.Logger;

import com.bigdata.btree.ITuple;
import com.bigdata.btree.KeyOutOfRangeException;
import com.bigdata.btree.filter.Advancer;
import com.bigdata.btree.keys.IKeyBuilder;
import com.bigdata.btree.keys.KeyBuilder;
import com.bigdata.rdf.internal.IV;
import com.bigdata.rdf.internal.IVUtility;
import com.bigdata.rdf.internal.impl.extensions.GeoSpatialLiteralExtension;
import com.bigdata.rdf.internal.impl.literal.LiteralExtensionIV;
import com.bigdata.rdf.model.BigdataLiteral;
import com.bigdata.rdf.model.BigdataValue;
import com.bigdata.rdf.spo.SPO;

/**
 * Advances the cursor to the next zOrderKey that is greater or equal than the
 * first point in the next region. Note that this next key is not necessarily a
 * hit (but, depending on the data) this might be a miss again.
 * 
 * @author Bryan Thompson
 */
public class ZOrderIndexBigMinAdvancer extends Advancer {

   private static final long serialVersionUID = -6438977707376228799L;

   private static final transient Logger log = Logger
         .getLogger(ZOrderIndexBigMinAdvancer.class);
   
   final protected static boolean DEBUG = log.isDebugEnabled();
   
   // Search min (upper left) byte array as z-order string (no leading zero)
   private final byte[] searchMinZOrder;

   // Search max (lower right) byte array as z-order string (no leading zero)
   private final byte[] searchMaxZOrder;

   // the position within the index in which we find the zOrderComponent
   private final int zOrderComponentPos;
   
   // the GeoSpatialLiteralExtension object
   private final GeoSpatialLiteralExtension litExt;

   private final ZOrderRangeScanUtil rangeScanUtil;
   
   // counters object for statistics
   private final GeoSpatialCounters geoSpatialCounters;
   
   private transient IKeyBuilder keyBuilder;

   public ZOrderIndexBigMinAdvancer(
      final byte[] searchMinZOrder, /* the minimum search key (top left) */
      final byte[] searchMaxZOrder, /* the maximum search key (bottom right) */
      final GeoSpatialLiteralExtension litExt,
      final int zOrderComponentPos /* position of the zOrder in the index */,
      final GeoSpatialCounters geoSpatialCounters) {

      this.litExt = litExt;
      this.searchMinZOrder = litExt.unpadLeadingZero(searchMinZOrder);
      // this.seachMinLong = litExt.fromZOrderByteArray(this.searchMinZOrder);
      
      this.searchMaxZOrder = litExt.unpadLeadingZero(searchMaxZOrder);
      // this.seachMaxLong = litExt.fromZOrderByteArray(this.searchMaxZOrder);
      
      this.zOrderComponentPos = zOrderComponentPos;
      this.geoSpatialCounters = geoSpatialCounters;

      this.rangeScanUtil = 
         new ZOrderRangeScanUtil(
            this.searchMinZOrder, this.searchMaxZOrder, litExt.getNumDimensions());
      
   }
   
   
   @SuppressWarnings("rawtypes")
   @Override
   protected void advance(final ITuple tuple) {

      if (keyBuilder == null) {
         keyBuilder = KeyBuilder.newInstance();
      }
      
      // iterate unless tuple in range is found or we reached the end
      ITuple curTuple = tuple; 
      while(curTuple!=null) {
         
         if (DEBUG) {
            log.debug("Advancor visiting tuple:    " + curTuple);
         }
         
         final long rangeCheckCalStart = System.nanoTime();
         
         final byte[] key = curTuple.getKey();
   
         keyBuilder.reset();
   
         // decode components up to (and including) the z-order string
         final IV[] ivs = IVUtility.decode(key,zOrderComponentPos+1);
         
         // encode everything up to (and excluding) the z-order component "as is"
         for (int i=0; i zOrderIv = 
            (LiteralExtensionIV)ivs[ivs.length-1];
         
         // current record (aka dividing record) as unsigned
         final byte[] dividingRecord = 
            litExt.toZOrderByteArray(zOrderIv.getDelegate());

         final boolean inRange = rangeScanUtil.isInSearchRange(dividingRecord);

         final long rangeCheckCalEnd = System.nanoTime();
         geoSpatialCounters.addRangeCheckCalculationTime(rangeCheckCalEnd-rangeCheckCalStart);
   
         if (!inRange) {

            // this is a miss
            geoSpatialCounters.registerZOrderIndexMiss();
            
            long bigMinCalStart = System.nanoTime();
            
            if (log.isDebugEnabled()) {
               log.debug("-> tuple " + curTuple + " not in range");
            }

            // calculate bigmin over the z-order component
            final byte[] bigMin = rangeScanUtil.calculateBigMin(dividingRecord);
            
            // pad a zero
            final LiteralExtensionIV bigMinIv = litExt.createIVFromZOrderByteArray(bigMin);
            IVUtility.encode(keyBuilder, bigMinIv);
   
            final long bigMinCalEnd = System.nanoTime();
            geoSpatialCounters.addBigMinCalculationTime(bigMinCalEnd-bigMinCalStart);
            
            // advance to the specified key ...
            try {
               if (log.isDebugEnabled()) {
                  log.debug("-> advancing to bigmin: " + bigMinIv);
               }

               ITuple next = src.seek(keyBuilder.getKey());
                     
               // ... or the next higher one
               if (next==null) {
                  next = src.next(); 
               }
      
               // continue iterate
               curTuple = next;

            }  catch (NoSuchElementException e) {
     
               throw new KeyOutOfRangeException("Advancer out of search range");
               
            }
            
         } else {
            
            geoSpatialCounters.registerZOrderIndexHit();
            return;
         }
      }

   }
   

   
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy