summaryrefslogtreecommitdiff
path: root/internal/contentenc/content.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/contentenc/content.go')
-rw-r--r--internal/contentenc/content.go48
1 files changed, 27 insertions, 21 deletions
diff --git a/internal/contentenc/content.go b/internal/contentenc/content.go
index c0f9851..81864d4 100644
--- a/internal/contentenc/content.go
+++ b/internal/contentenc/content.go
@@ -204,33 +204,39 @@ func (be *ContentEnc) DecryptBlock(ciphertext []byte, blockNo uint64, fileID []b
// 2 seems to work ok for now.
const encryptMaxSplit = 2
+// encryptBlocksParallel splits the plaintext into parts and encrypts them
+// in parallel.
+func (be *ContentEnc) encryptBlocksParallel(plaintextBlocks [][]byte, ciphertextBlocks [][]byte, firstBlockNo uint64, fileID []byte) {
+ ncpu := runtime.NumCPU()
+ if ncpu > encryptMaxSplit {
+ ncpu = encryptMaxSplit
+ }
+ groupSize := len(plaintextBlocks) / ncpu
+ var wg sync.WaitGroup
+ for i := 0; i < ncpu; i++ {
+ wg.Add(1)
+ go func(i int) {
+ low := i * groupSize
+ high := (i + 1) * groupSize
+ if i == ncpu-1 {
+ // Last group, pick up any left-over blocks
+ high = len(plaintextBlocks)
+ }
+ be.doEncryptBlocks(plaintextBlocks[low:high], ciphertextBlocks[low:high], firstBlockNo+uint64(low), fileID)
+ wg.Done()
+ }(i)
+ }
+ wg.Wait()
+}
+
// EncryptBlocks is like EncryptBlock but takes multiple plaintext blocks.
// Returns a byte slice from CReqPool - so don't forget to return it
// to the pool.
func (be *ContentEnc) EncryptBlocks(plaintextBlocks [][]byte, firstBlockNo uint64, fileID []byte) []byte {
ciphertextBlocks := make([][]byte, len(plaintextBlocks))
// For large writes, we parallelize encryption.
- if len(plaintextBlocks) >= 32 {
- ncpu := runtime.NumCPU()
- if ncpu > encryptMaxSplit {
- ncpu = encryptMaxSplit
- }
- groupSize := len(plaintextBlocks) / ncpu
- var wg sync.WaitGroup
- for i := 0; i < ncpu; i++ {
- wg.Add(1)
- go func(i int) {
- low := i * groupSize
- high := (i + 1) * groupSize
- if i == ncpu-1 {
- // Last group, pick up any left-over blocks
- high = len(plaintextBlocks)
- }
- be.doEncryptBlocks(plaintextBlocks[low:high], ciphertextBlocks[low:high], firstBlockNo+uint64(low), fileID)
- wg.Done()
- }(i)
- }
- wg.Wait()
+ if len(plaintextBlocks) >= 32 && runtime.NumCPU() >= 2 {
+ be.encryptBlocksParallel(plaintextBlocks, ciphertextBlocks, firstBlockNo, fileID)
} else {
be.doEncryptBlocks(plaintextBlocks, ciphertextBlocks, firstBlockNo, fileID)
}