func (s *DynamoStore) UpdateRoot(current, last hash.Hash) bool { s.requestWg.Wait() putArgs := dynamodb.PutItemInput{ TableName: aws.String(s.table), Item: map[string]*dynamodb.AttributeValue{ refAttr: {B: s.rootKey}, chunkAttr: {B: current.DigestSlice()}, compAttr: {S: aws.String(noneValue)}, }, } if last.IsEmpty() { putArgs.ConditionExpression = aws.String(valueNotExistsExpression) } else { putArgs.ConditionExpression = aws.String(valueEqualsExpression) putArgs.ExpressionAttributeValues = map[string]*dynamodb.AttributeValue{ ":prev": {B: last.DigestSlice()}, } } _, err := s.ddbsvc.PutItem(&putArgs) if err != nil { if awsErr, ok := err.(awserr.Error); ok { if awsErr.Code() == "ConditionalCheckFailedException" { return false } d.Chk.NoError(awsErr) } else { d.Chk.NoError(err) } } return true }
func (s *DynamoStore) makeNamespacedKey(h hash.Hash) []byte { // This is semantically `return append(s.namespace, r.DigestSlice()...)`, but it seemed like we'd be doing this a LOT, and we know how much space we're going to need anyway. So, pre-allocate a slice and then copy into it. hashSlice := h.DigestSlice() key := make([]byte, s.namespaceLen+len(hashSlice)) copy(key, s.namespace) copy(key[s.namespaceLen:], hashSlice) return key }
// toDbKey takes a refHeight and a hash and returns a binary key suitable for use with LevelDB. The default sort order used by LevelDB ensures that these keys (and their associated values) will be iterated in ref-height order. func toDbKey(refHeight uint64, hash hash.Hash) []byte { digest := hash.DigestSlice() buf := bytes.NewBuffer(make([]byte, 0, uint64Size+binary.Size(digest))) err := binary.Write(buf, binary.BigEndian, refHeight) d.Chk.NoError(err) err = binary.Write(buf, binary.BigEndian, digest) d.Chk.NoError(err) return buf.Bytes() }
func (l *LevelDBStore) toChunkKey(r hash.Hash) []byte { digest := r.DigestSlice() out := make([]byte, len(l.chunkPrefix), len(l.chunkPrefix)+len(digest)) copy(out, l.chunkPrefix) return append(out, digest...) }