github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/lib/objectserver/memory/add.go (about)

     1  package memory
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"io"
     8  
     9  	"github.com/Cloud-Foundations/Dominator/lib/hash"
    10  	"github.com/Cloud-Foundations/Dominator/lib/objectcache"
    11  )
    12  
    13  func (objSrv *ObjectServer) addObject(reader io.Reader, length uint64,
    14  	expectedHash *hash.Hash) (hash.Hash, bool, error) {
    15  	hashVal, data, err := objectcache.ReadObject(reader, length, expectedHash)
    16  	if err != nil {
    17  		return hashVal, false, err
    18  	}
    19  	// Check for existing object and collision.
    20  	objSrv.rwLock.RLock()
    21  	oldData, ok := objSrv.objectMap[hashVal]
    22  	objSrv.rwLock.RUnlock()
    23  	if ok {
    24  		if err := collisionCheck(data, oldData); err != nil {
    25  			return hashVal, false, errors.New(
    26  				"collision detected: " + err.Error())
    27  		}
    28  		// No collision and no error: it's the same object. Go home early.
    29  		return hashVal, false, nil
    30  	}
    31  	objSrv.rwLock.Lock()
    32  	objSrv.objectMap[hashVal] = data
    33  	objSrv.rwLock.Unlock()
    34  	return hashVal, true, nil
    35  }
    36  
    37  func collisionCheck(data []byte, oldData []byte) error {
    38  	if len(data) != len(oldData) {
    39  		return fmt.Errorf("length mismatch. Data=%d, existing object=%d",
    40  			len(data), len(oldData))
    41  	}
    42  	if !bytes.Equal(data, oldData) {
    43  		return errors.New("content mismatch")
    44  	}
    45  	return nil
    46  }