예제 #1
0
static bool FindEdges (const TRI_edge_direction_e direction,
                       TRI_multi_pointer_t* idx,
                       TRI_vector_pointer_t* result,
                       TRI_edge_header_t* entry,
                       const int matchType) {
  TRI_vector_pointer_t found;
  TRI_edge_header_t* edge;

  entry->_flags = TRI_LookupFlagsEdge(direction);
  found = TRI_LookupByKeyMultiPointer(TRI_UNKNOWN_MEM_ZONE, idx, entry);

  if (found._length > 0) {
    size_t i;

    if (result->_capacity == 0) {
      int res;

      // if result vector is still empty and we have results, re-init the
      // result vector to a "good" size. this will save later reallocations
      res = TRI_InitVectorPointer2(result, TRI_UNKNOWN_MEM_ZONE, found._length);
      if (res != TRI_ERROR_NO_ERROR) {
        TRI_DestroyVectorPointer(&found);
        TRI_set_errno(res);

        return false;
      }
    }

    // add all results found
    for (i = 0;  i < found._length;  ++i) {
      edge = (TRI_edge_header_t*) found._buffer[i];

      // the following queries will use the following sequences of matchTypes:
      // inEdges(): 1, 2,  outEdges(): 1, 2,  edges(): 1, 3

      // if matchType is 1, we'll return all found edges without further filtering
      //
      // if matchType is 2 (inEdges or outEdges query), the direction is reversed.
      // We'll exclude all self-reflexive edges now (we already got them in iteration 1),
      // and alsoexclude all unidirectional edges
      //
      // if matchType is 3, the direction is also reversed. We'll exclude all
      // self-reflexive edges now (we already got them in iteration 1)

      if (matchType > 1) {
        // if the edge is self-reflexive, we have already found it in iteration 1
        // we must skip it here, otherwise we would produce duplicates
        if (IsReflexive(edge)) {
          continue;
        }
      }

      TRI_PushBackVectorPointer(result, CONST_CAST(edge->_mptr));
    }
  }


  TRI_DestroyVectorPointer(&found);

  return true;
}
예제 #2
0
static bool FindEdges (const TRI_edge_direction_e direction,
                       TRI_edge_index_t* idx,
                       TRI_vector_pointer_t* result,
                       TRI_edge_header_t* entry,
                       const int matchType) {
  TRI_vector_pointer_t found;

  if (direction == TRI_EDGE_OUT) {
    found = TRI_LookupByKeyMultiPointer(TRI_UNKNOWN_MEM_ZONE, 
                                        &idx->_edges_from, 
                                        entry);
  }
  else if (direction == TRI_EDGE_IN) {
    found = TRI_LookupByKeyMultiPointer(TRI_UNKNOWN_MEM_ZONE, 
                                        &idx->_edges_to, 
                                        entry);
  }
  else {
    assert(false);   // TRI_EDGE_ANY not supported here
  }

  if (found._length > 0) {
    size_t i;

    if (result->_capacity == 0) {
      int res;

      // if result vector is still empty and we have results, re-init the
      // result vector to a "good" size. this will save later reallocations
      res = TRI_InitVectorPointer2(result, TRI_UNKNOWN_MEM_ZONE, found._length);
      if (res != TRI_ERROR_NO_ERROR) {
        TRI_DestroyVectorPointer(&found);
        TRI_set_errno(res);

        return false;
      }
    }

    // add all results found
    for (i = 0;  i < found._length;  ++i) {
      TRI_doc_mptr_t* edge = (TRI_doc_mptr_t*) found._buffer[i];

      // the following queries will use the following sequences of matchTypes:
      // inEdges(): 1,  outEdges(): 1,  edges(): 1, 3

      // if matchType is 1, we'll return all found edges without filtering
      // We'll exclude all loop edges now (we already got them in iteration 1),
      // and alsoexclude all unidirectional edges
      //
      // if matchType is 3, the direction is also reversed. We'll exclude all
      // loop edges now (we already got them in iteration 1)

      if (matchType > 1) {
        
        // if the edge is a loop, we have already found it in iteration 1
        // we must skip it here, otherwise we would produce duplicates
        if (IsReflexive(edge)) {
          continue;
        }
      }
      
      TRI_PushBackVectorPointer(result, CONST_CAST(edge));

    }
  }

  TRI_DestroyVectorPointer(&found);

  return true;
}