anchor.diff:              return(Coordinator, Key, Type, Tx, PropertyList, State)
       end.
   
  -%% @doc Check if this partition is ready to proceed with a read.
  --spec pvc_check_time(
  -    partition_id(),
  -    vectorclock_partition:partition_vc(),
  -    vectorclock_partition:partition_vc()
  -) -> ready | {not_ready, non_neg_integer()}.
  -
  -pvc_check_time(Partition, MostRecentVC, VCaggr) ->
  -    MostRecentTime = vectorclock_partition:get_partition_time(Partition, MostRecentVC),
  -    AggregateTime = vectorclock_partition:get_partition_time(Partition, VCaggr),
  -    lager:info("PVC Will wait until MostRecentVC[i] (~p) >= VCaggr[i] (~p)", [MostRecentTime, AggregateTime]),
  -    case MostRecentTime < AggregateTime of
  -        true ->
  -            {not_ready, ?PVC_WAIT_MS};
  -        false ->
  -            ready
  -    end.
  -
   %% @doc check_clock: Compares its local clock with the tx timestamp.
   %%      if local clock is behind, it sleeps the fms until the clock
   %%      catches up. CLOCK-SI: clock skew.
  
positive.code:     ok = pvc_perform_read_internal(Coordinator, IndexNode, Key, Type, Tx, State),
      {noreply, State}.
  
  pvc_perform_read_internal(Coordinator, IndexNode, Key, Type, Tx, State = #state{
      partition = Partition
  }) ->
      %% Sanity check
      pvc = Tx#transaction.transactional_protocol,
  
      {ok, MostRecentVC} = clocksi_vnode:pvc_get_most_recent_vc(IndexNode),
  
      VCaggr = Tx#transaction.pvc_meta#pvc_tx_meta.time#pvc_time.vcaggr,
      %% FIXME(borja): This check is being done too soon. Move
      %% The check only needs to be performed before scanning the CLog.
      %% If this partition was read before (see MaxVersion = case ...),
      %% then we don't need to check the time (see alg. line 29, line 31)
      case pvc_check_time(Partition, MostRecentVC, VCaggr) of
          {not_ready, WaitTime} ->
              lager:info("PVC Partition not ready, will wait ~p ms", [WaitTime]),
              erlang:send_after(WaitTime, self(), {pvc_perform_read_cast, Coordinator, IndexNode, Key, Type, Tx}),
              ok;
          ready ->
              ok = perform_read_internal(Coordinator, Key, Type, Tx, [], State)
      end.
  
  -spec pvc_perform_read(pid() | {fsm, pid()}, key(), type(), vectorclock_partition:partition_vc(), #state{}) -> ok.
  pvc_perform_read(Coordinator, Key, Type, MaxVC, #state{mat_state=MatState}) ->
      lager:info("PVC read will use MaxVC ~p", [dict:to_list(MaxVC)]),
      case materializer_vnode:pvc_read(pvc, Key, Type, MaxVC, MatState) of
          {error, Reason} ->
              reply_to_coordinator(Coordinator, {error, Reason});
  
          {ok, Snapshot, CommitVC} ->
              Value = Type:value(Snapshot),
              lager:info("PVC read Got snapshot ~p at time ~p", [Snapshot, dict:to_list(CommitVC)]),
              CoordReturn = {pvc_readreturn, {Key, Value, CommitVC, MaxVC}},
  
              %% TODO(borja): Check when is this triggered
              ServerReturn = {ok, Value},
              reply_to_coordinator(Coordinator, CoordReturn, ServerReturn)
      end.
  
  %% @doc Scan the log for the maximum aggregate time that will be used for a read
  
  -spec pvc_find_maxvc(index_node(), log_id(), #transaction{}) -> {ok, vectorclock_partition:partition_vc()} | {error, reason()}.
  pvc_find_maxvc(IndexNode, LogId, #transaction{
      %% Sanity check
      transactional_protocol = pvc,
  
negative.code:             end
      end.
  
  %% @doc Given a key and a version vector clock, get the appropiate snapshot
  %%
  %%      It will scan the materializer for the specific snapshot, and reply
  %%      to the coordinator the value of that snapshot, along with the commit
  %%      vector clock time of that snapshot.
  %%
  -spec pvc_perform_read(
      {fsm, pid()} | pid(),
      key(),
      type(),
      vectorclock_partition:partition_vc(),
      #state{}
  ) -> ok.
  
  pvc_perform_read(Coordinator, Key, Type, MaxVC, #state{mat_state=MatState}) ->
      lager:info("PVC read will use MaxVC ~p", [dict:to_list(MaxVC)]),
      case materializer_vnode:pvc_read(pvc, Key, Type, MaxVC, MatState) of
          {error, Reason} ->
              reply_to_coordinator(Coordinator, {error, Reason});
  
          {ok, Snapshot, CommitVC} ->
              Value = Type:value(Snapshot),
              lager:info("PVC read Got snapshot ~p at time ~p", [Snapshot, dict:to_list(CommitVC)]),
              CoordReturn = {pvc_readreturn, {Key, Value, CommitVC, MaxVC}},
  
              %% TODO(borja): Check when is this triggered
              ServerReturn = {ok, Value},
              reply_to_coordinator(Coordinator, CoordReturn, ServerReturn)
      end.
  
  perform_read_internal(Coordinator, Key, Type, Tx, [], State = #state{
      partition=Partition,
  