Exemple #1
0
func (self *CoreWorkload) getFieldLengthGenerator(p Properties) (g.IntegerGenerator, error) {
	var fieldLengthGenerator g.IntegerGenerator
	fieldLengthDistribution := p.GetDefault(PropertyFieldLengthDistribution, PropertyFieldLengthDistributionDefault)
	propStr := p.GetDefault(PropertyFieldLength, PropertyFieldCountDefault)
	fieldLength, err := strconv.ParseInt(propStr, 0, 64)
	if err != nil {
		return nil, err
	}
	fieldLengthHistogramFile := p.GetDefault(PropertyFieldLengthHistogramFile, PropertyFieldLengthHistogramFileDefault)
	switch fieldLengthDistribution {
	case "constant":
		fieldLengthGenerator = g.NewConstantIntegerGenerator(fieldLength)
	case "uniform":
		fieldLengthGenerator = g.NewUniformIntegerGenerator(1, fieldLength)
	case "zipfian":
		fieldLengthGenerator = g.NewZipfianGeneratorByInterval(1, fieldLength-1)
	case "histogram":
		fieldLengthGenerator, err = g.NewHistogramGeneratorFromFile(fieldLengthHistogramFile)
		if err != nil {
			return nil, err
		}
	default:
		return nil, g.NewErrorf("unknown field length distribution %s", fieldLengthDistribution)
	}
	return fieldLengthGenerator, nil
}
Exemple #2
0
// Initialize the scenario.
// Called once, in the main routine, before any operations are started.
func (self *CoreWorkload) Init(p Properties) error {
	table := p.GetDefault(PropertyTableName, PropertyTableNameDefault)

	propStr := p.GetDefault(PropertyFieldCount, PropertyFieldCountDefault)
	fieldCount, err := strconv.ParseInt(propStr, 0, 64)
	if err != nil {
		return err
	}
	fieldPrefix := p.GetDefault(PropertyFieldPrefix, PropertyFieldPrefixDefault)
	fieldNames := make([]string, 0, fieldCount)
	for i := int64(0); i < fieldCount; i++ {
		fieldNames = append(fieldNames, fmt.Sprintf("%s%d", fieldPrefix, i))
	}
	fieldLengthGenerator, err := self.getFieldLengthGenerator(p)
	if err != nil {
		return err
	}

	propStr = p.GetDefault(PropertyReadProportion, PropertyReadProportionDefault)
	readProportion, err := strconv.ParseFloat(propStr, 64)
	if err != nil {
		return err
	}
	propStr = p.GetDefault(PropertyUpdateProportion, PropertyUpdateProportionDefault)
	updateProportion, err := strconv.ParseFloat(propStr, 64)
	if err != nil {
		return err
	}
	propStr = p.GetDefault(PropertyInsertProportion, PropertyInsertProportionDefault)
	insertProportion, err := strconv.ParseFloat(propStr, 64)
	if err != nil {
		return err
	}
	propStr = p.GetDefault(PropertyScanProportion, PropertyScanProportionDefault)
	scanProportion, err := strconv.ParseFloat(propStr, 64)
	if err != nil {
		return err
	}
	propStr = p.GetDefault(PropertyReadModifyWriteProportion, PropertyReadModifyWriteProportionDefault)
	readModifyWriteProportion, err := strconv.ParseFloat(propStr, 64)
	if err != nil {
		return err
	}
	propStr = p.GetDefault(PropertyRecordCount, PropertyRecordCountDefault)
	recordCount, err := strconv.ParseInt(propStr, 0, 64)
	if err != nil {
		return err
	}
	if recordCount == 0 {
		recordCount = math.MaxInt32
	}
	requestDistrib := p.GetDefault(PropertyRequestDistribution, PropertyRequestDistributionDefault)
	propStr = p.GetDefault(PropertyMaxScanLength, PropertyMaxScanLengthDefault)
	maxScanLength, err := strconv.ParseInt(propStr, 0, 64)
	if err != nil {
		return err
	}
	scanLengthDistrib := p.GetDefault(PropertyScanLengthDistribution, PropertyScanLengthDistributionDefault)
	propStr = p.GetDefault(PropertyInsertStart, PropertyInsertStartDefault)
	insertStart, err := strconv.ParseInt(propStr, 0, 64)
	if err != nil {
		return err
	}
	propStr = p.GetDefault(PropertyReadAllFields, PropertyReadAllFieldsDefault)
	readAllFields, err := strconv.ParseBool(propStr)
	if err != nil {
		return err
	}
	propStr = p.GetDefault(PropertyWriteAllFields, PropertyWriteAllFieldsDefault)
	writeAllFields, err := strconv.ParseBool(propStr)
	if err != nil {
		return err
	}
	propStr = p.GetDefault(PropertyDataIntegrity, PropertyDataIntegrityDefault)
	dataIntegrity, err := strconv.ParseBool(propStr)
	if err != nil {
		return err
	}
	propStr = p.GetDefault(PropertyFieldLengthDistribution, PropertyFieldLengthDistributionDefault)
	isConstant := (propStr == "constant")
	// Confirm that fieldLengthGenerator returns a constant if data integrity check requested.
	if dataIntegrity && isConstant {
		return g.NewErrorf("must have constant field size to check data integrity")
	}
	propStr = p.GetDefault(PropertyInsertOrder, PropertyInsertOrderDefault)
	var orderedInserts bool
	var keyChooser g.IntegerGenerator
	if propStr == "hashed" {
		orderedInserts = false
	} else if requestDistrib == "exponential" {
		propStr = p.GetDefault(PropertyExponentialPercentile, PropertyExponentialPercentileDefault)
		percentile, err := strconv.ParseFloat(propStr, 64)
		if err != nil {
			return err
		}
		propStr = p.GetDefault(PropertyExponentialFraction, PropertyExponentialFractionDefault)
		fraction, err := strconv.ParseFloat(propStr, 64)
		if err != nil {
			return err
		}
		keyChooser = g.NewExponentialGenerator(percentile, float64(recordCount)*fraction)
	} else {
		orderedInserts = true
	}

	keyPrefix := p.GetDefault(PropertyKeyPrefix, PropertyKeyPrefixDefault)
	keySequence := g.NewCounterGenerator(insertStart)
	operationChooser := g.NewDiscreteGenerator()

	if readProportion > 0 {
		operationChooser.AddValue(readProportion, "READ")
	}
	if updateProportion > 0 {
		operationChooser.AddValue(updateProportion, "UPDATE")
	}
	if insertProportion > 0 {
		operationChooser.AddValue(insertProportion, "INSERT")
	}
	if scanProportion > 0 {
		operationChooser.AddValue(scanProportion, "SCAN")
	}
	if readModifyWriteProportion > 0 {
		operationChooser.AddValue(readModifyWriteProportion, "READMODIFYWRITE")
	}

	transactionInsertKeySequence := g.NewAcknowledgedCounterGenerator(recordCount)
	switch requestDistrib {
	case "uniform":
		keyChooser = g.NewUniformIntegerGenerator(0, recordCount-1)
	case "zipfian":
		// It does this by generating a random "next key" in part by
		// taking the modulus over the number of keys.
		// If the number of keys changes, this would shift the modulus,
		// and we don't want that to change which keys are popular
		// so we'll actually construct the scrambled zipfian generator
		// with a keyspace that is larger than exists at the beginning
		// of the test. That is, we'll predict the number of inserts, and
		// tell the scrambled zipfian generator the number of existing keys
		// plus the number of predicted keys as the total keyspace.
		// Then, if the generator picks a key that hasn't been inserted yet,
		// will just ignore it and pick another key. This way, the size of
		// the keyspace doesn't change from the prespective of the scrambled
		// zipfian generator.
		propStr = p.GetDefault(PropertyOperationCount, "")
		opCount, err := strconv.ParseInt(propStr, 0, 64)
		if err != nil {
			return err
		}
		// 2.0 is fudge factor
		expectedNewKeys := int64(float64(opCount) * insertProportion * 2.0)
		keyChooser = g.NewScrambledZipfianGeneratorByItems(recordCount + expectedNewKeys)
	case "latest":
		keyChooser = g.NewSkewedLatestGenerator(transactionInsertKeySequence.CounterGenerator)
	case "hotspot":
		propStr = p.GetDefault(HotspotDataFraction, HotspotDataFractionDefault)
		hotSetFraction, err := strconv.ParseFloat(propStr, 64)
		if err != nil {
			return err
		}
		propStr = p.GetDefault(HotspotOpnFraction, HotspotOpnFractionDefault)
		hotOpnFraction, err := strconv.ParseFloat(propStr, 64)
		if err != nil {
			return err
		}
		keyChooser = g.NewHotspotIntegerGenerator(0, recordCount-1, hotSetFraction, hotOpnFraction)
	default:
		return g.NewErrorf("unknown request distribution %s", requestDistrib)
	}

	fieldChooser := g.NewUniformIntegerGenerator(0, fieldCount-1)
	var scanLengthChooser g.IntegerGenerator
	switch scanLengthDistrib {
	case "uniform":
		scanLengthChooser = g.NewUniformIntegerGenerator(1, maxScanLength)
	case "zipfian":
		scanLengthChooser = g.NewZipfianGeneratorByInterval(1, maxScanLength)
	default:
		return g.NewErrorf("distribution %s not allowed for scan length", scanLengthDistrib)
	}

	propStr = p.GetDefault(InsertionRetryLimit, InsertionRetryLimitDefault)
	insertionRetryLimit, err := strconv.ParseInt(propStr, 0, 64)
	if err != nil {
		return err
	}
	propStr = p.GetDefault(InsertionRetryInterval, InsertionRetryIntervalDefault)
	insertionRetryInterval, err := strconv.ParseInt(propStr, 0, 64)
	if err != nil {
		return err
	}

	// set all fields
	self.table = table
	self.fieldCount = fieldCount
	self.fieldNames = fieldNames
	self.fieldLengthGenerator = fieldLengthGenerator
	self.readAllFields = readAllFields
	self.writeAllFields = writeAllFields
	self.dataIntegrity = dataIntegrity
	self.keyPrefix = keyPrefix
	self.keySequence = keySequence
	self.operationChooser = operationChooser
	self.keyChooser = keyChooser
	self.fieldChooser = fieldChooser
	self.transactionInsertKeySequence = transactionInsertKeySequence
	self.scanLengthChooser = scanLengthChooser
	self.orderedInserts = orderedInserts
	self.recordCount = recordCount
	self.insertionRetryLimit = insertionRetryLimit
	self.insertionRetryInterval = insertionRetryInterval
	return nil
}