func (bu *bucketUploads) remove(uploadID UploadID) {
	upload := bu.uploads[uploadID]
	delete(bu.uploads, uploadID)
	var uploads []*multipartUpload
	{
		upv, ok := bu.objectIndex.Get(upload.Object)
		if !ok || upv == nil {
			return
		}
		uploads = upv.([]*multipartUpload)
	}
	var found = -1
	var v *multipartUpload
	for found, v = range uploads {
		if v.ID == uploadID {
			break
		}
	}
	if found >= 0 {
		uploads = append(uploads[:found], uploads[found+1:]...)  
	}
	if len(uploads) == 0 {
		bu.objectIndex.Delete(upload.Object)
	} else {
		bu.objectIndex.Set(upload.Object, uploads)
	}
}
remove assumes uploader.mu is acquired
package gofakes3
import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"math/big"
	"net/url"
	"sync"
	"time"
	"github.com/johannesboyne/gofakes3/internal/goskipiter"
	"github.com/ryszard/goskiplist/skiplist"
)
var add1 = new(big.Int).SetInt64(1)
type bucketUploads struct {
	uploads map[UploadID]*multipartUpload
	objectIndex *skiplist.SkipList  
}
func newBucketUploads() *bucketUploads {
	return &bucketUploads{
		uploads:     map[UploadID]*multipartUpload{},
		objectIndex: skiplist.NewStringMap(),
	}
}
func (bu *bucketUploads) add(mpu *multipartUpload) {
	bu.uploads[mpu.ID] = mpu
	uploads, ok := bu.objectIndex.Get(mpu.Object)
	if !ok {
		uploads = []*multipartUpload{mpu}
	} else {
		uploads = append(uploads.([]*multipartUpload), mpu)
	}
	bu.objectIndex.Set(mpu.Object, uploads)
}