TupleIdSequence* TupleStorageSubBlock::getMatchesForPredicate(const Predicate *pred) const {
  TupleIdSequence *matches = new TupleIdSequence();

  tuple_id max_tid = getMaxTupleID();

  if (pred == NULL) {
    if (isPacked()) {
      for (tuple_id tid = 0; tid <= max_tid; ++tid) {
        matches->append(tid);
      }
    } else {
      for (tuple_id tid = 0; tid <= max_tid; ++tid) {
        if (hasTupleWithID(tid)) {
          matches->append(tid);
        }
      }
    }
  } else {
    if (isPacked()) {
      for (tuple_id tid = 0; tid <= max_tid; ++tid) {
        if (pred->matchesForSingleTuple(*this, tid)) {
          matches->append(tid);
        }
      }
    } else {
      for (tuple_id tid = 0; tid <= max_tid; ++tid) {
        if (hasTupleWithID(tid) && (pred->matchesForSingleTuple(*this, tid))) {
          matches->append(tid);
        }
      }
    }
  }

  return matches;
}
tuple_id TupleStorageSubBlock::numTuples() const {
  if (isEmpty()) {
    return 0;
  } else if (isPacked()) {
    return getMaxTupleID() + 1;
  } else {
    // WARNING: This branch is O(N). Subclasses should override wherever possible.
    tuple_id count = 0;
    for (tuple_id tid = 0; tid <= getMaxTupleID(); ++tid) {
      if (hasTupleWithID(tid)) {
        ++count;
      }
    }
    // Should have at least one tuple, otherwise isEmpty() would have been true.
    DEBUG_ASSERT(count > 0);
    return count;
  }
}
TupleIdSequence* TupleStorageSubBlock::getExistenceMap() const {
  const tuple_id max_tid = getMaxTupleID();
  TupleIdSequence *existing_tuples = new TupleIdSequence(max_tid + 1);

  if (isPacked()) {
    existing_tuples->setRange(0, max_tid + 1, true);
  } else {
    for (tuple_id tid = 0; tid <= max_tid; ++tid) {
      if (hasTupleWithID(tid)) {
        existing_tuples->set(tid, true);
      }
    }
  }

  return existing_tuples;
}
OrderedTupleIdSequence* TupleStorageSubBlock::getExistenceList() const {
  const tuple_id max_tid = getMaxTupleID();
  OrderedTupleIdSequence *existence_list = new OrderedTupleIdSequence();
  existence_list->reserve(numTuples());

  if (isPacked()) {
    for (tuple_id tid = 0; tid <= max_tid; ++tid) {
      existence_list->emplace_back(tid);
    }
  } else {
    for (tuple_id tid = 0; tid <= max_tid; ++tid) {
      if (hasTupleWithID(tid)) {
        existence_list->emplace_back(tid);
      }
    }
  }

  return existence_list;
}