diff options
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.java | 269 |
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 |