func (fltr *Filter) write(buf []byte, offset int) (int, error) {
	var err error

	// Write name.
	len := copy(buf[offset+1:], fltr.name)
	buf[offset] = byte(len)
	offset += len + 1

	// Write particle type.
	buf[offset] = byte(fltr.begin.GetType())
	offset++

	// Write filter begin.
	len, err = fltr.begin.write(buf, offset+4)
	if err != nil {
		return -1, err
	}
	Buffer.Int32ToBytes(int32(len), buf, offset)
	offset += len + 4

	// Write filter end.
	len, err = fltr.end.write(buf, offset+4)
	if err != nil {
		return -1, err
	}
	Buffer.Int32ToBytes(int32(len), buf, offset)
	offset += len + 4

	return offset, nil
}
// Header write for write operations.
func (cmd *baseCommand) writeHeaderWithPolicy(policy *WritePolicy, readAttr int, writeAttr int, fieldCount int, operationCount int) {
	// Set flags.
	generation := int32(0)
	infoAttr := 0

	switch policy.RecordExistsAction {
	case UPDATE:
	case UPDATE_ONLY:
		infoAttr |= _INFO3_UPDATE_ONLY
	case REPLACE:
		infoAttr |= _INFO3_CREATE_OR_REPLACE
	case REPLACE_ONLY:
		infoAttr |= _INFO3_REPLACE_ONLY
	case CREATE_ONLY:
		writeAttr |= _INFO2_CREATE_ONLY
	}

	switch policy.GenerationPolicy {
	case NONE:
	case EXPECT_GEN_EQUAL:
		generation = policy.Generation
		writeAttr |= _INFO2_GENERATION
	case EXPECT_GEN_GT:
		generation = policy.Generation
		writeAttr |= _INFO2_GENERATION_GT
	}

	if policy.CommitLevel == COMMIT_MASTER {
		infoAttr |= _INFO3_COMMIT_MASTER
	}

	if policy.ConsistencyLevel == CONSISTENCY_ALL {
		readAttr |= _INFO1_CONSISTENCY_ALL
	}

	// Write all header data except total size which must be written last.
	cmd.dataBuffer[8] = _MSG_REMAINING_HEADER_SIZE // Message header length.
	cmd.dataBuffer[9] = byte(readAttr)
	cmd.dataBuffer[10] = byte(writeAttr)
	cmd.dataBuffer[11] = byte(infoAttr)
	cmd.dataBuffer[12] = 0 // unused
	cmd.dataBuffer[13] = 0 // clear the result code
	Buffer.Int32ToBytes(generation, cmd.dataBuffer, 14)
	Buffer.Int32ToBytes(policy.Expiration, cmd.dataBuffer, 18)

	// Initialize timeout. It will be written later.
	cmd.dataBuffer[22] = 0
	cmd.dataBuffer[23] = 0
	cmd.dataBuffer[24] = 0
	cmd.dataBuffer[25] = 0

	Buffer.Int16ToBytes(int16(fieldCount), cmd.dataBuffer, 26)
	Buffer.Int16ToBytes(int16(operationCount), cmd.dataBuffer, 28)
	cmd.dataOffset = int(_MSG_TOTAL_HEADER_SIZE)
}
func (cmd *baseCommand) writeOperationForOperationType(operation OperationType) {
	Buffer.Int32ToBytes(int32(4), cmd.dataBuffer, cmd.dataOffset)
	cmd.dataOffset += 4
	cmd.dataBuffer[cmd.dataOffset] = (byte(operation))
	cmd.dataOffset++
	cmd.dataBuffer[cmd.dataOffset] = (0)
	cmd.dataOffset++
	cmd.dataBuffer[cmd.dataOffset] = (0)
	cmd.dataOffset++
	cmd.dataBuffer[cmd.dataOffset] = (0)
	cmd.dataOffset++
}
func (cmd *baseCommand) writeOperationForBinName(name string, operation OperationType) {
	nameLength := copy(cmd.dataBuffer[(cmd.dataOffset+int(_OPERATION_HEADER_SIZE)):], name)
	Buffer.Int32ToBytes(int32(nameLength+4), cmd.dataBuffer, cmd.dataOffset)
	cmd.dataOffset += 4
	cmd.dataBuffer[cmd.dataOffset] = (byte(operation))
	cmd.dataOffset++
	cmd.dataBuffer[cmd.dataOffset] = (byte(0))
	cmd.dataOffset++
	cmd.dataBuffer[cmd.dataOffset] = (byte(0))
	cmd.dataOffset++
	cmd.dataBuffer[cmd.dataOffset] = (byte(nameLength))
	cmd.dataOffset++
	cmd.dataOffset += nameLength
}
func (cmd *baseCommand) writeOperationForOperation(operation *Operation) error {
	nameLength := copy(cmd.dataBuffer[(cmd.dataOffset+int(_OPERATION_HEADER_SIZE)):], operation.BinName)

	valueLength, err := operation.BinValue.write(cmd.dataBuffer, cmd.dataOffset+int(_OPERATION_HEADER_SIZE)+nameLength)
	if err != nil {
		return err
	}

	Buffer.Int32ToBytes(int32(nameLength+valueLength+4), cmd.dataBuffer, cmd.dataOffset)
	cmd.dataOffset += 4
	cmd.dataBuffer[cmd.dataOffset] = (byte(operation.OpType))
	cmd.dataOffset++
	cmd.dataBuffer[cmd.dataOffset] = (byte(operation.BinValue.GetType()))
	cmd.dataOffset++
	cmd.dataBuffer[cmd.dataOffset] = (byte(0))
	cmd.dataOffset++
	cmd.dataBuffer[cmd.dataOffset] = (byte(nameLength))
	cmd.dataOffset++
	cmd.dataOffset += nameLength + valueLength
	return nil
}
func (pckr *packer) PackInt(valType int, val int32) {
	pckr.buffer.WriteByte(byte(valType))
	pos := pckr.grow(_b4)
	Buffer.Int32ToBytes(val, pckr.buffer.Bytes(), pos)
}
func (acmd *AdminCommand) writeFieldHeader(id byte, size int) {
	Buffer.Int32ToBytes(int32(size+1), acmd.dataBuffer, acmd.dataOffset)
	acmd.dataOffset += 4
	acmd.dataBuffer[acmd.dataOffset] = id
	acmd.dataOffset++
}
func (cmd *baseCommand) execute(ifc command) (err error) {
	policy := ifc.getPolicy(ifc).GetBasePolicy()
	iterations := 0

	// set timeout outside the loop
	limit := time.Now().Add(policy.Timeout)

	// set logging level from internal logger
	scope := log.NewScope(os.Stdout, "aerospike client debug", int(Logger.GetLevel())+1)
	defer scope.Flush()

	scope.Debug("start execute command")

	// Execute command until successful, timed out or maximum iterations have been reached.
	for {
		// too many retries
		if iterations++; (policy.MaxRetries > 0) && (iterations > policy.MaxRetries+1) {
			break
		}

		// Sleep before trying again, after the first iteration
		if iterations > 1 && policy.SleepBetweenRetries > 0 {
			time.Sleep(policy.SleepBetweenRetries)
		}

		// check for command timeout
		if policy.Timeout > 0 && time.Now().After(limit) {
			break
		}

		scope.Debug("getting node")

		node, err := ifc.getNode(ifc)
		if err != nil {
			// Node is currently inactive.  Retry.
			continue
		}

		// set command node, so when you return a record it has the node
		cmd.node = node

		scope.Debugf("getting connection with timeout %v", policy.Timeout)

		cmd.conn, err = node.GetConnection(policy.Timeout)
		if err != nil {
			// Socket connection error has occurred. Decrease health and retry.
			node.DecreaseHealth()

			Logger.Warn("Node " + node.String() + ": " + err.Error())
			continue
		}

		scope.Debug("getting buffer")

		// Draw a buffer from buffer pool, and make sure it will be put back
		cmd.dataBuffer = bufPool.Get()
		// defer bufPool.Put(cmd.dataBuffer)

		// Set command buffer.
		err = ifc.writeBuffer(ifc)
		if err != nil {
			// All runtime exceptions are considered fatal. Do not retry.
			// Close socket to flush out possible garbage. Do not put back in pool.
			node.InvalidateConnection(cmd.conn)
			return err
		}

		// Reset timeout in send buffer (destined for server) and socket.
		Buffer.Int32ToBytes(int32(policy.Timeout/time.Millisecond), cmd.dataBuffer, 22)

		scope.Debug("send command")

		// Send command.
		_, err = cmd.conn.Write(cmd.dataBuffer[:cmd.dataOffset])
		if err != nil {
			// IO errors are considered temporary anomalies. Retry.
			// Close socket to flush out possible garbage. Do not put back in pool.
			node.InvalidateConnection(cmd.conn)

			Logger.Warn("Node " + node.String() + ": " + err.Error())
			// IO error means connection to server node is unhealthy.
			// Reflect cmd status.
			node.DecreaseHealth()
			continue
		}

		scope.Debug("parse result")

		// Parse results.
		err = ifc.parseResult(ifc, cmd.conn)
		if err != nil {
			// close the connection
			// cancelling/closing the batch/multi commands will return an error, which will
			// close the connection to throw away its data and signal the server about the
			// situation. We will not put back the connection in the buffer.
			if KeepConnection(err) {
				// Put connection back in pool.
				node.PutConnection(cmd.conn)
			} else {
				node.InvalidateConnection(cmd.conn)
			}

			scope.Errorf("error: %s", err)

			return err
		}

		scope.Debug("end")

		// Reflect healthy status.
		node.RestoreHealth()

		// Put connection back in pool.
		node.PutConnection(cmd.conn)

		// put back buffer to the pool
		bufPool.Put(cmd.dataBuffer)

		// command has completed successfully.  Exit method.
		return nil

	}

	// execution timeout
	return NewAerospikeError(TIMEOUT, "command execution timed out.")
}
func (cmd *baseCommand) writeFieldHeader(size int, ftype FieldType) {
	Buffer.Int32ToBytes(int32(size+1), cmd.dataBuffer, cmd.dataOffset)
	cmd.dataOffset += 4
	cmd.dataBuffer[cmd.dataOffset] = (byte(ftype))
	cmd.dataOffset++
}