Preserve sparse structure during in-place operations

SparseArrays automatically runs dropzeros! after certain operations: for example,

using SparseArrays
A = spdiagm(ones(3))
println(nnz(A)) # result: 3
A .+= spdiagm(-1 .* ones(3))
println(nnz(A)) # result: 0

How can I prevent this from happening? Basically I want a version of .+= that does not change the sparsity structure of the left side.

The matrix H that I’m looking at is of the form J' * J + c * I, where J has fixed sparsity structure. I could work entry-by-entry: iterate through the columns of J as sparse vectors, compute pairwise dot products, and set the appropriate entries. But it seems like there should be a better way. (I care about performance: J' * J is almost certainly faster than explicitly computing dots products of pairs of columns.)

Iterating thru the columns was too slow. The best workaround I’ve found is the following:

"""Does `A += B' * B`, in a way that preserves the sparse structure of `A`, if possible.
A workaround for the fact that Julia seems to run `dropzeros!(A)` automatically if I just 
do `A .+= B' * B`."""
function A_plus_eq_BT_B!(A::SparseMatrixCSC, B::SparseMatrixCSC)
    M = B' * B
    @assert M.colptr == A.colptr && M.rowval == A.rowval
    A.nzval .+= M.nzval
    return
end

In context, I know that A’s sparse structure will be identical to that of B' * B, so this does the job.