All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glassfish.grizzly.memcached.MemcachedRequest Maven / Gradle / Ivy

There is a newer version: 1.3.18
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package org.glassfish.grizzly.memcached;

import org.glassfish.grizzly.Buffer;
import org.glassfish.grizzly.Cacheable;
import org.glassfish.grizzly.ThreadCache;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Memcached request
 * 

* {@code response} and {@code responseStatus} will be set by the filter when the response will be received. * And the filter will notify {@code notify} instance after it will complete the processing for the received message. * * @author Bongjae Chang */ public class MemcachedRequest { private static final int MAX_KEY_LENGTH = 250; // 250bytes private static final int MAX_VALUE_LENGTH = 1024 * 1024; // 1M private final boolean hasExtras; private final boolean hasKey; private final boolean hasValue; private final CommandOpcodes op; private final boolean noReply; private final int opaque; private final long cas; private final byte dataType; private final short vBucketId; // extras and body private final Integer flags; private final Long delta; private final Long initial; private final Integer expirationInSecs; private final Integer verbosity; private final BufferWrapper.BufferType originKeyType; private final Object originKey; private final Buffer key; private final Buffer value; final AtomicBoolean disposed = new AtomicBoolean(); final CountDownLatch notify = new CountDownLatch(1); Object response; Boolean isError; private MemcachedRequest(final Builder builder) { this.hasExtras = builder.hasExtras; this.hasKey = builder.hasKey; this.hasValue = builder.hasValue; this.op = builder.op; this.noReply = builder.noReply; this.opaque = builder.opaque; this.cas = builder.cas; this.dataType = builder.dataType; this.vBucketId = builder.vBucketId; this.flags = builder.flags; this.delta = builder.delta; this.initial = builder.initial; this.expirationInSecs = builder.expirationInSecs; this.verbosity = builder.verbosity; this.originKeyType = builder.originKeyType; this.originKey = builder.originKey; this.key = builder.key; this.value = builder.value; } public boolean hasExtras() { return hasExtras; } public boolean hasKey() { return hasKey; } public boolean hasValue() { return hasValue; } public CommandOpcodes getOp() { return op; } public boolean isNoReply() { return noReply; } public int getOpaque() { return opaque; } public long getCas() { return cas; } public byte getDataType() { return dataType; } public short getvBucketId() { return vBucketId; } public Integer getFlags() { return flags; } public Long getDelta() { return delta; } public Long getInitial() { return initial; } public Integer getExpirationInSecs() { return expirationInSecs; } public Integer getVerbosity() { return verbosity; } public BufferWrapper.BufferType getOriginKeyType() { return originKeyType; } public Object getOriginKey() { return originKey; } public Buffer getKey() { return key; } public Buffer getValue() { return value; } public byte getExtrasLength() { if (!hasExtras) { return 0; } else { return (byte) (((flags != null ? 4 : 0) + (delta != null ? 8 : 0) + (initial != null ? 8 : 0) + (expirationInSecs != null ? 4 : 0) + (verbosity != null ? 4 : 0)) & 0x7f); } } public void fillExtras(final Buffer buffer) { if (!hasExtras || buffer == null) { return; } switch (op) { case Set: case SetQ: case Add: case AddQ: case Replace: case ReplaceQ: if (flags != null) { buffer.putInt(flags); } if (expirationInSecs != null) { buffer.putInt(expirationInSecs); } break; case Increment: case IncrementQ: case Decrement: case DecrementQ: if (delta != null) { buffer.putLong(delta); } if (initial != null) { buffer.putLong(initial); } if (expirationInSecs != null) { buffer.putInt(expirationInSecs); } break; case Verbosity: if (verbosity != null) { buffer.putInt(verbosity); } break; case GAT: case GATQ: case Touch: case Flush: case FlushQ: if (expirationInSecs != null) { buffer.putInt(expirationInSecs); } break; default: break; } } public short getKeyLength() { return hasKey && key != null ? (short) (key.remaining() & 0x7fff) : 0; } public int getValueLength() { return hasValue && value != null ? value.remaining() : 0; } public static class Builder implements Cacheable { private static final ThreadCache.CachedTypeIndex CACHE_IDX = ThreadCache.obtainIndex(Builder.class, 16); private boolean hasExtras; private boolean hasKey; private boolean hasValue; private CommandOpcodes op; private boolean noReply; private int opaque; private long cas; private byte dataType; private short vBucketId; // extras and body private Integer flags; private Long delta; private Long initial; private Integer expirationInSecs; private Integer verbosity; private BufferWrapper.BufferType originKeyType; private Object originKey; private Buffer key; private Buffer value; public static Builder create(final boolean hasExtras, final boolean hasKey, final boolean hasValue) { final Builder builder = ThreadCache.takeFromCache(CACHE_IDX); if (builder != null) { builder.initialize(hasExtras, hasKey, hasValue); return builder; } return new Builder(hasExtras, hasKey, hasValue); } private Builder(final boolean hasExtras, final boolean hasKey, final boolean hasValue) { initialize(hasExtras, hasKey, hasValue); } private void initialize(final boolean hasExtras, final boolean hasKey, final boolean hasValue) { this.hasExtras = hasExtras; this.hasKey = hasKey; this.hasValue = hasValue; } public Builder op(final CommandOpcodes op) { this.op = op; return this; } public Builder noReply(final boolean noReply) { this.noReply = noReply; return this; } public Builder opaque(final int opaque) { this.opaque = opaque; return this; } public Builder cas(final long cas) { this.cas = cas; return this; } public Builder dataType(final byte dataType) { this.dataType = dataType; return this; } public Builder vBucketId(final short vBucketId) { this.vBucketId = vBucketId; return this; } public Builder flags(final Integer flags) { this.flags = flags; return this; } public Builder delta(final Long delta) { this.delta = delta; return this; } public Builder initial(final Long initial) { this.initial = initial; return this; } public Builder expirationInSecs(final Integer expirationInSecs) throws IllegalArgumentException { if (expirationInSecs < 0) { throw new IllegalArgumentException("expiration must be greater than 0"); } this.expirationInSecs = expirationInSecs; return this; } public Builder verbosity(final Integer verbosity) { this.verbosity = verbosity; return this; } public Builder originKeyType(final BufferWrapper.BufferType originKeyType) throws IllegalArgumentException { if (originKeyType != null) { this.originKeyType = originKeyType; } return this; } public Builder originKey(final Object originKey) throws IllegalArgumentException { if (originKey != null) { this.originKey = originKey; } return this; } public Builder key(final Buffer key) throws IllegalArgumentException { if (key != null) { final int keyLen = key.remaining(); if (keyLen > MAX_KEY_LENGTH) { throw new IllegalArgumentException("key length is in excess of " + MAX_KEY_LENGTH + "bytes. keyLen=" + keyLen + "bytes"); } this.key = key; } return this; } public Builder value(final Buffer value) throws IllegalArgumentException { if (value != null) { final int valueLen = value.remaining(); if (valueLen > MAX_VALUE_LENGTH) { throw new IllegalArgumentException("value length is in excess of " + MAX_VALUE_LENGTH + "bytes. valueLen=" + valueLen + "bytes"); } this.value = value; } return this; } public MemcachedRequest build() { return new MemcachedRequest(this); } @Override public void recycle() { hasExtras = false; hasKey = false; hasValue = false; op = null; noReply = false; opaque = 0; cas = 0; dataType = 0; vBucketId = 0; flags = null; delta = null; initial = null; expirationInSecs = null; verbosity = null; originKey = null; key = null; value = null; ThreadCache.putToCache(CACHE_IDX, this); } } @Override public String toString() { return "MemcachedRequest{" + "hasExtras=" + hasExtras + ", hasKey=" + hasKey + ", hasValue=" + hasValue + ", op=" + op + ", noReply=" + noReply + ", opaque=" + opaque + ", cas=" + cas + ", dataType=" + dataType + ", vBucketId=" + vBucketId + ", flags=" + flags + ", delta=" + delta + ", initial=" + initial + ", expirationInSecs=" + expirationInSecs + ", verbosity=" + verbosity + ", originKeyType=" + originKeyType + ", originKey=" + originKey + ", key=" + key + ", response=" + response + ", isError=" + isError + ", value=" + value + '}'; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy