Remove a level of indirection when using CellInfo

The CellInfo struct contains a mutex, which interacts poorly
with some standard library containers which may move things around.
As a result we were using std::unique_ptr<CellInfo> in these
containers, but this change gets rid of that level of indirection
as std::unordered_map can construct CellInfo in place and we can
replace the use of std::vector with an array we know will not be
resized.

This improves the performance of the schur eliminator a bit but
also the performance of the block diagonal preconditioners.

Change-Id: If3ccd1273a754d9c5112e6e611ce31066b6b27b5
diff --git a/internal/ceres/block_random_access_diagonal_matrix.cc b/internal/ceres/block_random_access_diagonal_matrix.cc
index 357fc31..643dbf1 100644
--- a/internal/ceres/block_random_access_diagonal_matrix.cc
+++ b/internal/ceres/block_random_access_diagonal_matrix.cc
@@ -52,10 +52,10 @@
     : context_(context), num_threads_(num_threads) {
   m_ = CompressedRowSparseMatrix::CreateBlockDiagonalMatrix(nullptr, blocks);
   double* values = m_->mutable_values();
-  layout_.reserve(blocks.size());
-  for (auto& block : blocks) {
-    layout_.emplace_back(std::make_unique<CellInfo>(values));
-    values += block.size * block.size;
+  layout_ = std::make_unique<CellInfo[]>(blocks.size());
+  for (int i = 0; i < blocks.size(); ++i) {
+    layout_[i].values = values;
+    values += blocks[i].size * blocks[i].size;
   }
 }
 
@@ -77,7 +77,7 @@
   *col = 0;
   *row_stride = stride;
   *col_stride = stride;
-  return layout_[row_block_id].get();
+  return &layout_[row_block_id];
 }
 
 // Assume that the user does not hold any locks on any cell blocks
@@ -91,9 +91,9 @@
   auto& blocks = m_->row_blocks();
   const int num_blocks = blocks.size();
   ParallelFor(context_, 0, num_blocks, num_threads_, [this, blocks](int i) {
-    auto* cell_info = layout_[i].get();
+    auto& cell_info = layout_[i];
     auto& block = blocks[i];
-    MatrixRef b(cell_info->values, block.size, block.size);
+    MatrixRef b(cell_info.values, block.size, block.size);
     b = b.selfadjointView<Eigen::Upper>().llt().solve(
         Matrix::Identity(block.size, block.size));
   });
@@ -107,9 +107,9 @@
   const int num_blocks = blocks.size();
   ParallelFor(
       context_, 0, num_blocks, num_threads_, [this, blocks, x, y](int i) {
-        auto* cell_info = layout_[i].get();
+        auto& cell_info = layout_[i];
         auto& block = blocks[i];
-        ConstMatrixRef b(cell_info->values, block.size, block.size);
+        ConstMatrixRef b(cell_info.values, block.size, block.size);
         VectorRef(y + block.position, block.size).noalias() +=
             b * ConstVectorRef(x + block.position, block.size);
       });