# A Resilient Large-Scale Trajectory Index for Cloud-Based Moving Object Applications
## 4 Query Processing
### Continuous Range Query  
Continuous Range Query (\(CRQ\)) consists of \(k\) clauses where each clause has \(RQ\) and an indicator for a trajectory-in or trajectory-out. Therefore, when receiving a \(k\)-\(CRQ\ =\{<RQ_{1},flag_{1}>,<RQ_{2},flag_{2}>,\ldots,<RQ_{k},flag_{k}>\}\) on a trajectory set \(T\), RMOI needs to find any \(Traj\in T\) such that  
\[\forall i\in[1,2,\ldots,k],\;Traj_{space}\ \textcircled{\$}\ RQ_{i}\;\;\text{where}\ \ \textcircled{\$}= \begin{cases}Traj_{space}\cap RQ_{i}\colon&( flag_{i}=True)\\ Traj_{space}\cap RQ_{i}=\phi\colon&(flag_{i}=False)\end{cases} \quad. \tag{7}\]  
Algorithm 2 outlines the required steps to process \(k\)-\(CRQ\). First, RMOI traverses the GlobalRMOI based on the spatial property for each \(RQ_{i}\), where \(1\leq i\leq k\). It determines the required _Pids_ and returns two items: an overall set and an array of sets. The overall set contains all the _Pids_ required for all \(RQs\) of \(CRQ\) and is used when initializing the Spark Job to filter undesired RDD partitions. The second item, denoted by ReqPids, is an array of sets, which contains all the required _Pids_ as an individual set for each \(RQ_{i}\). It is used to refine unnecessary LocalRMOI traversal, as shown in Line 8. At Line 5, RMOI identifies any trajectory intersects with any \(RQ_{i}\) by using a transformation MapPartitions, which is running in parallel by the worker nodes on the given RDD partitions. Each engaged worker uses an array of hash sets for each RDD partition to collect the overlapped _Tids_ (i.e., \(Tids\cap RQ_{i}\) without considering the \(flags\) values) and the corresponding clause's id (\(ClauseID\)). The Boolean value of the \(flag\) does not matter at this point because RMOI needs to report all the overlapped _Tids_ to check later on for the trajectory-out of other \(RQs\)' results. It uses a hash set to eliminate duplication among _Tids_ of a particular \(RQ_{i}\) and to speed up searching in the next step. In the case of partial trajectory-preservation, the results from different partitions are returned as lists of 2-tuple of \(Tid\) and \(ClauseID\) and concatenated into a PairRDD\(<Tid,ClauseID>\). At this point, RMOI will finish the local reduction, where it is conducted on the RDD partitions level. After that, RMOI starts the global reduction by using a GroupBy transformation to reduce the PairRDD on _Tids_, Line 27. Finally, RMOI runs a Filter transformation to eliminate any _Tid_ that does not fulfill the \(CRQ\)'s definition, as illustrated in Line 29. The purpose of the \(ClauseID\) during filtration is to indicate that the associated _Tid_ has been tested, and it intersected with \(RQ_{ClauseID}\). In the case of full trajectory-preservation, all the required computations are carried out during the first transformation, Line 5. As seen in Lines 10-23, RMOI picks a set of the resulted _Tids_ where the associated \(flag\) is true. Then, it iterates over the _Tids_ of the picked set to eliminate any _Tid_ that does not fulfill the \(CRQ\)'s definition. Finally, it returns the final result as an RDD of _Tids_ without the need for a global reduction, i.e., GroupBy and Filter transformations.