Worst-Case Optimal Join Algorithms