summaryrefslogtreecommitdiffstats
path: root/simple/simple-transport/src/main/java/org/simpleframework/transport/reactor/ActionSet.java
diff options
context:
space:
mode:
Diffstat (limited to 'simple/simple-transport/src/main/java/org/simpleframework/transport/reactor/ActionSet.java')
-rw-r--r--simple/simple-transport/src/main/java/org/simpleframework/transport/reactor/ActionSet.java269
1 files changed, 269 insertions, 0 deletions
diff --git a/simple/simple-transport/src/main/java/org/simpleframework/transport/reactor/ActionSet.java b/simple/simple-transport/src/main/java/org/simpleframework/transport/reactor/ActionSet.java
new file mode 100644
index 0000000..adc4ef7
--- /dev/null
+++ b/simple/simple-transport/src/main/java/org/simpleframework/transport/reactor/ActionSet.java
@@ -0,0 +1,269 @@
+/*
+ * ActionSet.java February 2013
+ *
+ * Copyright (C) 2013, Niall Gallagher <niallg@users.sf.net>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package org.simpleframework.transport.reactor;
+
+import static java.nio.channels.SelectionKey.OP_ACCEPT;
+import static java.nio.channels.SelectionKey.OP_CONNECT;
+import static java.nio.channels.SelectionKey.OP_READ;
+import static java.nio.channels.SelectionKey.OP_WRITE;
+
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+
+/**
+ * The <code>ActionSet</code> object represents a set of actions that
+ * are associated with a particular selection key. Here the set
+ * stores an <code>Action</code> for each of the interested operation
+ * types. In some situations a single action may be interested in
+ * several operations which must be remembered by the set.
+ *
+ * @author Niall Gallagher
+ */
+class ActionSet {
+
+ /**
+ * This is the selection key associated with the action set.
+ */
+ private final SelectionKey key;
+
+ /**
+ * This contains the the actions indexed by operation type.
+ */
+ private final Action[] set;
+
+ /**
+ * Constructor for the <code>ActionSet</code> object. This is
+ * used to create a set for storing actions keyed by operation
+ * type. Only one action is kept per operation type.
+ *
+ * @param key this is the associated selection key
+ */
+ public ActionSet(SelectionKey key) {
+ this.set = new Action[4];
+ this.key = key;
+ }
+
+ /**
+ * This provides the selection key associated with the action set.
+ * For each ready operation on the selection key the set contains
+ * an action that can be executed.
+ *
+ * @return this provides the selection key for this action set
+ */
+ public SelectionKey key() {
+ return key;
+ }
+
+ /**
+ * This provides the channel associated with the action set. This
+ * is the channel that is registered for selection using the
+ * interested operations for the set.
+ *
+ * @return this returns the selectable channel for the action set
+ */
+ public SelectableChannel channel() {
+ return key.channel();
+ }
+
+ /**
+ * This provides an iterator of the actions that exist within the
+ * action set. Regardless of whether a single action is interested
+ * is several operations this will return an iteration of unique
+ * actions. Modifications to the iterator do not affect the set.
+ *
+ * @return this returns an iterator of unique actions for the set
+ */
+ public Action[] list() {
+ Action[] actions = new Action[4];
+ int count = 0;
+
+ for(Action action : set) {
+ if(action != null) {
+ actions[count++] = action;
+ }
+ }
+ return copyOf(actions, count);
+ }
+
+ /**
+ * This is sued to acquire all actions that match the currently
+ * ready operations of the key. All actions returned by this will
+ * be executed and the interest will typically be removed.
+ *
+ * @return returns the array of ready operations for the set
+ */
+ public Action[] ready() {
+ int ready = key.readyOps();
+
+ if(ready != 0) {
+ return get(ready);
+ }
+ return new Action[]{};
+ }
+
+ /**
+ * This is used to attach an action to the set for a specific
+ * interest bitmask. If the bitmask contains several operations
+ * then the action is registered for each individual operation.
+ *
+ * @param action this is the action that is to be attached
+ * @param interest this is the interest for the action
+ */
+ public void attach(Action action) {
+ int interest = action.getInterest();
+
+ if((interest | OP_READ) == interest) {
+ set[0] = action;
+ }
+ if((interest | OP_WRITE) == interest) {
+ set[1] = action;
+ }
+ if((interest | OP_ACCEPT) == interest) {
+ set[2] = action;
+ }
+ if((interest | OP_CONNECT) == interest) {
+ set[3] = action;
+ }
+ }
+
+ /**
+ * This is used to remove interest from the set. Removal of
+ * interest from the set is performed by registering a null for
+ * the interest operation.
+ *
+ * @param interest this is the interest to be removed
+ */
+ public Action[] remove(int interest) {
+ Action[] actions = get(interest);
+
+ if((interest | OP_READ) == interest) {
+ set[0] = null;
+ }
+ if((interest | OP_WRITE) == interest) {
+ set[1] = null;
+ }
+ if((interest | OP_ACCEPT) == interest) {
+ set[2] = null;
+ }
+ if((interest | OP_CONNECT) == interest) {
+ set[3] = null;
+ }
+ return actions;
+ }
+
+ /**
+ * This is used to acquire the actions that match the bitmask of
+ * interest operations. If there are no actions representing the
+ * interest required an empty array will be returned.
+ *
+ * @param interest this is the interest to acquire actions for
+ *
+ * @return this will return an array of actions for the interest
+ */
+ public Action[] get(int interest) {
+ Action[] actions = new Action[4];
+ int count = 0;
+
+ if((interest | OP_READ) == interest) {
+ if(set[0] != null) {
+ actions[count++] = set[0];
+ }
+ }
+ if((interest | OP_WRITE) == interest) {
+ if(set[1] != null) {
+ actions[count++] = set[1];
+ }
+ }
+ if((interest | OP_ACCEPT) == interest) {
+ if(set[2] != null) {
+ actions[count++] = set[2];
+ }
+ }
+ if((interest | OP_CONNECT) == interest) {
+ if(set[3] != null) {
+ actions[count++] = set[3];
+ }
+ }
+ return copyOf(actions, count);
+ }
+
+ /**
+ * This is used to create a copy of the specified list with only
+ * the first few non null values. This ensures we can keep the
+ * internal array immutable and still use arrays.
+ *
+ * @param list this is the list that is to be copied to a new array
+ * @param count this is the number of entries to copy from the list
+ *
+ * @return a copy of the original list up to the specified count
+ */
+ private Action[] copyOf(Action[] list, int count) {
+ Action[] copy = new Action[count];
+
+ for(int i = 0; i < count; i++) {
+ copy[i] = list[i];
+ }
+ return copy;
+ }
+
+ /**
+ * This is used to acquire the operations that this is interested
+ * in. If there are currently no registered actions then this will
+ * return zero. Interest is represented by non-null actions only.
+ *
+ * @return this returns the interested operations for this
+ */
+ public int interest() {
+ int interest = 0;
+
+ if(set[0] != null) {
+ interest |= OP_READ;
+ }
+ if(set[1] != null) {
+ interest |= OP_WRITE;
+ }
+ if(set[2] != null) {
+ interest |= OP_ACCEPT;
+ }
+ if(set[3] != null) {
+ interest |= OP_CONNECT;
+ }
+ return interest;
+ }
+
+ /**
+ * This is used to clear all interest from the set. This will
+ * basically clear out any actions that have been registered with
+ * the set. After invocation the iterator will be empty.
+ */
+ public void clear() {
+ set[0] = set[1] =
+ set[2] = set[3] = null;
+ }
+
+ /**
+ * This is used to cancel the <code>SelectionKey</code> associated
+ * with the action set. Canceling the key in this manner ensures
+ * it is not returned in further selection operations.
+ */
+ public void cancel() {
+ key.cancel();
+ }
+}
+ \ No newline at end of file