{
+
+ private final int index;
+
+ private final String name;
+
+ private final AttributeInitFunction function;
+
+ AttributeKey(int index, String name, AttributeInitFunction function) {
+ this.name = name;
+ this.index = index;
+ this.function = function;
+ }
+
+ public int getIndex() {
+ return index;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public AttributeInitFunction getFunction() {
+ return function;
+ }
+
+ @Override
+ public String toString() {
+ return "name: " + name + ", index: " + index;
+ }
+
+}
diff --git a/firenio-core/src/main/java/com/firenio/collection/AttributeMap.java b/firenio-core/src/main/java/com/firenio/collection/AttributeMap.java
new file mode 100644
index 000000000..d60515a57
--- /dev/null
+++ b/firenio-core/src/main/java/com/firenio/collection/AttributeMap.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 com.firenio.collection;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * use for static variable, eg:
+ *
+ * static final AttributeKey KEY_NAME = AttributeMap.valueOfKey(Channel.class, "KEY_NAME");
+ *
+ */
+//TODO 考虑多个ChannelContext时,每个Context里Channel存储的数据key不一样,会造成内存浪费
+public abstract class AttributeMap {
+
+ private static final Map, AttributeKeys> INDEX_MAPPING = new ConcurrentHashMap<>();
+
+ private final Object[] attributes;
+
+ private volatile int memoryBarrier = 0;
+
+ public AttributeMap() {
+ AttributeKeys keys = getKeys();
+ if (keys == null) {
+ attributes = null;
+ return;
+ }
+ keys.initialized = true;
+ this.attributes = new Object[keys.getCounter()];
+ for (AttributeKey key : keys.keys.values()) {
+ AttributeInitFunction function = key.getFunction();
+ function.setValue(this, key.getIndex());
+ }
+ }
+
+ public T getAttribute(AttributeKey key) {
+ return (T) getAttribute(key.getIndex());
+ }
+
+ public T getAttributeUnsafe(AttributeKey key) {
+ return (T) getAttributeUnsafe(key.getIndex());
+ }
+
+ public Object getAttribute(int key) {
+ memoryBarrier = 1;
+ return attributes[key];
+ }
+
+ public Object getAttributeUnsafe(int key) {
+ return attributes[key];
+ }
+
+ public void setAttribute(AttributeKey key, Object value) {
+ attributes[key.getIndex()] = value;
+ }
+
+ public void setAttribute(int key, Object value) {
+ memoryBarrier = 1;
+ attributes[key] = value;
+ }
+
+ public void setAttributeUnsafe(int key, Object value) {
+ attributes[key] = value;
+ }
+
+ public static AttributeKeys getKeys(Class clazz) {
+ return INDEX_MAPPING.get(clazz);
+ }
+
+ public static AttributeKey valueOfKey(Class clazz, String name) {
+ return valueOfKey(clazz, name, null);
+ }
+
+ public static AttributeKey valueOfKey(Class clazz, String name, AttributeInitFunction function) {
+ AttributeKeys attributeKeys = INDEX_MAPPING.get(clazz);
+ if (attributeKeys == null) {
+ synchronized (INDEX_MAPPING) {
+ attributeKeys = INDEX_MAPPING.get(clazz);
+ if (attributeKeys == null) {
+ attributeKeys = new AttributeKeys();
+ INDEX_MAPPING.put(clazz, attributeKeys);
+ }
+ }
+ }
+ return attributeKeys.valueOf(name, function);
+ }
+
+ protected int getMemoryBarrier() {
+ return memoryBarrier;
+ }
+
+ protected abstract AttributeKeys getKeys();
+
+ public static class AttributeKeys {
+
+ final Map keys = new HashMap<>();
+ final Map ro_keys = Collections.unmodifiableMap(keys);
+
+ int counter = 0;
+ volatile boolean initialized = false;
+
+ synchronized AttributeKey valueOf(String name, AttributeInitFunction function) {
+ if (initialized) {
+ throw new RuntimeException("incorrect usage, AttributeKey can only be static constant");
+ }
+ if (function == null) {
+ function = NULL_VALUE_ATTRIBUTE_INIT_FUNCTION;
+ }
+ keys.put(name, new AttributeKey(counter++, name, function));
+ return keys.get(name);
+ }
+
+ public Map getKeys() {
+ return ro_keys;
+ }
+
+ public int getCounter() {
+ return counter;
+ }
+
+ }
+
+ public interface AttributeInitFunction {
+
+ void setValue(AttributeMap map, int key);
+
+ }
+
+ static final AttributeInitFunction NULL_VALUE_ATTRIBUTE_INIT_FUNCTION = new AttributeInitFunction() {
+ @Override
+ public void setValue(AttributeMap map, int key) { }
+ };
+
+}
diff --git a/firenio-core/src/main/java/com/firenio/collection/AttributesImpl.java b/firenio-core/src/main/java/com/firenio/collection/AttributesImpl.java
deleted file mode 100644
index d5d6f5f04..000000000
--- a/firenio-core/src/main/java/com/firenio/collection/AttributesImpl.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2015 The FireNio Project
- *
- * 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 com.firenio.collection;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-public class AttributesImpl implements Attributes {
-
- private final Map
*/
private boolean isEnoughSslUnwrap(ByteBuf src) throws SSLException {
- if (src.remaining() < 5) {
+ if (src.readableBytes() < 5) {
return false;
}
- int pos = src.position();
+ int pos = src.readIndex();
// TLS - Check ContentType
int type = src.getUnsignedByte(pos);
if (type < 20 || type > 23) {
@@ -501,14 +535,14 @@ private boolean isEnoughSslUnwrap(ByteBuf src) throws SSLException {
throw NOT_TLS;
}
int len = packetLength + 5;
- if (src.remaining() < len) {
+ if (src.readableBytes() < len) {
return false;
}
if (len > SSL_PACKET_LIMIT) {
throw SSL_PACKET_OVER_LIMIT;
}
- src.markL();
- src.limit(pos + len);
+ src.markWriteIndex();
+ src.writeIndex(pos + len);
return true;
}
@@ -544,16 +578,17 @@ protected void read() throws Exception {
}
private void read_plain() throws Exception {
- ByteBuf src = eventLoop.getReadBuf();
+ final Channel ch = this;
+ final ProtocolCodec codec = this.codec;
+ ByteBuf dst = codec.getPlainReadBuf(eventLoop, ch);
for (; ; ) {
- src.clear();
- read_plain_remain(src);
- if (!read_data(src)) {
+ codec.readPlainRemain(ch, dst);
+ if (!read_data(dst)) {
return;
}
- boolean full = src.isFullLimit();
- accept(src);
- if (!full) {
+ accept(dst);
+ // for epoll et mode
+ if (dst.hasWritableBytes()) {
break;
}
}
@@ -567,78 +602,70 @@ private void read_ssl() throws Exception {
if (!read_data(src)) {
return;
}
- boolean full = src.isFullLimit();
for (; ; ) {
if (isEnoughSslUnwrap(src)) {
ByteBuf res = unwrap(src);
if (res != null) {
accept(res);
}
- src.resetL();
- if (!src.hasRemaining()) {
+ src.resetWriteIndex();
+ if (!src.hasReadableBytes()) {
break;
}
} else {
- if (src.hasRemaining()) {
+ if (src.hasReadableBytes()) {
slice_remain_ssl(src);
}
break;
}
}
- if (!full) {
+ // for epoll et mode
+ if (src.hasWritableBytes()) {
break;
}
}
}
- private boolean read_data(ByteBuf src) {
- int len = native_read();
+ private boolean read_data(ByteBuf dst) {
+ int len = native_read(dst);
if (len < 1) {
if (len == -1) {
Util.close(this);
return false;
}
- store_remain(src.flip());
+ store_remain(dst);
return false;
}
- if (Native.EPOLL_AVAILABLE) {
- src.absLimit(src.absPos() + len);
- src.absPos(0);
- } else {
- src.reverse();
- src.flip();
- }
+ dst.skipWrite(len);
return true;
}
private void store_remain(ByteBuf src) {
- if (src.hasRemaining()) {
+ if (src.hasReadableBytes()) {
if (enable_ssl) {
slice_remain_ssl(src);
} else {
- slice_remain_plain(src);
+ codec.storePlainReadRemain(this, src);
}
}
}
- private void read_plain_remain(ByteBuf dst) {
- ByteBuf remaining_buf = this.plain_remain_buf;
- if (remaining_buf == null) {
- return;
+ protected void read_plain_remain(ByteBuf dst) {
+ ByteBuf remain = this.plain_remain_buf;
+ if (remain != null) {
+ dst.writeBytes(remain);
+ remain.release();
+ this.plain_remain_buf = null;
}
- dst.putBytes(remaining_buf);
- remaining_buf.release();
- this.plain_remain_buf = null;
}
private void read_ssl_remain(ByteBuf dst) {
- ByteBuf remaining_buf = this.ssl_remain_buf;
- if (remaining_buf == null) {
- return;
+ ByteBuf remain = this.ssl_remain_buf;
+ if (remain != null) {
+ dst.writeBytes(remain);
+ remain.release();
+ this.ssl_remain_buf = null;
}
- dst.putBytes(remaining_buf);
- remaining_buf.release();
- this.ssl_remain_buf = null;
}
public void release(Frame frame) {
@@ -716,21 +743,26 @@ private void safe_close() {
release(ssl_remain_buf);
release(plain_remain_buf);
close_channel();
+ channel_establish();
fire_closed();
stop_context();
}
}
+ private void channel_establish() {
+ context.channelEstablish(this, CLOSED_CHANNEL);
+ }
+
abstract void close_channel();
public abstract void setOption(int name, int value) throws IOException;
private ByteBuf slice_remain(ByteBuf src) {
- int remain = src.remaining();
+ int remain = src.readableBytes();
if (remain > 0) {
ByteBuf remaining = alloc().allocate(remain);
- remaining.putBytes(src);
- return remaining.flip();
+ remaining.writeBytes(src);
+ return remaining;
} else {
return null;
}
@@ -744,15 +776,16 @@ private void stop_context() {
//FIXME 部分buf不需要swap
private ByteBuf swap(ByteBufAllocator allocator, ByteBuf buf) {
- ByteBuf out = allocator.allocate(buf.limit());
- out.putBytes(buf);
- return out.flip();
+ // use writeIndex instead of readableBytes because of the buf readIndex always be zero.
+ ByteBuf out = allocator.allocate(buf.writeIndex());
+ out.writeBytes(buf);
+ return out;
}
private void sync_buf(SSLEngineResult result, ByteBuf src, ByteBuf dst) {
//FIXME 同步。。。。。
- src.reverse();
- dst.reverse();
+ src.reverseRead();
+ dst.reverseWrite();
// int bytesConsumed = result.bytesConsumed();
// int bytesProduced = result.bytesProduced();
// if (bytesConsumed > 0) {
@@ -772,9 +805,8 @@ private ByteBuf unwrap(ByteBuf src) throws IOException {
SSLEngine ssl_engine = getSSLEngine();
ByteBuf dst = FastThreadLocal.get().getSslUnwrapBuf();
if (ssl_handshake_finished) {
- dst.clear();
- read_plain_remain(dst);
- SSLEngineResult result = ssl_engine.unwrap(src.nioBuffer(), dst.nioBuffer());
+ codec.readPlainRemain(this, dst);
+ SSLEngineResult result = ssl_engine.unwrap(src.nioReadBuffer(), dst.nioWriteBuffer());
if (result.getStatus() == Status.BUFFER_OVERFLOW) {
//why throw an exception here instead of handle it?
//the getSslUnwrapBuf will return an thread local buffer for unwrap,
@@ -783,12 +815,12 @@ private ByteBuf unwrap(ByteBuf src) throws IOException {
//one EventLoop only have one buffer,but before do unwrap, every channel maybe cached a large
//buffer under SSL_UNWRAP_BUFFER_SIZE,I do not think it is a good way to cached much memory in
//channel, it is not friendly for load much channels in one system, if you get exception here,
- //you may need find a way to limit you frame size,or cache your incomplete frame's data to
+ //you may need find a way to writeIndex you frame size,or cache your incomplete frame's data to
//file system or others way.
throw SSL_UNWRAP_OVER_LIMIT;
}
sync_buf(result, src, dst);
- return dst.flip();
+ return dst;
} else {
for (; ; ) {
dst.clear();
@@ -805,10 +837,20 @@ private ByteBuf unwrap(ByteBuf src) throws IOException {
finish_handshake();
return null;
} else if (handshakeStatus == HandshakeStatus.NEED_UNWRAP) {
- if (src.hasRemaining()) {
+ if (src.hasReadableBytes()) {
continue;
}
return null;
+ } else if (handshakeStatus == HandshakeStatus.NOT_HANDSHAKING) {
+ // NOTICE: this handle may not the NOT_HANDSHAKING expected
+ // NOT_HANDSHAKING is mean closed in wildfly-openssl.unwrap, so do not do finish_handshake
+ // see: https://stackoverflow.com/questions/31149383/difference-between-not-handshaking-and-finished
+ if (SSL_DEBUG) {
+ logger.error("unwrap handle status: NOT_HANDSHAKING({})", this);
+ }
+ throw SSL_UNWRAP_CLOSED;
+ } else if (result.getStatus() == Status.BUFFER_OVERFLOW) {
+ throw SSL_UNWRAP_OVER_LIMIT;
}
}
}
@@ -816,7 +858,7 @@ private ByteBuf unwrap(ByteBuf src) throws IOException {
private static SSLEngineResult unwrap(SSLEngine ssl_engine, ByteBuf src, ByteBuf dst) throws SSLException {
try {
- return ssl_engine.unwrap(src.nioBuffer(), dst.nioBuffer());
+ return ssl_engine.unwrap(src.nioReadBuffer(), dst.nioWriteBuffer());
} catch (SSLException e) {
logger.error(e.getMessage());
debugException(logger, e);
@@ -832,64 +874,68 @@ private ByteBuf wrap(ByteBuf src) throws IOException {
if (ssl_handshake_finished) {
byte sslWrapExt = this.ssl_wrap_ext;
if (sslWrapExt == 0) {
- out = alloc.allocate(guess_wrap_out(src.remaining(), 0xff + 1));
+ out = alloc.allocate(guess_wrap_out(src.readableBytes(), 0xff + 1));
} else {
- out = alloc.allocate(guess_wrap_out(src.remaining(), sslWrapExt & 0xff));
+ out = alloc.allocate(guess_wrap_out(src.readableBytes(), sslWrapExt & 0xff));
}
final int SSL_PACKET_BUFFER_SIZE = SslContext.SSL_PACKET_BUFFER_SIZE;
for (; ; ) {
- SSLEngineResult result = engine.wrap(src.nioBuffer(), out.nioBuffer());
+ SSLEngineResult result = engine.wrap(src.nioReadBuffer(), out.nioWriteBuffer());
Status status = result.getStatus();
sync_buf(result, src, out);
if (status == Status.CLOSED) {
- return out.flip();
+ return out;
} else if (status == Status.BUFFER_OVERFLOW) {
out.expansion(out.capacity() + SSL_PACKET_BUFFER_SIZE);
continue;
} else {
- if (src.hasRemaining()) {
+ if (src.hasReadableBytes()) {
continue;
}
if (sslWrapExt == 0) {
- int srcLen = src.limit();
- int outLen = out.position();
+ int srcLen = src.writeIndex();
+ int outLen = out.readIndex();
int y = ((srcLen + 1) / SSL_PACKET_BUFFER_SIZE) + 1;
int u = ((outLen - srcLen) / y) * 2;
this.ssl_wrap_ext = (byte) u;
}
- return out.flip();
+ return out;
}
}
} else {
ByteBuf dst = FastThreadLocal.get().getSslWrapBuf();
for (; ; ) {
dst.clear();
- SSLEngineResult result = engine.wrap(src.nioBuffer(), dst.nioBuffer());
+ SSLEngineResult result = engine.wrap(src.nioReadBuffer(), dst.nioWriteBuffer());
Status status = result.getStatus();
HandshakeStatus handshakeStatus = result.getHandshakeStatus();
sync_buf(result, src, dst);
if (status == Status.CLOSED) {
- return swap(alloc, dst.flip());
+ return swap(alloc, dst);
}
if (handshakeStatus == HandshakeStatus.NEED_UNWRAP) {
if (out != null) {
- out.putBytes(dst.flip());
- return out.flip();
+ out.writeBytes(dst);
+ return out;
}
- return swap(alloc, dst.flip());
+ return swap(alloc, dst);
} else if (handshakeStatus == HandshakeStatus.NEED_WRAP) {
if (out == null) {
out = alloc.allocate(256);
}
- out.putBytes(dst.flip());
+ out.writeBytes(dst);
continue;
} else if (handshakeStatus == HandshakeStatus.FINISHED) {
finish_handshake();
if (out != null) {
- out.putBytes(dst.flip());
- return out.flip();
+ out.writeBytes(dst);
+ return out;
}
- return swap(alloc, dst.flip());
+ return swap(alloc, dst);
+ } else if (handshakeStatus == HandshakeStatus.NOT_HANDSHAKING) {
+ // NOTICE: this handle may not the NOT_HANDSHAKING expected
+ // It is shouldn't here to have "NOT_HANDSHAKING", because of the ssl is closed?
+ throw SSL_WRAP_CLOSED;
} else if (handshakeStatus == HandshakeStatus.NEED_TASK) {
run_delegated_tasks(engine);
continue;
@@ -911,7 +957,7 @@ public void write(ByteBuf buf) {
ByteBuf old = buf;
try {
buf = wrap(old);
- } catch (Exception e) {
+ } catch (Throwable e) {
debugException(logger, e);
} finally {
old.release();
@@ -942,9 +988,14 @@ public void writeAndFlush(Frame frame) throws Exception {
flush();
}
+ @Override
+ protected AttributeKeys getKeys() {
+ return getKeys(Channel.class);
+ }
+
abstract boolean isInterestWrite();
- abstract int native_read();
+ abstract int native_read(ByteBuf dst);
static final class EpollChannel extends Channel {
@@ -977,9 +1028,9 @@ boolean isInterestWrite() {
}
@Override
- int native_read() {
- ByteBuf buf = eventLoop.getReadBuf();
- return Native.read(fd, eventLoop.getBufAddress() + buf.absPos(), buf.remaining());
+ int native_read(ByteBuf dst) {
+ long address = dst.address() + dst.absWriteIndex();
+ return Native.read(fd, address, dst.writableBytes());
}
@Override
@@ -1010,13 +1061,13 @@ int write() {
}
if (cw_len == 1) {
ByteBuf buf = cwb_array[0];
- long address = buf.address() + buf.absPos();
- int len = Native.write(fd, address, buf.remaining());
+ long address = buf.address() + buf.absReadIndex();
+ int len = Native.write(fd, address, buf.readableBytes());
if (len == -1) {
return -1;
}
- buf.skip(len);
- if (buf.hasRemaining()) {
+ buf.skipRead(len);
+ if (buf.hasReadableBytes()) {
this.current_wbs_len = 1;
this.interestWrite = true;
return 0;
@@ -1034,9 +1085,9 @@ int write() {
long iov_pos = iovec;
for (int i = 0; i < cw_len; i++) {
ByteBuf buf = cwb_array[i];
- Unsafe.putLong(iov_pos, buf.address() + buf.absPos());
+ Unsafe.putLong(iov_pos, buf.address() + buf.absReadIndex());
iov_pos += 8;
- Unsafe.putLong(iov_pos, buf.remaining());
+ Unsafe.putLong(iov_pos, buf.readableBytes());
iov_pos += 8;
}
long len = Native.writev(fd, iovec, cw_len);
@@ -1045,14 +1096,14 @@ int write() {
}
for (int i = 0; i < cw_len; i++) {
ByteBuf buf = cwb_array[i];
- int r = buf.remaining();
+ int r = buf.readableBytes();
if (len < r) {
- buf.skip((int) len);
+ buf.skipRead((int) len);
int remain = cw_len - i;
System.arraycopy(cwb_array, i, cwb_array, 0, remain);
fill_null(cwb_array, remain, cw_len);
this.interestWrite = true;
- this.current_wbs_len = remain;
+ this.current_wbs_len = (byte) remain;
return 0;
} else {
len -= r;
@@ -1133,7 +1184,7 @@ boolean isInterestWrite() {
private int native_write(ByteBuffer src) {
try {
return channel.write(src);
- } catch (IOException e) {
+ } catch (Throwable e) {
return -1;
}
}
@@ -1141,16 +1192,16 @@ private int native_write(ByteBuffer src) {
private long native_write(ByteBuffer[] srcs, int len) {
try {
return channel.write(srcs, 0, len);
- } catch (IOException e) {
+ } catch (Throwable e) {
return -1;
}
}
@Override
- int native_read() {
+ int native_read(ByteBuf dst) {
try {
- return channel.read(eventLoop.getReadBuf().nioBuffer());
- } catch (IOException e) {
+ return channel.read(dst.nioWriteBuffer());
+ } catch (Throwable e) {
return -1;
}
}
@@ -1189,14 +1240,14 @@ int write() {
}
if (cwb_len == 1) {
ByteBuf buf = cwb_array[0];
- ByteBuffer nioBuf = buf.nioBuffer();
+ ByteBuffer nioBuf = buf.nioReadBuffer();
int len = native_write(nioBuf);
if (len == -1) {
return -1;
}
if (nioBuf.hasRemaining()) {
this.current_wbs_len = 1;
- buf.reverse();
+ buf.reverseRead();
interestWrite();
return 0;
} else {
@@ -1210,7 +1261,7 @@ int write() {
}
} else {
for (int i = 0; i < cwb_len; i++) {
- wb_array[i] = cwb_array[i].nioBuffer();
+ wb_array[i] = cwb_array[i].nioReadBuffer();
}
long len = native_write(wb_array, cwb_len);
if (len == -1) {
@@ -1219,13 +1270,13 @@ int write() {
for (int i = 0; i < cwb_len; i++) {
ByteBuf buf = cwb_array[i];
if (wb_array[i].hasRemaining()) {
- buf.reverse();
+ buf.reverseRead();
int remain = cwb_len - i;
System.arraycopy(cwb_array, i, cwb_array, 0, remain);
fill_null(cwb_array, remain, cwb_len);
fill_null(wb_array, i, cwb_len);
interestWrite();
- this.current_wbs_len = remain;
+ this.current_wbs_len = (byte) remain;
return 0;
} else {
wb_array[i] = null;
@@ -1279,7 +1330,7 @@ private static Field OPENSSL_DESTROYED() {
static boolean isOpensslEngineDestroyed(SSLEngine sslEngine) {
try {
- return ((Integer) OPENSSL_DESTROYED.get(sslEngine)) == 1;
+ return ((Integer) OPENSSL_DESTROYED.get(sslEngine)) != 0;
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
diff --git a/firenio-core/src/main/java/com/firenio/component/ChannelAcceptor.java b/firenio-core/src/main/java/com/firenio/component/ChannelAcceptor.java
index 6cc7f69aa..11a2d09f2 100644
--- a/firenio-core/src/main/java/com/firenio/component/ChannelAcceptor.java
+++ b/firenio-core/src/main/java/com/firenio/component/ChannelAcceptor.java
@@ -146,6 +146,11 @@ public synchronized void unbind() {
Util.stop(this);
}
+ @Override
+ public String toString() {
+ return (unsafe instanceof EpollAcceptorUnsafe ? "Epoll" : "Jdk") + "Acceptor(" + getServerAddress() + ")";
+ }
+
static abstract class AcceptorUnsafe implements Closeable {
abstract void bind(NioEventLoop el, ChannelAcceptor a, int backlog) throws IOException;
diff --git a/firenio-core/src/main/java/com/firenio/component/ChannelActiveListener.java b/firenio-core/src/main/java/com/firenio/component/ChannelActiveListener.java
index 152cbb3b5..53fee7631 100644
--- a/firenio-core/src/main/java/com/firenio/component/ChannelActiveListener.java
+++ b/firenio-core/src/main/java/com/firenio/component/ChannelActiveListener.java
@@ -24,7 +24,7 @@ public class ChannelActiveListener implements ChannelIdleListener {
private Logger logger = LoggerFactory.getLogger(getClass());
@Override
- public void channelIdled(Channel ch, long lastIdleTime, long currentTime) {
+ public void channelIdled(Channel ch, long lastIdleTime) {
if (ch.getLastAccessTime() < lastIdleTime) {
logger.info("disconnect(hb) {}", ch);
Util.close(ch);
diff --git a/firenio-core/src/main/java/com/firenio/component/ChannelAliveListener.java b/firenio-core/src/main/java/com/firenio/component/ChannelAliveListener.java
index 2c15dcd27..8185cf173 100644
--- a/firenio-core/src/main/java/com/firenio/component/ChannelAliveListener.java
+++ b/firenio-core/src/main/java/com/firenio/component/ChannelAliveListener.java
@@ -24,7 +24,7 @@ public class ChannelAliveListener implements ChannelIdleListener {
private Logger logger = LoggerFactory.getLogger(getClass());
@Override
- public void channelIdled(Channel ch, long lastIdleTime, long currentTime) {
+ public void channelIdled(Channel ch, long lastIdleTime) {
if (ch.getLastAccessTime() < lastIdleTime && matched(ch)) {
logger.info("disconnect(hb) {}", ch);
Util.close(ch);
diff --git a/firenio-core/src/main/java/com/firenio/component/ChannelConnector.java b/firenio-core/src/main/java/com/firenio/component/ChannelConnector.java
index a238a5a5d..76c2b2847 100644
--- a/firenio-core/src/main/java/com/firenio/component/ChannelConnector.java
+++ b/firenio-core/src/main/java/com/firenio/component/ChannelConnector.java
@@ -19,6 +19,7 @@
import java.io.IOException;
import java.net.InetAddress;
import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import com.firenio.Develop;
@@ -39,12 +40,12 @@
public final class ChannelConnector extends ChannelContext implements Closeable {
private static final Logger logger = LoggerFactory.getLogger(ChannelConnector.class);
- private volatile Callback callback;
- private volatile boolean callback_ed = true;
private Channel ch;
private NioEventLoop eventLoop;
- private volatile DelayedQueue.DelayTask timeoutTask;
private ConnectorUnsafe unsafe;
+ private volatile Callback callback;
+ private volatile boolean callback_ed = true;
+ private volatile DelayedQueue.DelayTask timeoutTask;
public ChannelConnector(int port) {
this("127.0.0.1", port);
@@ -64,11 +65,6 @@ public ChannelConnector(NioEventLoopGroup group, String host, int port) {
if (!group.isSharable() && !group.isRunning()) {
group.setEventLoopSize(1);
}
- if (Native.EPOLL_AVAILABLE) {
- unsafe = new EpollConnectorUnsafe();
- } else {
- unsafe = new JavaConnectorUnsafe();
- }
}
public ChannelConnector(String host, int port) {
@@ -78,9 +74,9 @@ public ChannelConnector(String host, int port) {
@Override
protected void channelEstablish(Channel ch, Throwable ex) {
if (!callback_ed) {
- this.unsafe.channelEstablish(ch, eventLoop, ex);
this.ch = ch;
this.callback_ed = true;
+ this.unsafe.channelEstablish(ch, ex);
this.timeoutTask.cancel();
try {
this.callback.call(ch, ex);
@@ -94,10 +90,6 @@ protected void channelEstablish(Channel ch, Throwable ex) {
public synchronized void close() {
Util.close(ch);
Util.stop(this);
- if (!getProcessorGroup().isSharable()) {
- this.eventLoop = null;
- }
- this.ch = null;
}
public synchronized Channel connect() throws Exception {
@@ -118,12 +110,17 @@ public synchronized void connect(Callback callback, long timeout) throw
throw new IOException("connect is pending");
}
this.callback_ed = false;
- this.timeoutTask = new TimeoutTask(this, timeout);
this.callback = callback;
+ this.timeoutTask = new TimeoutTask(this, timeout);
this.getProcessorGroup().setContext(this);
+ if (Native.EPOLL_AVAILABLE) {
+ unsafe = new EpollConnectorUnsafe();
+ } else {
+ unsafe = new JavaConnectorUnsafe();
+ }
Util.start(getProcessorGroup());
Util.start(this);
- if (eventLoop == null) {
+ if (eventLoop == null || !eventLoop.isRunning()) {
eventLoop = getProcessorGroup().getNext();
}
boolean submitted = this.eventLoop.submit(new Runnable() {
@@ -152,17 +149,9 @@ public synchronized Channel connect(long timeout) throws Exception {
// If your application blocking here, check if you are blocking the io thread.
// Notice that do not blocking io thread at any time.
callback.await();
- if (callback.isTimeout()) {
- Util.close(this);
- throw new TimeoutException("connect to " + getServerAddress() + " time out");
- }
if (callback.isFailed()) {
Util.close(this);
- Throwable ex = callback.getThrowable();
- if (ex instanceof Exception) {
- throw (Exception) callback.getThrowable();
- }
- throw new IOException("connect failed", ex);
+ throw new IOException("connect failed", callback.getThrowable());
}
return getChannel();
}
@@ -202,14 +191,15 @@ static abstract class ConnectorUnsafe {
abstract void connect(ChannelConnector ctx, NioEventLoop el) throws IOException;
- abstract void channelEstablish(Channel ch, NioEventLoop el, Throwable ex);
+ abstract void channelEstablish(Channel ch, Throwable ex);
}
static final class EpollConnectorUnsafe extends ConnectorUnsafe {
- private int fd = -1;
- private String remoteAddr;
+ private int fd = -1;
+ private String remoteAddr;
+ private EpollEventLoop el;
@Override
void connect(ChannelConnector ctx, NioEventLoop el) throws IOException {
@@ -219,28 +209,28 @@ void connect(ChannelConnector ctx, NioEventLoop el) throws IOException {
int fd = Native.connect(host.getHostAddress(), ctx.getPort());
Native.throwException(fd);
this.fd = fd;
- el.schedule(ctx.timeoutTask);
+ this.el = un;
un.ctxs.put(fd, ctx);
+ el.schedule(ctx.timeoutTask);
int res = Native.epoll_add(un.epfd, fd, Native.EPOLL_OUT);
Native.throwException(res);
}
@Override
- void channelEstablish(Channel ch, NioEventLoop el, Throwable ex) {
+ void channelEstablish(Channel ch, Throwable ex) {
if (ex != null && fd != -1) {
- EpollEventLoop un = (EpollEventLoop) el;
- un.ctxs.remove(fd);
+ el.ctxs.remove(fd);
if (Develop.NATIVE_DEBUG) {
- int res = Native.epoll_del(un.epfd, fd);
+ int res = Native.epoll_del(el.epfd, fd);
if (res == -1) {
- logger.error("cancel...epfd:{},fd:{}", un.epfd, fd);
+ logger.error("cancel...epfd:{},fd:{}", el.epfd, fd);
}
res = Native.close(fd);
if (res == -1) {
logger.error("cancel...fd:{}", fd);
}
} else {
- Native.epoll_del(un.epfd, fd);
+ Native.epoll_del(el.epfd, fd);
Native.close(fd);
}
this.fd = -1;
@@ -251,25 +241,22 @@ String getRemoteAddr() {
return remoteAddr;
}
- int getFd() {
- return fd;
- }
-
}
static final class JavaConnectorUnsafe extends ConnectorUnsafe {
private SocketChannel javaChannel;
+ private SelectionKey selectionKey;
@Override
void connect(ChannelConnector ctx, NioEventLoop el) throws IOException {
- Util.close(javaChannel);
this.javaChannel = SocketChannel.open();
this.javaChannel.configureBlocking(false);
if (!javaChannel.connect(ctx.getServerAddress())) {
el.schedule(ctx.timeoutTask);
JavaEventLoop elUnsafe = (JavaEventLoop) el;
- javaChannel.register(elUnsafe.getSelector(), SelectionKey.OP_CONNECT, ctx);
+ Selector selector = elUnsafe.getSelector();
+ this.selectionKey = javaChannel.register(selector, SelectionKey.OP_CONNECT, ctx);
}
}
@@ -278,16 +265,10 @@ SocketChannel getSelectableChannel() {
}
@Override
- void channelEstablish(Channel ch, NioEventLoop el, Throwable ex) {
- final SocketChannel channel = this.javaChannel;
- if (ex != null && channel != null) {
- final JavaEventLoop un = (JavaEventLoop) el;
- SelectionKey key = channel.keyFor(un.getSelector());
- if (key != null) {
- key.cancel();
- }
- Util.close(channel);
- this.javaChannel = null;
+ void channelEstablish(Channel ch, Throwable ex) {
+ if (ex != null) {
+ selectionKey.cancel();
+ Util.close(javaChannel);
}
}
diff --git a/firenio-core/src/main/java/com/firenio/component/ChannelContext.java b/firenio-core/src/main/java/com/firenio/component/ChannelContext.java
index ebff8940e..50e4e9d34 100644
--- a/firenio-core/src/main/java/com/firenio/component/ChannelContext.java
+++ b/firenio-core/src/main/java/com/firenio/component/ChannelContext.java
@@ -33,6 +33,7 @@
import com.firenio.common.Assert;
import com.firenio.common.FileUtil;
import com.firenio.common.Properties;
+import com.firenio.common.Unsafe;
import com.firenio.common.Util;
import com.firenio.concurrent.EventLoop;
import com.firenio.concurrent.EventLoopGroup;
@@ -148,19 +149,29 @@ protected void doStart() throws Exception {
}
if (isEnableSsl()) {
sb.setLength(0);
- for (String p : SslContext.ENABLED_PROTOCOLS) {
+ for (String p : sslContext.getProtocols()) {
sb.append(p);
sb.append(',');
sb.append(' ');
}
sb.setLength(sb.length() - 2);
- logger.info("ssl default protocols : [ {} ]", sb.toString());
+ logger.info("ssl protocols : [ {} ]", sb.toString());
+ }
+ if (isEnableSsl()) {
+ sb.setLength(0);
+ for (String p : sslContext.getCipherSuites()) {
+ sb.append(p);
+ sb.append(',');
+ sb.append(' ');
+ }
+ sb.setLength(sb.length() - 2);
+ logger.info("ssl cipher suites : [ {} ]", sb.toString());
}
}
}
private String getByteBufPoolType(NioEventLoopGroup g) {
- if (Options.isEnableUnsafeBuf()) {
+ if (Unsafe.UNSAFE_BUF_AVAILABLE) {
return "unsafe";
}
return g.isEnableMemoryPoolDirect() ? "direct" : "heap";
diff --git a/firenio-core/src/main/java/com/firenio/component/ChannelIdleListener.java b/firenio-core/src/main/java/com/firenio/component/ChannelIdleListener.java
index ae5c1da1d..5f337df55 100644
--- a/firenio-core/src/main/java/com/firenio/component/ChannelIdleListener.java
+++ b/firenio-core/src/main/java/com/firenio/component/ChannelIdleListener.java
@@ -19,6 +19,6 @@
public interface ChannelIdleListener extends EventListener {
- void channelIdled(Channel ch, long lastIdleTime, long currentTime);
+ void channelIdled(Channel ch, long lastIdleTime);
}
diff --git a/firenio-core/src/main/java/com/firenio/component/ChannelManager.java b/firenio-core/src/main/java/com/firenio/component/ChannelManager.java
index 96ca37278..51d2c531d 100644
--- a/firenio-core/src/main/java/com/firenio/component/ChannelManager.java
+++ b/firenio-core/src/main/java/com/firenio/component/ChannelManager.java
@@ -44,18 +44,26 @@ public static void broadcast(ByteBuf buf, Collection chs) {
}
}
+ public void broadcast(ByteBuf buf) {
+ broadcast(buf, channels.values());
+ }
+
public static void broadcast(Frame frame, Collection chs) throws Exception {
if (chs.size() == 0) {
+ frame.release();
return;
}
Channel ch = chs.iterator().next();
- if (ch != null) {
- broadcast(ch.encode(frame), chs);
+ if (ch == null) {
+ frame.release();
+ return;
+ }
+ try {
+ ByteBuf buf = ch.getCodec().encode(ch, frame);
+ broadcast(buf, chs);
+ } finally {
+ frame.release();
}
- }
-
- public void broadcast(ByteBuf buf) {
- broadcast(buf, channels.values());
}
public void broadcast(Frame frame) throws Exception {
diff --git a/firenio-core/src/main/java/com/firenio/component/ExceptionCaughtHandle.java b/firenio-core/src/main/java/com/firenio/component/ExceptionCaughtHandle.java
index afeb8ffa4..85dfb56d0 100644
--- a/firenio-core/src/main/java/com/firenio/component/ExceptionCaughtHandle.java
+++ b/firenio-core/src/main/java/com/firenio/component/ExceptionCaughtHandle.java
@@ -20,6 +20,6 @@
*/
public interface ExceptionCaughtHandle {
- void exceptionCaught(Channel ch, Frame frame, Exception ex);
+ void exceptionCaught(Channel ch, Frame frame, Throwable ex);
}
diff --git a/firenio-core/src/main/java/com/firenio/component/FastThreadLocal.java b/firenio-core/src/main/java/com/firenio/component/FastThreadLocal.java
index 5a24128ec..252f1ca4b 100644
--- a/firenio-core/src/main/java/com/firenio/component/FastThreadLocal.java
+++ b/firenio-core/src/main/java/com/firenio/component/FastThreadLocal.java
@@ -23,28 +23,27 @@
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
import com.firenio.buffer.ByteBuf;
-import com.firenio.collection.AttributesImpl;
+import com.firenio.collection.AttributeKey;
+import com.firenio.collection.AttributeMap;
import com.firenio.common.Util;
/**
* @author wangkai
*/
-public final class FastThreadLocal extends AttributesImpl {
+public final class FastThreadLocal extends AttributeMap {
- private static final AtomicInteger indexedVarsIndex = new AtomicInteger(0);
- private static final int maxIndexedVarsSize = 32;
- private static final ThreadLocal slowThreadLocal = new ThreadLocal<>();
+ private static final ThreadLocal slowThreadLocal = new ThreadLocal<>();
- private byte[] bytes32 = new byte[32];
- private Map charsetDecoders = new IdentityHashMap<>();
- private Map charsetEncoders = new IdentityHashMap<>();
- private Object[] indexedVariables = new Object[maxIndexedVarsSize];
+ private byte[] bytes32 = new byte[32];
+ private Map charsetDecoders = new IdentityHashMap<>();
+ private Map charsetEncoders = new IdentityHashMap<>();
private ByteBuf sslUnwrapBuf;
private ByteBuf sslWrapBuf;
- private StringBuilder stringBuilder = new StringBuilder(512);
+ private StringBuilder stringBuilder = new StringBuilder(512);
+ private List> list = new ArrayList<>();
+ private Map, ?> map = new HashMap<>();
FastThreadLocal() {}
@@ -75,15 +74,12 @@ public static FastThreadLocal get() {
}
}
- public static int nextIndexedVariablesIndex() {
- if (indexedVarsIndex.get() >= maxIndexedVarsSize) {
- return -1;
- }
- int index = indexedVarsIndex.getAndIncrement();
- if (index >= maxIndexedVarsSize) {
- return -1;
- }
- return index;
+ public static AttributeKey valueOfKey(String name) {
+ return AttributeMap.valueOfKey(FastThreadLocal.class, name);
+ }
+
+ public static AttributeKey valueOfKey(String name, AttributeInitFunction function) {
+ return AttributeMap.valueOfKey(FastThreadLocal.class, name, function);
}
private void destroy0() {
@@ -113,40 +109,16 @@ public CharsetEncoder getCharsetEncoder(Charset charset) {
return encoder;
}
- public Object getIndexedVariable(int index) {
- return indexedVariables[index];
- }
-
- public List> getList(int index) {
- List> list = (List>) getIndexedVariable(index);
- if (list == null) {
- list = new ArrayList<>();
- setIndexedVariable(index, list);
- }
- list.clear();
- return list;
- }
-
- public Map, ?> getMap(int index) {
- Map, ?> map = (Map, ?>) getIndexedVariable(index);
- if (map == null) {
- map = new HashMap<>();
- setIndexedVariable(index, map);
- }
- map.clear();
- return map;
- }
-
public ByteBuf getSslUnwrapBuf() {
if (sslUnwrapBuf == null) {
- sslUnwrapBuf = ByteBuf.direct(SslContext.SSL_UNWRAP_BUFFER_SIZE);
+ sslUnwrapBuf = ByteBuf.buffer(SslContext.SSL_UNWRAP_BUFFER_SIZE);
}
return sslUnwrapBuf;
}
public ByteBuf getSslWrapBuf() {
if (sslWrapBuf == null) {
- sslWrapBuf = ByteBuf.direct(SslContext.SSL_PACKET_BUFFER_SIZE);
+ sslWrapBuf = ByteBuf.buffer(SslContext.SSL_PACKET_BUFFER_SIZE);
}
return sslWrapBuf;
}
@@ -156,8 +128,18 @@ public StringBuilder getStringBuilder() {
return stringBuilder;
}
- public void setIndexedVariable(int index, Object value) {
- indexedVariables[index] = value;
+ public List> getList() {
+ list.clear();
+ return list;
}
+ public Map, ?> getMap() {
+ map.clear();
+ return map;
+ }
+
+ @Override
+ protected AttributeKeys getKeys() {
+ return getKeys(FastThreadLocal.class);
+ }
}
diff --git a/firenio-core/src/main/java/com/firenio/component/Frame.java b/firenio-core/src/main/java/com/firenio/component/Frame.java
index 36191b8ef..4efa9263b 100644
--- a/firenio-core/src/main/java/com/firenio/component/Frame.java
+++ b/firenio-core/src/main/java/com/firenio/component/Frame.java
@@ -81,7 +81,7 @@ public void setBytes(byte[] bytes, int off, int len, Channel ch) {
}
public void setBytes(int header, byte[] bytes, int off, int len) {
- this.content = ByteBuf.heap(header + len).skip(header);
+ this.content = ByteBuf.buffer(header + len).skipWrite(header);
write(bytes, off, len);
}
@@ -98,7 +98,7 @@ public void write(byte[] bytes, int off, int len) {
if (c == null) {
throw new NullPointerException("do setContent(buf) before write");
}
- c.putBytes(bytes, off, len);
+ c.writeBytes(bytes, off, len);
}
public void write(String text, Channel ch) {
diff --git a/firenio-core/src/main/java/com/firenio/component/IoEventHandle.java b/firenio-core/src/main/java/com/firenio/component/IoEventHandle.java
index afec0a0db..d9512b0fe 100644
--- a/firenio-core/src/main/java/com/firenio/component/IoEventHandle.java
+++ b/firenio-core/src/main/java/com/firenio/component/IoEventHandle.java
@@ -25,7 +25,7 @@ public abstract class IoEventHandle implements ExceptionCaughtHandle {
public abstract void accept(Channel ch, Frame frame) throws Exception;
@Override
- public void exceptionCaught(Channel ch, Frame frame, Exception ex) {
+ public void exceptionCaught(Channel ch, Frame frame, Throwable ex) {
logger.error(ex.getMessage(), ex);
}
diff --git a/firenio-core/src/main/java/com/firenio/component/LoggerExceptionCaughtHandle.java b/firenio-core/src/main/java/com/firenio/component/LoggerExceptionCaughtHandle.java
index 2a79c4145..0e71daacd 100644
--- a/firenio-core/src/main/java/com/firenio/component/LoggerExceptionCaughtHandle.java
+++ b/firenio-core/src/main/java/com/firenio/component/LoggerExceptionCaughtHandle.java
@@ -26,7 +26,7 @@ public class LoggerExceptionCaughtHandle implements ExceptionCaughtHandle {
private Logger logger = LoggerFactory.getLogger(getClass());
@Override
- public void exceptionCaught(Channel ch, Frame frame, Exception ex) {
+ public void exceptionCaught(Channel ch, Frame frame, Throwable ex) {
logger.error(ex.getMessage(), ex);
}
diff --git a/firenio-core/src/main/java/com/firenio/component/Native.java b/firenio-core/src/main/java/com/firenio/component/Native.java
index 1504a2f05..0ff6545cc 100644
--- a/firenio-core/src/main/java/com/firenio/component/Native.java
+++ b/firenio-core/src/main/java/com/firenio/component/Native.java
@@ -2,13 +2,11 @@
import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
import com.firenio.Develop;
import com.firenio.Options;
import com.firenio.common.FileUtil;
import com.firenio.common.Unsafe;
-import com.firenio.common.Util;
import com.firenio.log.Logger;
import com.firenio.log.LoggerFactory;
@@ -18,54 +16,71 @@ public class Native {
//gcc -shared -g -fPIC -m64 -o obj/native.o src/Native.cpp
//gcc -shared -fPIC -m64 -o obj/native.o src/Native.cpp
- public static final boolean EPOLL_AVAILABLE;
- public static final int EPOLL_ERR;
- public static final int EPOLL_ET;
- public static final int EPOLL_IN;
- public static final int EPOLL_IN_ET;
- public static final int EPOLL_IN_OUT;
- public static final int EPOLL_IN_OUT_ET;
- public static final int EPOLL_OUT;
- public static final int EPOLL_OUT_ET;
- public static final int EPOLL_HUP;
- public static final int EPOLL_RD_HUP;
- public static final String[] ERRORS;
- public static final boolean IS_LINUX;
+ public static final int SEEK_SET = 0; /* Seek from beginning of file. */
+ public static final int SEEK_CUR = 1; /* Seek from current position. */
+ public static final int SEEK_END = 2; /* Seek from end of file. */
+ public static final int SEEK_DATA = 3; /* Seek to next data. */
+ public static final int SEEK_HOLE = 4; /* Seek to next hole. */
+
+ public static final int O_ACCMODE = 0003;
+ public static final int O_RDONLY = 00;
+ public static final int O_WRONLY = 01;
+ public static final int O_RDWR = 02;
+ public static final int O_CREAT = 0100;
+ public static final int O_EXCL = 0200;
+ public static final int O_NOCTTY = 0400;
+ public static final int O_TRUNC = 01000;
+ public static final int O_APPEND = 02000;
+ public static final int O_NONBLOCK = 04000;
+ public static final int O_DIRECT = 040000;
+ public static final int O_NDELAY = O_NONBLOCK;
+ public static final int O_SYNC = 04010000;
+ public static final int O_FSYNC = O_SYNC;
+ public static final int O_ASYNC = 020000;
+
+ public static final int EPOLL_ERR = 1 << 3;
+ public static final int EPOLL_ET = 1 << 31;
+ public static final int EPOLL_IN = 1 << 0;
+ public static final int EPOLL_OUT = 1 << 2;
+ public static final int EPOLL_HUP = 1 << 4;
+ public static final int EPOLL_RD_HUP = 1 << 13;
+ public static final int EPOLL_IN_ET = EPOLL_IN | EPOLL_ET;
+ public static final int EPOLL_IN_OUT = EPOLL_IN | EPOLL_OUT;
+ public static final int EPOLL_OUT_ET = EPOLL_OUT | EPOLL_ET;
+ public static final int EPOLL_IN_OUT_ET = EPOLL_IN_ET | EPOLL_OUT_ET;
+ public static final boolean EPOLL_AVAILABLE = try_load_epoll();
public static final int SIZEOF_EPOLL_EVENT;
public static final int SIZEOF_SOCK_ADDR_IN;
- private static final Logger logger = LoggerFactory.getLogger(Native.class);
+ public static final String[] ERRORS;
+ private static final Logger logger = LoggerFactory.getLogger(Native.class);
static {
- EPOLL_ET = 1 << 31;
- EPOLL_IN = 1 << 0;
- EPOLL_OUT = 1 << 2;
- EPOLL_ERR = 1 << 3;
- EPOLL_HUP = 1 << 4;
- EPOLL_RD_HUP = 1 << 13;
- EPOLL_IN_OUT = EPOLL_IN | EPOLL_OUT;
- EPOLL_IN_ET = EPOLL_IN | EPOLL_ET;
- EPOLL_OUT_ET = EPOLL_OUT | EPOLL_ET;
- EPOLL_IN_OUT_ET = EPOLL_IN_ET | EPOLL_OUT_ET;
- IS_LINUX = isLinux();
- EPOLL_AVAILABLE = IS_LINUX && tryLoadEpoll();
if (EPOLL_AVAILABLE) {
- ERRORS = new String[256];
- byte[] temp = new byte[1024];
- for (int i = 0; i < ERRORS.length; i++) {
- int len = strerrno(i, temp);
- ERRORS[i] = new String(temp, 0, len);
- }
+ ERRORS = load_errors();
SIZEOF_EPOLL_EVENT = size_of_epoll_event();
SIZEOF_SOCK_ADDR_IN = size_of_sockaddr_in();
} else {
+ ERRORS = null;
SIZEOF_EPOLL_EVENT = -1;
SIZEOF_SOCK_ADDR_IN = -1;
- ERRORS = null;
}
}
- private static boolean tryLoadEpoll() {
- if (Options.isEnableEpoll()) {
+ private static String[] load_errors() {
+ String[] errors = new String[256];
+ byte[] temp = new byte[1024];
+ for (int i = 0; i < errors.length; i++) {
+ int len = strerrno(i, temp);
+ errors[i] = new String(temp, 0, len);
+ }
+ return errors;
+ }
+
+ private static boolean try_load_epoll() {
+ if (!Unsafe.DIRECT_BUFFER_AVAILABLE) {
+ return false;
+ }
+ if (Unsafe.IS_LINUX && Options.isEnableEpoll()) {
boolean epollLoaded = false;
if (Develop.EPOLL_DEBUG) {
logger.info("load epoll from:{}", Develop.EPOLL_PATH);
@@ -76,7 +91,7 @@ private static boolean tryLoadEpoll() {
}
} else {
try {
- loadNative("native.o");
+ load_native("native.o");
epollLoaded = true;
} catch (Throwable e) {
if (Develop.NATIVE_DEBUG) {
@@ -92,7 +107,7 @@ private static boolean tryLoadEpoll() {
return true;
}
if (Develop.NATIVE_DEBUG) {
- logger.error("epoll creat failed:" + Native.err_str());
+ logger.error("epoll create failed:" + Native.err_str());
}
} catch (Throwable e) {
}
@@ -101,12 +116,20 @@ private static boolean tryLoadEpoll() {
return false;
}
+ private static void load_native(String name) throws IOException {
+ byte[] native_data = FileUtil.readBytesByCls(name, Native.class.getClassLoader());
+ File native_tmp = File.createTempFile(name, ".o");
+ FileUtil.writeByFile(native_tmp, native_data);
+ System.load(native_tmp.getAbsolutePath());
+ native_tmp.deleteOnExit();
+ }
+
public static int close_event() {
return EPOLL_ERR | EPOLL_HUP | EPOLL_RD_HUP;
}
public static int accept(int epfd, int listen_fd, long address) {
- return printException(accept0(epfd, listen_fd, address));
+ return print_exception(accept0(epfd, listen_fd, address));
}
public static int bind(String host, int port, int backlog) {
@@ -117,11 +140,11 @@ public static int close(int fd) {
if (fd == -1) {
return -1;
}
- return printException(close0(fd));
+ return print_exception(close0(fd));
}
public static int connect(String host, int port) {
- return printException(connect0(host, port));
+ return print_exception(connect0(host, port));
}
public static int epoll_add(int epfd, int fd, int state) {
@@ -136,19 +159,17 @@ public static int epoll_del(int epfd, int fd) {
if (fd == -1) {
return -1;
}
- return printException(epoll_del0(epfd, fd));
+ return print_exception(epoll_del0(epfd, fd));
}
public static int epoll_mod(int epfd, int fd, int state) {
- return printException(epoll_mod0(epfd, fd, state));
+ return print_exception(epoll_mod0(epfd, fd, state));
}
- public static int epoll_wait(int fd, long address, int maxEvents, long timeout) {
- return printException(epoll_wait0(fd, address, maxEvents, timeout));
+ public static int epoll_wait(int fd, long address, int max_events, long timeout) {
+ return print_exception(epoll_wait0(fd, address, max_events, timeout));
}
- public static native int errno();
-
public static String err_str() {
return err_str(errno());
}
@@ -162,24 +183,11 @@ private static String err_str(int errno) {
}
public static int event_fd_read(int fd) {
- return printException(event_fd_read0(fd));
+ return print_exception(event_fd_read0(fd));
}
public static int event_fd_write(int fd, long value) {
- return printException(event_fd_write0(fd, value));
- }
-
- private static boolean isLinux() {
- return Util.getStringProperty("os.name", "").toLowerCase().startsWith("lin");
- }
-
- private static void loadNative(String name) throws IOException {
- InputStream in = Native.class.getClassLoader().getResourceAsStream(name);
- File tmpFile = File.createTempFile(name, ".o");
- byte[] data = FileUtil.inputStream2ByteArray(in);
- FileUtil.writeByFile(tmpFile, data);
- System.load(tmpFile.getAbsolutePath());
- tmpFile.deleteOnExit();
+ return print_exception(event_fd_write0(fd, value));
}
public static long new_epoll_event_array(int size) {
@@ -191,10 +199,14 @@ public static int new_event_fd() {
}
public static int read(int fd, long address, int len) {
- return printException(read0(fd, address, len));
+ return print_exception(read0(fd, address, len));
}
- private static int printException(int res) {
+ public static int pread(int fd, long address, int len, long pos) {
+ return print_exception(pread0(fd, address, len, pos));
+ }
+
+ private static int print_exception(int res) {
if (Develop.NATIVE_DEBUG && res == -1) {
int errno = errno();
if (errno != 0) {
@@ -205,11 +217,16 @@ private static int printException(int res) {
return res;
}
- public static native int size_of_epoll_event();
-
- public static native int size_of_sockaddr_in();
-
- public static native int strerrno(int no, byte[] buf);
+ private static long print_exception(long res) {
+ if (Develop.NATIVE_DEBUG && res == -1) {
+ int errno = errno();
+ if (errno != 0) {
+ IOException e = new IOException(err_str(errno));
+ logger.error(e.getMessage(), e);
+ }
+ }
+ return res;
+ }
public static int throwException(int res) throws IOException {
if (res == -1) {
@@ -226,30 +243,39 @@ public static int throwRuntimeException(int res) {
}
public static int write(int fd, long address, int len) {
- return printException(write0(fd, address, len));
+ return print_exception(write0(fd, address, len));
+ }
+
+ public static int pwrite(int fd, long address, int len, long pos) {
+ return print_exception(pwrite0(fd, address, len, pos));
}
public static int get_port(int fd) {
- return Short.reverseBytes((short) printException(get_port0(fd))) & 0xffff;
+ return Short.reverseBytes((short) print_exception(get_port0(fd))) & 0xffff;
}
public static long writev(int fd, long iovec, int count) {
- return printException(writev0(fd, iovec, count));
+ return print_exception(writev0(fd, iovec, count));
}
public static int set_socket_opt(int fd, int type, int name, int value) {
- return printException(set_socket_opt0(fd, type, name, value));
+ return print_exception(set_socket_opt0(fd, type, name, value));
}
public static boolean finish_connect(int fd) {
- int type = SocketOptions.SOL_SOCKET >> 16;
+ int type = SocketOptions.RAW_SOL_SOCKET;
int res = get_socket_opt0(fd, type, SocketOptions.SO_ERROR & 0xff);
if (res != 0) {
if (res == -1) {
- printException(res);
+ print_exception(res);
} else {
- IOException e = new IOException(err_str(res & 0x7fffffff));
- logger.error(e.getMessage(), e);
+ if (Develop.NATIVE_DEBUG) {
+ if (res < 0) {
+ res = -res;
+ }
+ IOException e = new IOException(err_str(res));
+ logger.error(e.getMessage(), e);
+ }
}
return false;
}
@@ -257,10 +283,35 @@ public static boolean finish_connect(int fd) {
}
public static int get_socket_opt(int fd, int type, int name) {
- return printException(get_socket_opt0(fd, type, name));
+ return print_exception(get_socket_opt0(fd, type, name));
+ }
+
+ public static int open(String path, int op, int pem) {
+ return print_exception(open0(path, op, pem));
+ }
+
+ public static long posix_memalign_allocate(int len, int align) {
+ return print_exception(posix_memalign_allocate0(len, align));
+ }
+
+ public static long file_length(int fd) {
+ return print_exception(file_length0(fd));
+ }
+
+ public static long lseek(int fd, long off, int seek_mode) {
+ return print_exception(lseek0(fd, off, seek_mode));
}
- //---------------------------------------------------------------------------------------------------------
+ // epoll----------------------------------------------------------------------------------------
+
+ public static native int errno();
+
+ private static native int size_of_epoll_event();
+
+ private static native int size_of_sockaddr_in();
+
+ private static native int strerrno(int no, byte[] buf);
+
private static native int get_socket_opt0(int fd, int type, int name);
private static native int set_socket_opt0(int fd, int type, int name, int value);
@@ -281,7 +332,7 @@ public static int get_socket_opt(int fd, int type, int name) {
private static native int epoll_mod0(int epfd, int fd, int state);
- private static native int epoll_wait0(int fd, long address, int maxEvents, long timeout);
+ private static native int epoll_wait0(int fd, long address, int max_events, long timeout);
private static native int event_fd_read0(int fd);
@@ -297,4 +348,18 @@ public static int get_socket_opt(int fd, int type, int name) {
private static native int writev0(int fd, long iovec, int count);
+ // direct io----------------------------------------------------------------------------------------
+
+ private static native int open0(String path, int op, int pem);
+
+ private static native long posix_memalign_allocate0(int len, int align);
+
+ private static native long file_length0(int fd);
+
+ private static native long lseek0(int fd, long off, int seek_mode);
+
+ private static native int pread0(int fd, long address, int len, long off);
+
+ private static native int pwrite0(int fd, long address, int len, long off);
+
}
diff --git a/firenio-core/src/main/java/com/firenio/component/NioEventLoop.java b/firenio-core/src/main/java/com/firenio/component/NioEventLoop.java
index 6dc7a0200..4c2dd2083 100644
--- a/firenio-core/src/main/java/com/firenio/component/NioEventLoop.java
+++ b/firenio-core/src/main/java/com/firenio/component/NioEventLoop.java
@@ -29,10 +29,8 @@
import java.security.PrivilegedAction;
import java.util.AbstractSet;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
@@ -43,8 +41,11 @@
import com.firenio.buffer.ByteBuf;
import com.firenio.buffer.ByteBufAllocator;
import com.firenio.collection.ArrayListStack;
-import com.firenio.collection.Attributes;
+import com.firenio.collection.AttributeKey;
+import com.firenio.collection.AttributeMap;
+import com.firenio.collection.AttributeMap.AttributeInitFunction;
import com.firenio.collection.DelayedQueue;
+import com.firenio.collection.IntArray;
import com.firenio.collection.IntMap;
import com.firenio.collection.LinkedBQStack;
import com.firenio.collection.Stack;
@@ -64,28 +65,33 @@
/**
* @author wangkai
*/
-public abstract class NioEventLoop extends EventLoop implements Attributes {
+public abstract class NioEventLoop extends EventLoop {
static final boolean CHANNEL_READ_FIRST = Options.isChannelReadFirst();
static final Logger logger = NEW_LOGGER();
static final IOException NOT_FINISH_CONNECT = NOT_FINISH_CONNECT();
static final IOException OVER_CH_SIZE_LIMIT = OVER_CH_SIZE_LIMIT();
+ // NOTICE USE_HAS_TASK can make a memory barrier for io thread,
+ // please do not change this value to false unless you are really need.
+ // I am not sure if the select()/select(n) has memory barrier,
+ // it can be set USE_HAS_TASK to false if there is a memory barrier.
static final boolean USE_HAS_TASK = true;
final ByteBufAllocator alloc;
- final Map attributes = new HashMap<>();
final ByteBuf buf;
- final IntMap channels = new IntMap<>(4096);
+ final AttributeMap attributeMap = new NioEventLoopAttributeMap();
+ final IntMap channels = new IntMap<>(4096);
+ final IntArray close_channels = new IntArray();
final int ch_size_limit;
- final DelayedQueue delayed_queue = new DelayedQueue();
- final BlockingQueue events = new LinkedBlockingQueue<>();
+ final DelayedQueue delayed_queue = new DelayedQueue();
+ final BlockingQueue events = new LinkedBlockingQueue<>();
final NioEventLoopGroup group;
final int index;
- final AtomicInteger selecting = new AtomicInteger();
+ final AtomicInteger selecting = new AtomicInteger();
final boolean sharable;
final long buf_address;
final boolean acceptor;
- volatile boolean has_task = false;
+ volatile boolean has_task = false;
NioEventLoop(NioEventLoopGroup group, int index, String threadName) {
super(threadName);
@@ -97,43 +103,43 @@ public abstract class NioEventLoop extends EventLoop implements Attributes {
this.ch_size_limit = group.getChannelSizeLimit();
int channelReadBuffer = group.getChannelReadBuffer();
if (channelReadBuffer > 0) {
- this.buf = ByteBuf.direct(channelReadBuffer);
- this.buf_address = Unsafe.address(buf.getNioBuffer());
+ this.buf = ByteBuf.buffer(channelReadBuffer);
+ this.buf_address = buf.address();
} else {
this.buf = null;
this.buf_address = -1;
}
}
- private static void channel_idle(ChannelIdleListener l, Channel ch, long lastIdleTime, long currentTime) {
+ private static void channel_idle(ChannelIdleListener l, Channel ch, long lastIdleTime) {
try {
- l.channelIdled(ch, lastIdleTime, currentTime);
- } catch (Exception e) {
+ l.channelIdled(ch, lastIdleTime);
+ } catch (Throwable e) {
logger.error(e.getMessage(), e);
}
}
- private static void channel_idle(ChannelContext context, IntMap channels, long last_idle_time, long current_time) {
+ private static void channel_idle(ChannelContext context, IntMap channels, long last_idle_time) {
List ls = context.getChannelIdleEventListeners();
for (int i = 0; i < ls.size(); i++) {
ChannelIdleListener l = ls.get(i);
for (channels.scan(); channels.hasNext(); ) {
- Channel ch = channels.nextValue();
- channel_idle(l, ch, last_idle_time, current_time);
+ Channel ch = channels.value();
+ channel_idle(l, ch, last_idle_time);
}
}
}
- private static void channel_idle_share(IntMap channels, long last_idle_time, long current_time) {
+ private static void channel_idle_share(IntMap channels, long last_idle_time) {
for (channels.scan(); channels.hasNext(); ) {
- Channel ch = channels.nextValue();
+ Channel ch = channels.value();
ChannelContext context = ch.getContext();
List ls = context.getChannelIdleEventListeners();
if (ls.size() == 1) {
- channel_idle(ls.get(0), ch, last_idle_time, current_time);
+ channel_idle(ls.get(0), ch, last_idle_time);
} else {
for (int i = 0; i < ls.size(); i++) {
- channel_idle(ls.get(i), ch, last_idle_time, current_time);
+ channel_idle(ls.get(i), ch, last_idle_time);
}
}
}
@@ -163,7 +169,7 @@ static IOException NOT_FINISH_CONNECT() {
}
static IOException OVER_CH_SIZE_LIMIT() {
- return Util.unknownStackTrace(new IOException("over channel size limit"), NioEventLoop.class, "register_channel(...)");
+ return Util.unknownStackTrace(new IOException("over channel size writeIndex"), NioEventLoop.class, "register_channel(...)");
}
static void read_exception_caught(Channel ch, Throwable ex) {
@@ -178,32 +184,23 @@ public ByteBufAllocator alloc() {
return alloc;
}
- @Override
- public Map attributes() {
- return attributes;
- }
-
//FIXME ..optimize sharable group
- private void channel_idle(long last_idle_time, long current_time) {
+ private void channel_idle(long last_idle_time) {
IntMap channels = this.channels;
if (channels.isEmpty()) {
return;
}
if (sharable) {
- channel_idle_share(channels, last_idle_time, current_time);
+ channel_idle_share(channels, last_idle_time);
} else {
- channel_idle(group.getContext(), channels, last_idle_time, current_time);
+ channel_idle(group.getContext(), channels, last_idle_time);
}
}
- @Override
- public void clearAttributes() {
- this.attributes.clear();
- }
-
private void close_channels() {
+ IntMap channels = this.channels;
for (channels.scan(); channels.hasNext(); ) {
- Util.close(channels.nextValue());
+ Util.close(channels.value());
}
}
@@ -211,23 +208,16 @@ protected long getBufAddress() {
return buf_address;
}
- @Override
- public Object getAttribute(Object key) {
- return this.attributes.get(key);
- }
-
- @Override
- public Set getAttributeNames() {
- return this.attributes.keySet();
+ public T getAttribute(AttributeKey key) {
+ return attributeMap.getAttribute(key);
}
public Channel getChannel(int channelId) {
return channels.get(channelId);
}
- @SuppressWarnings("unchecked")
- private Stack get_cache0(String key, int max) {
- Stack cache = (Stack) getAttribute(key);
+ private Stack get_cache0(AttributeKey> key, int max) {
+ Stack cache = getAttribute(key);
if (cache == null) {
if (group.isConcurrentFrameStack()) {
cache = new LinkedBQStack<>(max);
@@ -239,7 +229,7 @@ private Stack get_cache0(String key, int max) {
return cache;
}
- public Object getCache(String key, int max) {
+ public Object getCache(AttributeKey> key, int max) {
return get_cache0(key, max).pop();
}
@@ -261,21 +251,19 @@ protected ByteBuf getReadBuf() {
return buf;
}
- @SuppressWarnings("unchecked")
- public void release(String key, Object obj) {
- Stack buffer = (Stack) getAttribute(key);
+ public void release(AttributeKey> key, Object obj) {
+ Stack buffer = getAttribute(key);
if (buffer != null) {
buffer.push(obj);
}
}
- @Override
- public Object removeAttribute(Object key) {
- return this.attributes.remove(key);
+ public AttributeMap getAttributeMap() {
+ return attributeMap;
}
protected void removeChannel(int id) {
- channels.remove(id);
+ close_channels.add(id);
}
private void run_events(BlockingQueue events) {
@@ -329,11 +317,12 @@ private void clear_has_task() {
}
}
- private long run_delayed_events(DelayedQueue dq, long now, long nextIdle, long selectTime) {
+ private long run_delayed_events(DelayedQueue dq, long nextIdle) {
+ long now = Util.now();
for (; ; ) {
DelayedQueue.DelayTask t = dq.peek();
if (t == null) {
- break;
+ return nextIdle - now;
}
if (t.isCanceled()) {
dq.poll();
@@ -348,15 +337,15 @@ private long run_delayed_events(DelayedQueue dq, long now, long nextIdle, long s
} catch (Throwable e) {
logger.error(e.getMessage(), e);
}
- continue;
- }
- if (delay < nextIdle) {
- return delay - now;
+ now = Util.now();
} else {
- return selectTime;
+ if (delay < nextIdle) {
+ return delay - now;
+ } else {
+ return nextIdle - now;
+ }
}
}
- return selectTime;
}
@Override
@@ -366,8 +355,8 @@ public void run() {
final AtomicInteger selecting = this.selecting;
final BlockingQueue events = this.events;
final DelayedQueue dq = this.delayed_queue;
- long next_idle_time = 0;
- long last_idle_time = 0;
+ long last_idle_time = Util.now();
+ long next_idle_time = last_idle_time + idle;
long select_time = idle;
for (; ; ) {
// when this event loop is going to shutdown,we do not handle the last events
@@ -401,23 +390,37 @@ public void run() {
}
long now = Util.now();
if (now >= next_idle_time) {
- channel_idle(last_idle_time, now);
- last_idle_time = now;
- next_idle_time = now + idle;
- select_time = idle;
- } else {
- select_time = next_idle_time - now;
+ channel_idle(last_idle_time);
+ last_idle_time = next_idle_time;
+ next_idle_time = next_idle_time + idle;
}
run_events(events);
if (!dq.isEmpty()) {
- select_time = run_delayed_events(dq, now, next_idle_time, select_time);
+ select_time = run_delayed_events(dq, next_idle_time);
+ } else {
+ select_time = next_idle_time - Util.now();
}
+ remove_closed_channels();
} catch (Throwable e) {
logger.error(e);
}
}
}
+ private void remove_closed_channels() {
+ IntArray c_list = this.close_channels;
+ IntMap channels = this.channels;
+ if (!c_list.isEmpty()) {
+ for (int i = 0; i < c_list.size(); i++) {
+ Channel ch = channels.remove(c_list.get(i));
+ if (ch.isOpen()) {
+ channels.put(ch.getChannelId(), ch);
+ }
+ }
+ c_list.clear();
+ }
+ }
+
public boolean schedule(final DelayedQueue.DelayTask task) {
if (inEventLoop()) {
return delayed_queue.offer(task);
@@ -432,9 +435,8 @@ public void run() {
}
}
- @Override
- public void setAttribute(Object key, Object value) {
- this.attributes.put(key, value);
+ public void setAttribute(AttributeKey key, Object value) {
+ this.attributeMap.setAttribute(key, value);
}
public boolean submit(Runnable event) {
@@ -473,6 +475,13 @@ public void wakeup() {
abstract void wakeup0();
+ public static AttributeKey valueOfKey(String name) {
+ return AttributeMap.valueOfKey(NioEventLoop.class, name);
+ }
+
+ public static AttributeKey valueOfKey(String name, AttributeInitFunction function) {
+ return AttributeMap.valueOfKey(NioEventLoop.class, name, function);
+ }
static final class JavaEventLoop extends NioEventLoop {
@@ -539,7 +548,7 @@ public Object run() {
selectedKeysField.set(selector, keySet);
publicSelectedKeysField.set(selector, keySet);
return null;
- } catch (Exception e) {
+ } catch (Throwable e) {
return e;
}
}
@@ -626,7 +635,7 @@ private void accept(final ChannelAcceptor acceptor) {
public void run() {
try {
register_channel(ch, targetEL, acceptor, true);
- } catch (IOException e) {
+ } catch (Throwable e) {
logger.error(e.getMessage(), e);
}
}
@@ -724,7 +733,7 @@ private void register_channel(SocketChannel jch, NioEventLoop el, ChannelContext
int select(long timeout) {
try {
return selector.select(timeout);
- } catch (IOException e) {
+ } catch (Throwable e) {
debugException(logger, e);
return 0;
}
@@ -734,7 +743,7 @@ int select(long timeout) {
int select_now() {
try {
return selector.selectNow();
- } catch (IOException e) {
+ } catch (Throwable e) {
debugException(logger, e);
return 0;
}
@@ -917,8 +926,11 @@ public void run() {
private void accept(int fd, int e) {
Channel ch = getChannel(fd);
if (ch != null) {
- if (!ch.isOpen()) {
- return;
+ if (Develop.CHANNEL_DEBUG) {
+ if (!ch.isOpen()) {
+ logger.error("channel closed but goto accept block");
+ return;
+ }
}
if ((e & Native.close_event()) != 0) {
ch.close();
@@ -961,6 +973,12 @@ private void accept(int fd, int e) {
private void accept_connect(int fd, int e) {
ChannelConnector ctx = (ChannelConnector) ctxs.remove(fd);
+ if (ctx == null) {
+ if (Develop.CHANNEL_DEBUG) {
+ logger.error("server run in accept_connect........");
+ }
+ return;
+ }
if ((e & Native.close_event()) != 0 || !Native.finish_connect(fd)) {
ctx.channelEstablish(null, NOT_FINISH_CONNECT);
return;
@@ -1011,8 +1029,8 @@ private void register_channel(NioEventLoop el, ChannelContext ctx, int fd, Strin
}
Channel old = channels.get(fd);
if (old != null) {
- if (Develop.NATIVE_DEBUG) {
- logger.error("old channel ....................,open:{}", old.isOpen());
+ if (Develop.CHANNEL_DEBUG) {
+ logger.error("old channel ....................,{},open:{}", old, old.isOpen());
}
old.close();
}
@@ -1037,4 +1055,13 @@ void wakeup0() {
}
+ static class NioEventLoopAttributeMap extends AttributeMap {
+
+ @Override
+ protected AttributeKeys getKeys() {
+ return getKeys(NioEventLoop.class);
+ }
+
+ }
+
}
diff --git a/firenio-core/src/main/java/com/firenio/component/NioEventLoopGroup.java b/firenio-core/src/main/java/com/firenio/component/NioEventLoopGroup.java
index af4f8cb3b..9c0f76a42 100644
--- a/firenio-core/src/main/java/com/firenio/component/NioEventLoopGroup.java
+++ b/firenio-core/src/main/java/com/firenio/component/NioEventLoopGroup.java
@@ -20,6 +20,7 @@
import com.firenio.buffer.ByteBufAllocator;
import com.firenio.buffer.ByteBufAllocatorGroup;
import com.firenio.buffer.UnpooledByteBufAllocator;
+import com.firenio.common.Unsafe;
import com.firenio.common.Util;
import com.firenio.component.NioEventLoop.EpollEventLoop;
import com.firenio.component.NioEventLoop.JavaEventLoop;
@@ -42,7 +43,7 @@ public class NioEventLoopGroup extends EventLoopGroup {
private ChannelContext context;
private boolean enableMemoryPool = true;
//内存池是否使用启用堆外内存
- private boolean enableMemoryPoolDirect = true;
+ private boolean enableMemoryPoolDirect = Unsafe.DIRECT_BUFFER_AVAILABLE;
private NioEventLoop[] eventLoops;
private long idleTime = 30 * 1000;
//内存池内存单元数量(单核)
@@ -102,6 +103,15 @@ protected void doStart() throws Exception {
memoryPoolCapacity = (int) (total / (memoryPoolUnit * getEventLoopSize() * memoryPoolRate));
}
if (isEnableMemoryPool() && getAllocatorGroup() == null) {
+ if (Native.EPOLL_AVAILABLE) {
+ if (!isEnableMemoryPoolDirect()) {
+ throw new Exception("EPoll mode only support unsafe(direct) memory");
+ }
+ } else {
+ if (Unsafe.UNSAFE_BUF_AVAILABLE) {
+ throw new Exception("Java(Nio) mode can not use unsafe memory");
+ }
+ }
this.allocatorGroup = new ByteBufAllocatorGroup(getEventLoopSize(), memoryPoolCapacity, memoryPoolUnit, enableMemoryPoolDirect);
}
Util.start(getAllocatorGroup());
@@ -197,7 +207,7 @@ public NioEventLoop getNext() {
public ByteBufAllocator getNextByteBufAllocator(int index) {
ByteBufAllocatorGroup group = allocatorGroup;
if (group == null) {
- return UnpooledByteBufAllocator.get(isEnableMemoryPoolDirect());
+ return UnpooledByteBufAllocator.get();
} else {
return group.getAllocator(index);
}
@@ -209,6 +219,9 @@ public int getWriteBuffers() {
public void setWriteBuffers(int writeBuffers) {
checkNotRunning();
+ if (writeBuffers > Byte.MAX_VALUE) {
+ throw new RuntimeException("max write buffer size: " + Byte.MAX_VALUE);
+ }
this.writeBuffers = writeBuffers;
}
diff --git a/firenio-core/src/main/java/com/firenio/component/ProtocolCodec.java b/firenio-core/src/main/java/com/firenio/component/ProtocolCodec.java
index d1a274359..c1ff8478a 100644
--- a/firenio-core/src/main/java/com/firenio/component/ProtocolCodec.java
+++ b/firenio-core/src/main/java/com/firenio/component/ProtocolCodec.java
@@ -59,16 +59,14 @@ protected static IOException EXCEPTION(String method, String msg) {
return EXCEPTION(clazz, method, msg);
}
- protected static int nextIndexedVariablesIndex() {
- return FastThreadLocal.nextIndexedVariablesIndex();
- }
-
// 可能会遭受一种攻击,比如最大可接收数据为100,客户端传输到99后暂停,
// 这样多次以后可能会导致内存溢出
public abstract Frame decode(Channel ch, ByteBuf src) throws Exception;
// 注意:encode失败要release掉encode过程中申请的内存
- public abstract ByteBuf encode(Channel ch, Frame frame) throws Exception;
+ public ByteBuf encode(Channel ch, Frame frame) throws Exception {
+ throw new UnsupportedOperationException();
+ }
public abstract String getProtocolId();
@@ -103,6 +101,19 @@ protected void flush_pong(Channel ch, ByteBuf buf) {
ch.getContext().getHeartBeatLogger().logPongTo(ch);
}
+ protected ByteBuf getPlainReadBuf(NioEventLoop el, Channel ch) {
+ return el.getReadBuf();
+ }
+
+ protected void storePlainReadRemain(Channel ch, ByteBuf src) {
+ ch.slice_remain_plain(src);
+ }
+
+ protected void readPlainRemain(Channel ch, ByteBuf dst) {
+ dst.clear();
+ ch.read_plain_remain(dst);
+ }
+
protected ByteBuf getPingBuf() {
return null;
}
diff --git a/firenio-core/src/main/java/com/firenio/component/ReConnector.java b/firenio-core/src/main/java/com/firenio/component/ReConnector.java
index 041f490d5..c3a70b708 100644
--- a/firenio-core/src/main/java/com/firenio/component/ReConnector.java
+++ b/firenio-core/src/main/java/com/firenio/component/ReConnector.java
@@ -27,6 +27,7 @@ public class ReConnector implements Closeable {
private Logger logger = LoggerFactory.getLogger(getClass());
private volatile boolean reconnect = true;
private long retryTime = 15000;
+ private long timeout = 3000;
public ReConnector(ChannelConnector connector) {
this.connector = connector;
@@ -38,9 +39,20 @@ public synchronized void close() {
this.reconnect = false;
Util.close(connector);
Util.stop(connector.getProcessorGroup());
+ this.notify();
}
public synchronized void connect() {
+ connect(3000);
+ }
+
+ public synchronized void connect(long timeout) {
+ this.reconnect = true;
+ this.timeout = timeout;
+ this.connect0();
+ }
+
+ public synchronized void connect0() {
Channel ch = connector.getChannel();
for (; ; ) {
if (ch != null && ch.isOpen()) {
@@ -52,13 +64,17 @@ public synchronized void connect() {
}
logger.info("begin try to connect");
try {
- connector.connect();
+ connector.connect(timeout);
break;
} catch (Throwable e) {
logger.error(e.getMessage(), e);
}
logger.error("reconnect failed,try reconnect later on {} milliseconds", retryTime);
- Util.sleep(retryTime);
+ try {
+ this.wait(retryTime);
+ } catch (InterruptedException e) {
+ logger.error(e.getMessage(), e);
+ }
}
}
@@ -87,7 +103,7 @@ public void channelClosed(Channel ch) {
Util.exec(new Runnable() {
@Override
public void run() {
- reConnector.connect();
+ reConnector.connect0();
}
});
}
diff --git a/firenio-core/src/main/java/com/firenio/component/SilentExceptionCaughtHandle.java b/firenio-core/src/main/java/com/firenio/component/SilentExceptionCaughtHandle.java
index c55469557..20ee7bbde 100644
--- a/firenio-core/src/main/java/com/firenio/component/SilentExceptionCaughtHandle.java
+++ b/firenio-core/src/main/java/com/firenio/component/SilentExceptionCaughtHandle.java
@@ -21,6 +21,6 @@
public class SilentExceptionCaughtHandle implements ExceptionCaughtHandle {
@Override
- public void exceptionCaught(Channel ch, Frame frame, Exception ex) {}
+ public void exceptionCaught(Channel ch, Frame frame, Throwable ex) {}
}
diff --git a/firenio-core/src/main/java/com/firenio/component/SocketOptions.java b/firenio-core/src/main/java/com/firenio/component/SocketOptions.java
index 1704a076f..700ff984b 100644
--- a/firenio-core/src/main/java/com/firenio/component/SocketOptions.java
+++ b/firenio-core/src/main/java/com/firenio/component/SocketOptions.java
@@ -23,24 +23,26 @@
*/
public final class SocketOptions {
- public static final int PARAM_BOOLEAN;
- public static final int IPPROTO_TCP;
- public static final int SOL_SOCKET;
- public static final int SO_BROADCAST;
- public static final int SO_ERROR;
- public static final int SO_KEEPALIVE;
- public static final int SO_SNDBUF;
- public static final int SO_RCVBUF;
- public static final int SO_REUSEADDR;
- public static final int SO_LINGER;
- public static final int TCP_NODELAY;
- public static final int TCP_QUICKACK;
- private static final Object[] TCP_SOCKET_OPTIONS = new Object[16];
- private static final Object[] SO_SOCKET_OPTIONS = new Object[16];
+ public static final int RAW_IP_PROTO_TCP = 6;
+ public static final int RAW_SOL_SOCKET = 1;
+ public static final int SOL_SOCKET;
+ public static final int SO_BROADCAST;
+ public static final int SO_ERROR;
+ public static final int SO_KEEPALIVE;
+ public static final int SO_SNDBUF;
+ public static final int SO_RCVBUF;
+ public static final int SO_REUSEADDR;
+ public static final int SO_LINGER;
+ public static final int TCP_NODELAY;
+ public static final int TCP_QUICKACK;
+ static final int PARAM_BOOLEAN;
+ static final int IP_PROTO_TCP;
+ static final Object[] TCP_SOCKET_OPTIONS = new Object[16];
+ static final Object[] SO_SOCKET_OPTIONS = new Object[16];
static {
- IPPROTO_TCP = 6 << 16;
- SOL_SOCKET = 1 << 16;
+ IP_PROTO_TCP = RAW_IP_PROTO_TCP << 16;
+ SOL_SOCKET = RAW_SOL_SOCKET << 16;
PARAM_BOOLEAN = 1 << 8;
SO_ERROR = SOL_SOCKET | 4;
SO_BROADCAST = SOL_SOCKET | PARAM_BOOLEAN | 6;
@@ -49,8 +51,8 @@ public final class SocketOptions {
SO_RCVBUF = SOL_SOCKET | 8;
SO_REUSEADDR = SOL_SOCKET | PARAM_BOOLEAN | 2;
SO_LINGER = SOL_SOCKET | 13;
- TCP_NODELAY = IPPROTO_TCP | PARAM_BOOLEAN | 1;
- TCP_QUICKACK = IPPROTO_TCP | PARAM_BOOLEAN | 12;
+ TCP_NODELAY = IP_PROTO_TCP | PARAM_BOOLEAN | 1;
+ TCP_QUICKACK = IP_PROTO_TCP | PARAM_BOOLEAN | 12;
TCP_SOCKET_OPTIONS[TCP_NODELAY & 0xff] = StandardSocketOptions.TCP_NODELAY;
SO_SOCKET_OPTIONS[SO_BROADCAST & 0xff] = StandardSocketOptions.SO_BROADCAST;
SO_SOCKET_OPTIONS[SO_KEEPALIVE & 0xff] = StandardSocketOptions.SO_KEEPALIVE;
@@ -62,7 +64,7 @@ public final class SocketOptions {
@SuppressWarnings("unchecked")
public static SocketOption getSocketOption(int name) {
- if ((name & IPPROTO_TCP) != 0) {
+ if ((name & IP_PROTO_TCP) != 0) {
return (SocketOption) TCP_SOCKET_OPTIONS[name & 0xff];
} else if ((name & SOL_SOCKET) != 0) {
return (SocketOption) SO_SOCKET_OPTIONS[name & 0xff];
diff --git a/firenio-core/src/main/java/com/firenio/component/SslContext.java b/firenio-core/src/main/java/com/firenio/component/SslContext.java
index 015049741..164f3d56f 100644
--- a/firenio-core/src/main/java/com/firenio/component/SslContext.java
+++ b/firenio-core/src/main/java/com/firenio/component/SslContext.java
@@ -31,18 +31,20 @@
import javax.net.ssl.SSLSessionContext;
import com.firenio.Options;
+import com.firenio.common.Unsafe;
import com.firenio.log.Logger;
import com.firenio.log.LoggerFactory;
//ref from netty && undertow
public final class SslContext {
- public static final List ENABLED_CIPHERS;
- public static final String[] ENABLED_PROTOCOLS;
+ public static final List DEFAULT_CIPHERS;
+ public static final List DEFAULT_PROTOCOLS;
public static final boolean OPENSSL_AVAILABLE;
public static final int SSL_PACKET_BUFFER_SIZE;
public static final int SSL_UNWRAP_BUFFER_SIZE;
public static final Set SUPPORTED_CIPHERS;
+ public static final Set SUPPORTED_PROTOCOLS;
static final Logger logger = LoggerFactory.getLogger(SslContext.class);
static {
@@ -53,12 +55,12 @@ public final class SslContext {
}
boolean testOpenSsl = false;
try {
- if (Options.isEnableOpenssl()) {
+ if (Options.isEnableOpenssl() && Unsafe.UNSAFE_AVAILABLE) {
Class.forName("org.wildfly.openssl.OpenSSLProvider");
org.wildfly.openssl.OpenSSLProvider.register();
testOpenSsl = true;
}
- } catch (Exception | Error e) {
+ } catch (Throwable e) {
}
OPENSSL_AVAILABLE = testOpenSsl;
SSLContext context;
@@ -68,64 +70,61 @@ public final class SslContext {
} catch (Exception e) {
throw new Error("failed to initialize the default SSL context", e);
}
- SSL_UNWRAP_BUFFER_SIZE = Options.getSslUnwrapBufferSize(1024 * 256);
SSLEngine engine = context.createSSLEngine();
+ SSL_UNWRAP_BUFFER_SIZE = Options.getSslUnwrapBufferSize(1024 * 256);
SSL_PACKET_BUFFER_SIZE = engine.getSession().getPacketBufferSize();
+
// Choose the sensible default list of protocols.
- final String[] supportedProtocols = engine.getSupportedProtocols();
- Set supportedProtocolsSet = new HashSet<>(supportedProtocols.length);
- supportedProtocolsSet.addAll(Arrays.asList(supportedProtocols));
- List protocols = new ArrayList<>();
- addIfSupported(supportedProtocolsSet, protocols, "TLSv1.3", "TLSv1.2", "TLSv1.1", "TLSv1");
- if (!protocols.isEmpty()) {
- ENABLED_PROTOCOLS = protocols.toArray(new String[0]);
- } else {
- ENABLED_PROTOCOLS = engine.getEnabledProtocols();
- }
+ final String[] supportedProtocols = engine.getSupportedProtocols();
+ SUPPORTED_PROTOCOLS = new HashSet<>(supportedProtocols.length);
+ Collections.addAll(SUPPORTED_PROTOCOLS, supportedProtocols);
+
// Choose the sensible default list of cipher suites.
final String[] supportedCiphers = engine.getSupportedCipherSuites();
SUPPORTED_CIPHERS = new HashSet<>(supportedCiphers.length);
Collections.addAll(SUPPORTED_CIPHERS, supportedCiphers);
- List enabledCiphers = new ArrayList<>();
- addIfSupported(SUPPORTED_CIPHERS, enabledCiphers,
- // GCM (Galois/Counter Mode) requires JDK 8.
- "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
- // AES256 requires JCE unlimited strength jurisdiction
- // policy files.
- "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
- // GCM (Galois/Counter Mode) requires JDK 8.
- "TLS_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA",
- // AES256 requires JCE unlimited strength jurisdiction
- // policy files.
- "TLS_RSA_WITH_AES_256_CBC_SHA");
-
- if (enabledCiphers.isEmpty()) {
- // Use the default from JDK as fallback.
- for (String cipher : engine.getEnabledCipherSuites()) {
- if (cipher.contains("_RC4_")) {
- continue;
- }
- enabledCiphers.add(cipher);
- }
- }
- ENABLED_CIPHERS = Collections.unmodifiableList(enabledCiphers);
- }
-
- private final String[] applicationProtocols;
-
- private final String[] cipherSuites;
-
- private final ClientAuth clientAuth;
+ // default protocols
+ List defaultProtocols = new ArrayList<>();
+ defaultProtocols.add("TLSv1.3");
+ defaultProtocols.add("TLSv1.2");
+ defaultProtocols.add("TLSv1.1");
+
+ // ECDHE == PFS
+ List defaultCiphers = new ArrayList<>();
+ // GCM (Galois/Counter Mode) requires JDK 8.
+ defaultCiphers.add("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384");
+ defaultCiphers.add("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256");
+ defaultCiphers.add("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
+ defaultCiphers.add("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA");
+ // AES256 requires JCE unlimited strength jurisdiction policy files.
+ defaultCiphers.add("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA");
+ // GCM (Galois/Counter Mode) requires JDK 8.
+ defaultCiphers.add("TLS_RSA_WITH_AES_128_GCM_SHA256");
+ defaultCiphers.add("TLS_RSA_WITH_AES_128_CBC_SHA");
+ // AES256 requires JCE unlimited strength jurisdiction policy files.
+ defaultCiphers.add("TLS_RSA_WITH_AES_256_CBC_SHA");
+
+ DEFAULT_PROTOCOLS = Collections.unmodifiableList(defaultProtocols);
+ DEFAULT_CIPHERS = Collections.unmodifiableList(defaultCiphers);
+ }
+
+ private final String[] applicationProtocols;
+ private final String[] cipherSuites;
+ private final String[] protocols;
+ private final ClientAuth clientAuth;
private final boolean isServer;
private final SSLContext sslContext;
private final List unmodifiableCipherSuites;
+ private final List unmodifiableProtocols;
- SslContext(SSLContext sslContext, boolean isServer, List ciphers, ClientAuth clientAuth, String[] applicationProtocols) throws SSLException {
+ SslContext(SSLContext sslContext, boolean isServer, List protocols, List ciphers, ClientAuth clientAuth, String[] applicationProtocols) throws SSLException {
this.applicationProtocols = applicationProtocols;
this.clientAuth = clientAuth;
- this.cipherSuites = filterCipherSuites(ciphers, ENABLED_CIPHERS, SUPPORTED_CIPHERS);
+ this.cipherSuites = filterCipherSuites(ciphers, DEFAULT_CIPHERS, SUPPORTED_CIPHERS);
+ this.protocols = filterCipherSuites(protocols, DEFAULT_PROTOCOLS, SUPPORTED_PROTOCOLS);
this.unmodifiableCipherSuites = Collections.unmodifiableList(Arrays.asList(cipherSuites));
+ this.unmodifiableProtocols = Collections.unmodifiableList(Arrays.asList(this.protocols));
this.sslContext = sslContext;
this.isServer = isServer;
if (applicationProtocols != null && !OPENSSL_AVAILABLE) {
@@ -153,14 +152,19 @@ static SSLContext newSSLContext() throws NoSuchAlgorithmException {
}
}
- public final List cipherSuites() {
+ public final List getCipherSuites() {
return unmodifiableCipherSuites;
}
+ public final List getProtocols() {
+ return unmodifiableProtocols;
+ }
+
private SSLEngine configureEngine(SSLEngine engine) {
engine.setEnabledCipherSuites(cipherSuites);
- engine.setEnabledProtocols(ENABLED_PROTOCOLS);
+ engine.setEnabledProtocols(protocols);
engine.setUseClientMode(isClient());
+
if (isServer()) {
if (clientAuth == ClientAuth.OPTIONAL) {
engine.setWantClientAuth(true);
@@ -176,20 +180,17 @@ private SSLEngine configureEngine(SSLEngine engine) {
}
private String[] filterCipherSuites(List ciphers, List defaultCiphers, Set supportedCiphers) {
- if (ciphers == null) {
- return defaultCiphers.toArray(new String[0]);
- } else {
- List newCiphers = new ArrayList<>();
- for (String c : ciphers) {
- if (c == null) {
- break;
- }
- if (supportedCiphers.contains(c)) {
- newCiphers.add(c);
- }
+ List filter_ciphers = ciphers;
+ if (filter_ciphers == null) {
+ filter_ciphers = defaultCiphers;
+ }
+ List newCiphers = new ArrayList<>();
+ for (String c : filter_ciphers) {
+ if (supportedCiphers.contains(c)) {
+ newCiphers.add(c);
}
- return newCiphers.toArray(new String[0]);
}
+ return newCiphers.toArray(new String[0]);
}
public SSLContext getSSLContext() {
diff --git a/firenio-core/src/main/java/com/firenio/component/SslContextBuilder.java b/firenio-core/src/main/java/com/firenio/component/SslContextBuilder.java
index 82c2014b2..209fdc1bd 100644
--- a/firenio-core/src/main/java/com/firenio/component/SslContextBuilder.java
+++ b/firenio-core/src/main/java/com/firenio/component/SslContextBuilder.java
@@ -16,9 +16,6 @@
package com.firenio.component;
import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidAlgorithmParameterException;
@@ -57,6 +54,7 @@
import com.firenio.common.Cryptos;
import com.firenio.common.FileUtil;
import com.firenio.common.Util;
+import com.firenio.component.SslContext.ClientAuth;
/**
* Builder for configuring a new SslContext for creation.
@@ -66,13 +64,15 @@ public final class SslContextBuilder {
private String[] applicationProtocols;
private List ciphers;
- private SslContext.ClientAuth clientAuth = SslContext.ClientAuth.NONE;
+ private List protocols;
+ private ClientAuth clientAuth = ClientAuth.NONE;
+ private TrustType trustType;
private boolean isServer;
private KeyManagerFactory keyManagerFactory;
private long sessionCacheSize;
private long sessionTimeout;
private TrustManagerFactory trustManagerFactory;
- private TrustType trustType = TrustType.NONE;
+ private List rawX509Certificates;
private X509TrustManager x509TrustManager;
private SslContextBuilder(boolean isServer) {
@@ -80,25 +80,13 @@ private SslContextBuilder(boolean isServer) {
}
public static SslContextBuilder forClient(boolean trustAll) {
- return new SslContextBuilder(false).trustManager(trustAll);
+ return new SslContextBuilder(false).trust(trustAll);
}
public static SslContextBuilder forServer() {
return new SslContextBuilder(true);
}
- static List readCertificates(File file) throws CertificateException {
- InputStream in = null;
- try {
- in = new FileInputStream(file);
- return readCertificates(in);
- } catch (FileNotFoundException e) {
- throw new CertificateException("could not find certificate file: " + file);
- } finally {
- Util.close(in);
- }
- }
-
static List readCertificates(InputStream in) throws CertificateException {
List ls;
try {
@@ -106,10 +94,13 @@ static List readCertificates(InputStream in) throws CertificateException
} catch (IOException e) {
throw new CertificateException("failed to native_read certificate input stream", e);
}
+ return readCertificates(ls);
+ }
+
+ static List readCertificates(List ls) throws CertificateException {
List certs = new ArrayList<>();
StringBuilder b = new StringBuilder();
int readEnd = 0;
-
for (String s : ls) {
if (s.startsWith("----")) {
readEnd++;
@@ -124,7 +115,7 @@ static List readCertificates(InputStream in) throws CertificateException
b.append(s.trim().replace("\r", ""));
}
if (certs.isEmpty()) {
- throw new CertificateException("found no certificates in input stream");
+ throw new CertificateException("found no certificate in input stream");
}
return certs;
}
@@ -136,7 +127,7 @@ public SslContextBuilder applicationProtocols(String[] applicationProtocols) {
public SslContext build() throws SSLException {
SSLContext context = newSSLContext();
- return new SslContext(context, isServer, ciphers, clientAuth, applicationProtocols);
+ return new SslContext(context, isServer, protocols, ciphers, clientAuth, applicationProtocols);
}
private KeyManagerFactory buildKeyManagerFactory(KeyStore ks, char[] keyPasswordChars) throws SSLException {
@@ -199,6 +190,12 @@ public SslContextBuilder ciphers(List ciphers) {
return this;
}
+ public SslContextBuilder protocols(List protocols) {
+ needServer();
+ this.protocols = protocols;
+ return this;
+ }
+
public SslContextBuilder clientAuth(SslContext.ClientAuth clientAuth) {
needServer();
this.clientAuth = clientAuth;
@@ -260,7 +257,7 @@ public SslContextBuilder keyManager(InputStream keyInput, InputStream certChainI
try {
keyCertChain = toX509Certificates(certChainInput);
} catch (Exception e) {
- throw new IllegalArgumentException("Input stream not contain valid certificates.", e);
+ throw new IllegalArgumentException("Input stream not contain valid certificate.", e);
} finally {
Util.close(certChainInput);
}
@@ -321,20 +318,31 @@ private SSLContext newSSLContext() throws SSLException {
KeyManager[] kms = null;
if (isServer) {
kms = keyManagerFactory.getKeyManagers();
- }
- switch (trustType) {
- case ALL:
- tms = new X509TrustManager[]{new TrustAllX509TrustManager()};
- break;
- case TrustManagerFactory:
- tms = trustManagerFactory.getTrustManagers();
- break;
- case X509TrustManager:
- tms = new X509TrustManager[]{x509TrustManager};
- break;
- case NONE:
- default:
- break;
+ } else {
+ switch (trustType) {
+ case ALL:
+ tms = new X509TrustManager[]{new TrustAllX509TrustManager()};
+ break;
+ case TrustManagerFactory:
+ tms = trustManagerFactory.getTrustManagers();
+ break;
+ case X509TrustManager:
+ tms = new X509TrustManager[]{x509TrustManager};
+ break;
+ case RawX509Certificate:
+ if (rawX509Certificates.size() == 1) {
+ tms = new X509TrustManager[]{new TrustOneX509TrustManager(rawX509Certificates.get(0))};
+ } else {
+ X509Certificate[] cs = rawX509Certificates.toArray(new X509Certificate[0]);
+ tms = new X509TrustManager[]{new TrustX509TrustManager(cs)};
+ }
+ break;
+ default:
+ if (!isServer) {
+ throw new SSLException("did not trust anything");
+ }
+ break;
+ }
}
ctx.init(kms, tms, new SecureRandom());
SSLSessionContext sessCtx;
@@ -375,27 +383,41 @@ private PrivateKey toPrivateKey(InputStream keyInputStream, String keyPassword)
return getPrivateKeyFromByteBuffer(readCertificates(keyInputStream).get(0), keyPassword);
}
- private X509Certificate[] toX509Certificates(InputStream in) throws CertificateException {
+ public X509Certificate[] toX509Certificates(InputStream in) throws CertificateException {
Assert.notNull(in, "null inputstream");
return getCertificatesFromBuffers(readCertificates(in));
}
- public SslContextBuilder trustManager(boolean trustAll) {
+ public X509Certificate[] toX509Certificates(List ls) throws CertificateException {
+ Assert.notNull(ls, "null ls");
+ return getCertificatesFromBuffers(readCertificates(ls));
+ }
+
+ public SslContextBuilder trust(boolean trustAll) {
needClient();
trustType = trustAll ? TrustType.ALL : trustType;
return this;
}
- public SslContextBuilder trustManager(InputStream trustCertCollectionInputStream) {
+ public SslContextBuilder trust(InputStream trustCertCollectionInputStream) {
needClient();
try {
- return trustManager(toX509Certificates(trustCertCollectionInputStream));
+ return trust(toX509Certificates(trustCertCollectionInputStream));
} catch (Exception e) {
- throw new IllegalArgumentException("Input stream does not contain valid certificates.", e);
+ throw new IllegalArgumentException("Input stream does not contain valid certificate.", e);
}
}
- public SslContextBuilder trustManager(TrustManagerFactory trustManagerFactory) {
+ public SslContextBuilder trust(List trustCertCollectionLines) {
+ needClient();
+ try {
+ return trust(toX509Certificates(trustCertCollectionLines));
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Input stream does not contain valid certificate.", e);
+ }
+ }
+
+ public SslContextBuilder trust(TrustManagerFactory trustManagerFactory) {
needClient();
Assert.notNull(trustManagerFactory, "null trustManagerFactory");
this.trustManagerFactory = trustManagerFactory;
@@ -403,14 +425,37 @@ public SslContextBuilder trustManager(TrustManagerFactory trustManagerFactory) {
return this;
}
- public SslContextBuilder trustManager(X509Certificate... trustCertCollection) throws SSLException {
+ public SslContextBuilder trustRaw(InputStream trustCertCollection) throws CertificateException {
+ return trustRaw(toX509Certificates(trustCertCollection));
+ }
+
+ public SslContextBuilder trustRaw(List trustCertCollection) throws CertificateException {
+ return trustRaw(toX509Certificates(trustCertCollection));
+ }
+
+ public SslContextBuilder trustRaw(X509Certificate... trustCertCollection) {
+ needClient();
+ Assert.notEmpty(trustCertCollection, "empty trustCertCollection");
+ if (rawX509Certificates == null) {
+ rawX509Certificates = new ArrayList<>(trustCertCollection.length);
+ }
+ for (X509Certificate certificate : trustCertCollection) {
+ if (certificate != null) {
+ rawX509Certificates.add(certificate);
+ }
+ }
+ trustType = TrustType.RawX509Certificate;
+ return this;
+ }
+
+ public SslContextBuilder trust(X509Certificate... trustCertCollection) throws SSLException {
needClient();
Assert.notEmpty(trustCertCollection, "empty trustCertCollection");
- trustManager(buildTrustManagerFactory(trustCertCollection));
+ trust(buildTrustManagerFactory(trustCertCollection));
return this;
}
- public SslContextBuilder trustManager(X509TrustManager x509TrustManager) {
+ public SslContextBuilder trust(X509TrustManager x509TrustManager) {
needClient();
Assert.notNull(x509TrustManager, "null x509TrustManager");
this.x509TrustManager = x509TrustManager;
@@ -420,17 +465,78 @@ public SslContextBuilder trustManager(X509TrustManager x509TrustManager) {
enum TrustType {
- ALL, NONE, TrustManagerFactory, X509TrustManager
+ ALL, TrustManagerFactory, X509TrustManager, RawX509Certificate
+
+ }
+
+ static class TrustAllX509TrustManager implements X509TrustManager {
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] arg0, String arg1) {}
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] arg0, String arg1) { }
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
}
- class TrustAllX509TrustManager implements X509TrustManager {
+
+ static class TrustX509TrustManager implements X509TrustManager {
+
+ final X509Certificate[] certificates;
+
+ TrustX509TrustManager(X509Certificate[] certificates) {
+ this.certificates = certificates;
+ }
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) {}
@Override
- public void checkServerTrusted(X509Certificate[] arg0, String arg1) {}
+ public void checkServerTrusted(X509Certificate[] server_certs, String arg1) throws CertificateException {
+ for (int i = 0; i < certificates.length; i++) {
+ X509Certificate client_cert = certificates[i];
+ for (int j = 0; j < server_certs.length; j++) {
+ if (client_cert.equals(server_certs[j])) {
+ return;
+ }
+ }
+ }
+ throw new CertificateException();
+ }
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ }
+
+ static class TrustOneX509TrustManager implements X509TrustManager {
+
+ X509Certificate certificate;
+
+ TrustOneX509TrustManager(X509Certificate certificate) {
+ this.certificate = certificate;
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] arg0, String arg1) {}
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] server_certs, String arg1) throws CertificateException {
+ X509Certificate client_cert = certificate;
+ for (int i = 0; i < server_certs.length; i++) {
+ if (client_cert.equals(server_certs[i])) {
+ return;
+ }
+ }
+ throw new CertificateException();
+ }
@Override
public X509Certificate[] getAcceptedIssuers() {
diff --git a/firenio-core/src/main/java/com/firenio/concurrent/ExecutorEventLoop.java b/firenio-core/src/main/java/com/firenio/concurrent/ExecutorEventLoop.java
index 172d6a6b4..138cc7b85 100644
--- a/firenio-core/src/main/java/com/firenio/concurrent/ExecutorEventLoop.java
+++ b/firenio-core/src/main/java/com/firenio/concurrent/ExecutorEventLoop.java
@@ -39,7 +39,7 @@ private static void runJob(Runnable job) {
if (job != null) {
try {
job.run();
- } catch (Exception e) {
+ } catch (Throwable e) {
logger.error(e.getMessage(), e);
}
}
diff --git a/firenio-core/src/main/java/com/firenio/concurrent/ScmpLinkedQueue.java b/firenio-core/src/main/java/com/firenio/concurrent/ScmpLinkedQueue.java
deleted file mode 100644
index 26c72cc32..000000000
--- a/firenio-core/src/main/java/com/firenio/concurrent/ScmpLinkedQueue.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2015 The FireNio Project
- *
- * 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 com.firenio.concurrent;
-
-import com.firenio.common.Unsafe;
-
-public class ScmpLinkedQueue extends ScspLinkedQueue {
-
- private static final long tailOffset;
-
- static {
- try {
- tailOffset = Unsafe.objectFieldOffset(ScspLinkedQueue.class.getDeclaredField("tail"));
- } catch (Exception e) {
- throw new Error(e);
- }
- }
-
- public void offer(V v) {
- Node n = new Node<>();
- Node tail = getTail();
- if (Unsafe.compareAndSwapObject(this, tailOffset, tail, n)) {
- tail.v = v;
- tail.next = n;
- incrementAndGet();
- return;
- }
- for (; ; ) {
- tail = getTail();
- if (Unsafe.compareAndSwapObject(this, tailOffset, tail, n)) {
- tail.v = v;
- tail.next = n;
- incrementAndGet();
- return;
- }
- }
- }
-
-}
diff --git a/firenio-core/src/main/java/com/firenio/concurrent/ScspLinkedQueue.java b/firenio-core/src/main/java/com/firenio/concurrent/ScspLinkedQueue.java
deleted file mode 100644
index 36a573483..000000000
--- a/firenio-core/src/main/java/com/firenio/concurrent/ScspLinkedQueue.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2015 The FireNio Project
- *
- * 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 com.firenio.concurrent;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-public class ScspLinkedQueue {
-
- // not sure if this useful
- long p00, p01, p02, p03, p04, p05, p06, p07;
- long p10, p11, p12, p13, p14, p15, p16, p17;
- private volatile Node head = null; // volatile ?
- private AtomicInteger size = new AtomicInteger();
-
- private volatile Node tail = null;
-
- public ScspLinkedQueue() {
- this.head = new Node<>();
- this.tail = head;
- }
-
- Node getTail() {
- return tail;
- }
-
- protected int incrementAndGet() {
- return size.incrementAndGet();
- }
-
- public void offer(V v) {
- Node node = new Node<>();
- tail.v = v;
- tail.next = node;
- tail = node;
- size.incrementAndGet();
- }
-
- public V poll() {
- if (size.get() == 0) {
- return null;
- }
- size.decrementAndGet();
- Node h = head;
- head = h.next;
- return h.v;
- }
-
- public int size() {
- return size.get();
- }
-
- static class Node {
- Node next;
- V v;
- }
-
-}
diff --git a/firenio-core/src/main/java/com/firenio/concurrent/ThreadEventLoop.java b/firenio-core/src/main/java/com/firenio/concurrent/ThreadEventLoop.java
index 3d962f9c8..f0272b903 100644
--- a/firenio-core/src/main/java/com/firenio/concurrent/ThreadEventLoop.java
+++ b/firenio-core/src/main/java/com/firenio/concurrent/ThreadEventLoop.java
@@ -37,7 +37,7 @@ private static void runJob(Runnable job) {
if (job != null) {
try {
job.run();
- } catch (Exception e) {
+ } catch (Throwable e) {
logger.error(e.getMessage(), e);
}
}
@@ -49,7 +49,7 @@ protected void doLoop() throws InterruptedException {
}
@Override
- protected void doStart() throws Exception {
+ protected void doStart() {
int maxQueueSize = group.getMaxQueueSize();
this.jobs = new ArrayBlockingQueue<>(maxQueueSize);
}
diff --git a/firenio-core/src/main/java/com/firenio/concurrent/Waiter.java b/firenio-core/src/main/java/com/firenio/concurrent/Waiter.java
index d2f3fb806..a750397c1 100644
--- a/firenio-core/src/main/java/com/firenio/concurrent/Waiter.java
+++ b/firenio-core/src/main/java/com/firenio/concurrent/Waiter.java
@@ -42,12 +42,6 @@ public void await() {
await(0);
}
- /**
- * return true is timeout
- *
- * @param timeout
- * @return timeouted
- */
public void await(long timeout) {
synchronized (lock) {
if (!isDone) {
diff --git a/firenio-core/src/main/resources/native.o b/firenio-core/src/main/resources/native.o
old mode 100644
new mode 100755
index 1e38cb1ec..c4269f0c8
Binary files a/firenio-core/src/main/resources/native.o and b/firenio-core/src/main/resources/native.o differ
diff --git a/firenio-epoll/src/Native.cpp b/firenio-epoll/src/Native.cpp
index 29a56e549..d65ab8474 100644
--- a/firenio-epoll/src/Native.cpp
+++ b/firenio-epoll/src/Native.cpp
@@ -3,6 +3,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -12,6 +13,7 @@
#include
#include
#include
+#include
#include
@@ -294,6 +296,51 @@ static inline int make_socket_non_blocking(int fd){
return 0;
}
+JNIEXPORT jint JNICALL Java_com_firenio_component_Native_open0
+ (JNIEnv * e, jclass c,jstring path,jint op, jint pem){
+ const char *file_path = e->GetStringUTFChars(path, NULL);
+ return open(file_path, op, pem);
+ }
+
+JNIEXPORT jlong JNICALL Java_com_firenio_component_Native_posix_1memalign_1allocate0
+ (JNIEnv * e, jclass c, jint len, jint align){
+ unsigned char *buf;
+ int ret = posix_memalign((void **) &buf, align, len);
+ if (ret < 0) {
+ return ret;
+ }
+ return (jlong) buf;
+ }
+
+JNIEXPORT jlong JNICALL Java_com_firenio_component_Native_file_1length0
+ (JNIEnv * e, jclass c, jint fd){
+ struct stat stbuf;
+ int ret = fstat(fd, &stbuf);
+ if (( ret < 0) ) {
+ return ret;
+ }
+ if((!S_ISREG(stbuf.st_mode))){
+ return 0;
+ }
+ return (jlong)(stbuf.st_size);
+ }
+
+JNIEXPORT jlong JNICALL Java_com_firenio_component_Native_lseek0
+ (JNIEnv * e, jclass c, jint fd, jlong off, jint seek_mode){
+ return (jlong)(lseek(fd, off, seek_mode));
+ }
+
+JNIEXPORT jint JNICALL Java_com_firenio_component_Native_pread0
+ (JNIEnv * e, jclass c, jint fd, jlong address, jint len, jlong off){
+ return pread(fd, (void *)address, len, off);
+ }
+
+JNIEXPORT jint JNICALL Java_com_firenio_component_Native_pwrite0
+ (JNIEnv * e, jclass c, jint fd, jlong address, jint len, jlong off){
+ return pwrite(fd, (void *)address, len, off);
+ }
+
+
int main(){ return 0;}
#ifdef __cplusplus
diff --git a/firenio-homepage/conf/server.properties b/firenio-homepage/conf/server.properties
index 06666b09e..8cf12842e 100644
--- a/firenio-homepage/conf/server.properties
+++ b/firenio-homepage/conf/server.properties
@@ -25,3 +25,4 @@ server.writeBuffers=8
app.enableHttp2=false
#app.webRoot=C:/GIT/weixin-h5
app.welcome=/index.html
+app.proxy=false
diff --git a/firenio-homepage/http-startup.sh b/firenio-homepage/http-startup.sh
index 1e585f0e3..17dc9494e 100644
--- a/firenio-homepage/http-startup.sh
+++ b/firenio-homepage/http-startup.sh
@@ -1,3 +1,5 @@
+#!/bin/bash
+
cd ../firenio
mvn clean install -DskipTests
@@ -23,9 +25,13 @@ done
PRG="$0"
PRGDIR=`dirname "$PRG"`
-java -XX:+PrintGCDetails -Xloggc:gc.log -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=6666,suspend=n \
+(java -XX:+PrintGCDetails -Xloggc:gc.log -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=6666,suspend=n \
-cp $CLASSPATH \
-Dboot.mode=prod \
-Dboot.libPath=/app/lib \
+ -Dorg.wildfly.openssl.path=$1 \
-Dboot.class=sample.http11.startup.TestHttpBootstrapEngine \
- com.firenio.container.Bootstrap
+ com.firenio.container.Bootstrap) &
+
+## echo -17 > /proc/$(ps -ef | grep java | grep -v grep | awk '{print $2}')/oom_adj && cat /proc/$(ps -ef | grep java | grep -v grep | awk '{print $2}')/oom_adj
+
diff --git a/firenio-sample/sample-http/pom.xml b/firenio-sample/sample-http/pom.xml
index 47ad79a11..c244e3941 100644
--- a/firenio-sample/sample-http/pom.xml
+++ b/firenio-sample/sample-http/pom.xml
@@ -105,7 +105,7 @@
com.alibaba
fastjson
- 1.2.31
+ 1.2.62
@@ -117,25 +117,25 @@
com.firenio
firenio-codec
- 1.2.2-SNAPSHOT
+ 1.3.2-SNAPSHOT
org.wildfly.openssl
wildfly-openssl-windows-x86_64
- 1.0.6.Final
+ 1.0.8.Final
org.wildfly.openssl
wildfly-openssl-linux-x86_64
- 1.0.6.Final
+ 1.0.8.Final
org.wildfly.openssl
wildfly-openssl-java
- 1.0.6.Final
+ 1.0.8.Final
javax.annotation
diff --git a/firenio-sample/sample-http/src/main/java/sample/http11/HttpFrameHandle.java b/firenio-sample/sample-http/src/main/java/sample/http11/HttpFrameHandle.java
index 3a8cb7ca6..3ac8fe1ba 100644
--- a/firenio-sample/sample-http/src/main/java/sample/http11/HttpFrameHandle.java
+++ b/firenio-sample/sample-http/src/main/java/sample/http11/HttpFrameHandle.java
@@ -39,7 +39,7 @@
import com.firenio.log.Logger;
import com.firenio.log.LoggerFactory;
-//FIXME limit too large file
+//FIXME writeIndex too large file
public class HttpFrameHandle extends IoEventHandle {
private Charset charset = Util.UTF8;
@@ -97,7 +97,7 @@ protected void acceptHtml(Channel ch, Frame frame) throws Exception {
public void destroy(ChannelContext context) {}
@Override
- public void exceptionCaught(Channel ch, Frame frame, Exception ex) {
+ public void exceptionCaught(Channel ch, Frame frame, Throwable ex) {
logger.error(ex.getMessage(), ex);
frame.release();
if (!ch.isOpen()) {
@@ -347,9 +347,7 @@ long getLastModifyGTMTime() {
}
void setBinary(byte[] readBytesByFile) {
- ByteBuf content = ByteBuf.wrap(readBytesByFile);
- content.position(content.limit());
- this.content = content;
+ this.content = ByteBuf.wrapAuto(readBytesByFile);
}
void setContentType(HttpContentType contentType) {
diff --git a/firenio-sample/sample-http/src/main/java/sample/http11/proxy/HttpProxyServer.java b/firenio-sample/sample-http/src/main/java/sample/http11/proxy/HttpProxyServer.java
index b2168e31a..7d703c0cd 100644
--- a/firenio-sample/sample-http/src/main/java/sample/http11/proxy/HttpProxyServer.java
+++ b/firenio-sample/sample-http/src/main/java/sample/http11/proxy/HttpProxyServer.java
@@ -30,7 +30,6 @@
import com.firenio.component.Channel;
import com.firenio.component.ChannelAcceptor;
import com.firenio.component.ChannelConnector;
-import com.firenio.component.ChannelEventListenerAdapter;
import com.firenio.component.Frame;
import com.firenio.component.IoEventHandle;
import com.firenio.component.LoggerChannelOpenListener;
@@ -41,7 +40,7 @@
public class HttpProxyServer {
static final String CONNECT_RES = "HTTP/1.1 200 Connection Established\r\n\r\n";
- static final ByteBuf CONNECT_RES_BUF = ByteBuf.wrap(CONNECT_RES.getBytes());
+ static final ByteBuf CONNECT_RES_BUF = ByteBuf.wrapAuto(CONNECT_RES.getBytes());
static final HttpProxyServer server = new HttpProxyServer();
private ChannelAcceptor context;
@@ -106,7 +105,7 @@ public void accept(Channel ch, Frame frame) throws Exception {
ClientHttpFrame res = (ClientHttpFrame) frame;
IntMap hs = res.getResponse_headers();
for (hs.scan(); hs.hasNext(); ) {
- String v = hs.nextValue();
+ String v = hs.value();
if (v == null) {
continue;
}
@@ -126,7 +125,6 @@ public void accept(Channel ch, Frame frame) throws Exception {
});
String url = parseRequestURL(f.getRequestURL());
context.setPrintConfig(false);
- context.addChannelEventListener(new HttpProxyAttrListener());
context.addChannelEventListener(new LoggerChannelOpenListener());
context.connect((ch, ex) -> {
if (ex == null) {
@@ -150,20 +148,16 @@ public void accept(Channel ch, Frame frame) throws Exception {
context = new ChannelAcceptor(group, 8088);
context.addProtocolCodec(new HttpProxyCodec());
context.setIoEventHandle(eventHandle);
- context.addChannelEventListener(new HttpProxyAttrListener());
context.addChannelEventListener(new LoggerChannelOpenListener());
context.bind();
}
- static class HttpProxyAttrListener extends ChannelEventListenerAdapter {
+ static class HttpProxyCodec extends HttpCodec {
@Override
- public void channelOpened(Channel ch) {
- ch.setAttachment(new HttpProxyAttr());
+ protected Object newAttachment() {
+ return new HttpProxyAttr();
}
- }
-
- static class HttpProxyCodec extends HttpCodec {
@Override
public Frame decode(final Channel ch_src, ByteBuf src) throws Exception {
@@ -176,14 +170,9 @@ public Frame decode(final Channel ch_src, ByteBuf src) throws Exception {
@Override
public Frame decode(Channel ch, ByteBuf src) {
- ByteBuf buf = ch_src.alloc().allocate(src.remaining());
- buf.putBytes(src);
- ch_src.writeAndFlush(buf.flip());
- return null;
- }
-
- @Override
- public ByteBuf encode(Channel ch, Frame frame) {
+ ByteBuf buf = ch_src.alloc().allocate(src.readableBytes());
+ buf.writeBytes(src);
+ ch_src.writeAndFlush(buf);
return null;
}
@@ -199,12 +188,12 @@ public int getHeaderLength() {
});
context.setPrintConfig(false);
context.addChannelEventListener(new LoggerChannelOpenListener());
- ByteBuf buf = ch_src.alloc().allocate(src.remaining());
- buf.putBytes(src);
+ ByteBuf buf = ch_src.alloc().allocate(src.readableBytes());
+ buf.writeBytes(src);
s.connector = context;
s.connector.connect((ch_target, ex) -> {
if (ex == null) {
- ch_target.writeAndFlush(buf.flip());
+ ch_target.writeAndFlush(buf);
} else {
buf.release();
HttpProxyAttr.remove(ch_src);
@@ -212,9 +201,9 @@ public int getHeaderLength() {
}
});
} else {
- ByteBuf buf = ch_src.alloc().allocate(src.remaining());
- buf.putBytes(src);
- s.connector.getChannel().writeAndFlush(buf.flip());
+ ByteBuf buf = ch_src.alloc().allocate(src.readableBytes());
+ buf.writeBytes(src);
+ s.connector.getChannel().writeAndFlush(buf);
}
return null;
}
diff --git a/firenio-sample/sample-http/src/main/java/sample/http11/proxy4cloud/HttpProxy4CloudServer.java b/firenio-sample/sample-http/src/main/java/sample/http11/proxy4cloud/HttpProxy4CloudServer.java
index ae9503ad3..51d447ce1 100644
--- a/firenio-sample/sample-http/src/main/java/sample/http11/proxy4cloud/HttpProxy4CloudServer.java
+++ b/firenio-sample/sample-http/src/main/java/sample/http11/proxy4cloud/HttpProxy4CloudServer.java
@@ -19,6 +19,8 @@
import java.net.InetSocketAddress;
import java.net.Socket;
+import sample.http11.proxy.HttpProxyServer.HttpProxyAttr;
+
import com.firenio.buffer.ByteBuf;
import com.firenio.codec.http11.HttpAttachment;
import com.firenio.codec.http11.HttpCodec;
@@ -41,7 +43,7 @@
public class HttpProxy4CloudServer {
static final String CONNECT_RES = "HTTP/1.1 200 Connection Established\r\n\r\n";
- static final ByteBuf CONNECT_RES_BUF = ByteBuf.wrap(CONNECT_RES.getBytes());
+ static final ByteBuf CONNECT_RES_BUF = ByteBuf.wrapAuto(CONNECT_RES.getBytes());
static final String netHost;
static final int netPort = 18088;
static final HttpProxy4CloudServer server = new HttpProxy4CloudServer();
@@ -131,18 +133,12 @@ public Frame decode(final Channel ch_src, ByteBuf src) throws Exception {
@Override
public Frame decode(Channel ch, ByteBuf src) {
Channel t = (Channel) ch.getAttachment();
- ByteBuf buf = t.alloc().allocate(src.remaining());
- buf.putBytes(src);
- buf.flip();
+ ByteBuf buf = t.alloc().allocate(src.readableBytes());
+ buf.writeBytes(src);
t.writeAndFlush(buf);
return null;
}
- @Override
- public ByteBuf encode(Channel ch, Frame frame) {
- return null;
- }
-
@Override
public String getProtocolId() {
return "http-proxy-connect";
@@ -163,12 +159,12 @@ public int getHeaderLength() {
byte[] host_bytes = host.getBytes();
int len = 5 + host_bytes.length;
ByteBuf head = ch_target.alloc().allocate(len);
- head.putByte((byte) host_bytes.length);
- head.putByte((byte) 83);
- head.putByte((byte) 38);
- head.putShort(port);
- head.putBytes(host_bytes);
- ch_target.writeAndFlush(head.flip());
+ head.writeByte((byte) host_bytes.length);
+ head.writeByte((byte) 83);
+ head.writeByte((byte) 38);
+ head.writeShort(port);
+ head.writeBytes(host_bytes);
+ ch_target.writeAndFlush(head);
el.schedule(new DelayTask(10) {
@Override
public void run() {
@@ -183,9 +179,8 @@ public void run() {
}
return null;
} else {
- ByteBuf buf = t.alloc().allocate(src.remaining());
- buf.putBytes(src);
- buf.flip();
+ ByteBuf buf = t.alloc().allocate(src.readableBytes());
+ buf.writeBytes(src);
t.writeAndFlush(buf);
}
return null;
diff --git a/firenio-sample/sample-http/src/main/java/sample/http11/proxy4cloud/NetDataTransferServer.java b/firenio-sample/sample-http/src/main/java/sample/http11/proxy4cloud/NetDataTransferServer.java
index 2e9bbf36a..b389209c9 100644
--- a/firenio-sample/sample-http/src/main/java/sample/http11/proxy4cloud/NetDataTransferServer.java
+++ b/firenio-sample/sample-http/src/main/java/sample/http11/proxy4cloud/NetDataTransferServer.java
@@ -68,7 +68,7 @@ public Frame decode(Channel ch, ByteBuf src) throws Exception {
Channel t = (Channel) ch.getAttachment();
if (t == null) {
short hostLen = src.getUnsignedByte(0);
- if (src.remaining() < hostLen + 5) {
+ if (src.readableBytes() < hostLen + 5) {
ch.close();
return null;
}
@@ -80,8 +80,8 @@ public Frame decode(Channel ch, ByteBuf src) throws Exception {
}
byte[] hostBytes = new byte[hostLen];
int port = src.getUnsignedShort(3);
- src.skip(5);
- src.getBytes(hostBytes);
+ src.skipRead(5);
+ src.readBytes(hostBytes);
String host = new String(hostBytes);
NioEventLoop el = ch.getEventLoop();
ChannelConnector context = new ChannelConnector(el, host, port);
@@ -101,18 +101,12 @@ public Frame decode(Channel ch, ByteBuf src) throws Exception {
}, 10000);
return null;
}
- ByteBuf buf = t.alloc().allocate(src.remaining());
- buf.putBytes(src);
- buf.flip();
+ ByteBuf buf = t.alloc().allocate(src.readableBytes());
+ buf.writeBytes(src);
t.writeAndFlush(buf);
return null;
}
- @Override
- public ByteBuf encode(Channel ch, Frame frame) {
- return null;
- }
-
@Override
public String getProtocolId() {
return "NetDataTransfer";
diff --git a/firenio-sample/sample-http/src/main/java/sample/http11/service/TestEmojiServlet.java b/firenio-sample/sample-http/src/main/java/sample/http11/service/TestEmojiServlet.java
index 62a77c34c..759821bfd 100644
--- a/firenio-sample/sample-http/src/main/java/sample/http11/service/TestEmojiServlet.java
+++ b/firenio-sample/sample-http/src/main/java/sample/http11/service/TestEmojiServlet.java
@@ -45,7 +45,7 @@ protected void doAccept(Channel ch, HttpFrame frame) throws Exception {
List emojiList = EmojiUtil.bytes2Emojis(emoji.getBytes(Util.UTF8));
- String limitStr = frame.getRequestParam("limit");
+ String limitStr = frame.getRequestParam("writeIndex");
int limit;
if (Util.isNullOrBlank(limitStr)) {
limit = emojiList.size();
@@ -68,9 +68,7 @@ protected void doAccept(Channel ch, HttpFrame frame) throws Exception {
builder.append(HttpUtil.HTML_POWER_BY);
// builder.append(getScript());
builder.append(HttpUtil.HTML_BOTTOM);
- ByteBuf buf = ByteBuf.wrap(builder.toString().getBytes(ch.getCharset()));
- buf.position(buf.limit());
- frame.setContent(buf);
+ frame.setContent(ByteBuf.wrapAuto(builder.toString().getBytes(ch.getCharset())));
frame.setContentType(HttpContentType.text_html_utf8);
ch.writeAndFlush(frame);
}
diff --git a/firenio-sample/sample-http/src/main/java/sample/http11/service/TestShowMemoryServlet.java b/firenio-sample/sample-http/src/main/java/sample/http11/service/TestShowMemoryServlet.java
index 9bf73b726..b8664aaef 100644
--- a/firenio-sample/sample-http/src/main/java/sample/http11/service/TestShowMemoryServlet.java
+++ b/firenio-sample/sample-http/src/main/java/sample/http11/service/TestShowMemoryServlet.java
@@ -24,6 +24,7 @@
import com.firenio.buffer.ByteBufAllocatorGroup;
import com.firenio.codec.http11.HttpContentType;
import com.firenio.codec.http11.HttpFrame;
+import com.firenio.collection.DelayedQueue.DelayTask;
import com.firenio.common.DateUtil;
import com.firenio.common.Util;
import com.firenio.component.Channel;
@@ -49,7 +50,15 @@ protected void doAccept(Channel ch, HttpFrame f) throws Exception {
String kill = f.getRequestParam("kill");
if (!Util.isNullOrBlank(kill)) {
Integer id = Integer.valueOf(kill, 16);
- Util.close(CountChannelListener.chs.get(id));
+ Channel close_ch = CountChannelListener.chs.get(id);
+ if (close_ch != null){
+ close_ch.getEventLoop().schedule(new DelayTask(10) {
+ @Override
+ public void run() {
+ Util.close(close_ch);
+ }
+ });
+ }
}
BigDecimal time = new BigDecimal(Util.now_f() - context.getStartupTime());
diff --git a/firenio-sample/sample-http/src/main/java/sample/http11/service/WebSocketMsgAdapter.java b/firenio-sample/sample-http/src/main/java/sample/http11/service/WebSocketMsgAdapter.java
index b97bfcbf9..3d1226002 100644
--- a/firenio-sample/sample-http/src/main/java/sample/http11/service/WebSocketMsgAdapter.java
+++ b/firenio-sample/sample-http/src/main/java/sample/http11/service/WebSocketMsgAdapter.java
@@ -21,7 +21,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
-import com.firenio.codec.http11.WebSocketCodec;
+import com.firenio.buffer.ByteBuf;
import com.firenio.codec.http11.WebSocketFrame;
import com.firenio.component.Channel;
import com.firenio.component.ChannelManager;
@@ -40,7 +40,7 @@ public WebSocketMsgAdapter(String threadName) {
super(threadName);
}
- public void addClient(String username, Channel ch) {
+ public synchronized void addClient(String username, Channel ch) {
clientMap.put(ch.getChannelId(), new Client(ch, username));
channelMap.put(username, ch);
logger.info("client joined {} ,clients size: {}", ch, clientMap.size());
@@ -52,23 +52,32 @@ protected void doLoop() throws InterruptedException {
if (msg == null) {
return;
}
- Channel ch = msg.ch;
- if (ch != null) {
+ if (msg.ch != null) {
WebSocketFrame f = new WebSocketFrame();
- f.setString(msg.msg, ch);
+ f.setString(msg.msg, msg.ch);
try {
- ch.writeAndFlush(f);
+ msg.ch.writeAndFlush(f);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
} else {
if (!clientMap.isEmpty()) {
- WebSocketFrame f = new WebSocketFrame();
- f.setBytes(WebSocketCodec.MAX_HEADER_LENGTH, msg.msg.getBytes());
- try {
- ChannelManager.broadcast(f, channelMap.values());
- } catch (Exception e) {
- logger.error(e.getMessage(), e);
+ synchronized (this) {
+ Client client = clientMap.values().iterator().next();
+ Channel ch = client.channel;
+ WebSocketFrame f = new WebSocketFrame();
+ byte[] data = msg.msg.getBytes();
+ ByteBuf buf = ch.allocate(data.length);
+ buf.writeBytes(data);
+ f.setContent(buf);
+ ByteBuf buf2 = null;
+ try {
+ buf2 = ch.getCodec().encode(ch, f);
+ ChannelManager.broadcast(buf2, channelMap.values());
+ } catch (Exception e) {
+ buf.release();
+ logger.error(e.getMessage(), e);
+ }
}
}
}
@@ -87,7 +96,7 @@ public BlockingQueue getJobs() {
return msgs;
}
- public Client removeClient(Channel ch) {
+ public synchronized Client removeClient(Channel ch) {
Client client = clientMap.remove(ch.getChannelId());
if (client != null) {
channelMap.remove(client.getUsername());
diff --git a/firenio-sample/sample-http/src/main/java/sample/http11/startup/TestHttpBootstrapEngine.java b/firenio-sample/sample-http/src/main/java/sample/http11/startup/TestHttpBootstrapEngine.java
index d91df29e1..4dc01fc1c 100644
--- a/firenio-sample/sample-http/src/main/java/sample/http11/startup/TestHttpBootstrapEngine.java
+++ b/firenio-sample/sample-http/src/main/java/sample/http11/startup/TestHttpBootstrapEngine.java
@@ -15,6 +15,10 @@
*/
package sample.http11.startup;
+import sample.http11.SpringHttpFrameHandle;
+import sample.http11.proxy4cloud.NetDataTransferServer;
+import sample.http11.service.CountChannelListener;
+
import com.firenio.DevelopConfig;
import com.firenio.LifeCycle;
import com.firenio.LifeCycleListener;
@@ -26,6 +30,7 @@
import com.firenio.codec.http2.Http2Codec;
import com.firenio.common.FileUtil;
import com.firenio.common.Properties;
+import com.firenio.common.Util;
import com.firenio.component.ChannelAcceptor;
import com.firenio.component.ChannelAliveListener;
import com.firenio.component.ConfigurationParser;
@@ -36,10 +41,6 @@
import com.firenio.log.Logger;
import com.firenio.log.LoggerFactory;
-import sample.http11.SpringHttpFrameHandle;
-import sample.http11.proxy4cloud.NetDataTransferServer;
-import sample.http11.service.CountChannelListener;
-
/**
* @author wangkai
*/
@@ -51,7 +52,11 @@ public class TestHttpBootstrapEngine implements BootstrapEngine {
public void bootstrap(final String rootPath, final String mode) throws Exception {
DevelopConfig.NATIVE_DEBUG = true;
DevelopConfig.BUF_DEBUG = true;
+ DevelopConfig.SSL_DEBUG = true;
+ DevelopConfig.CHANNEL_DEBUG = true;
+ Options.setBufRecycle(false);
Options.setEnableEpoll(true);
+ Options.setEnableUnsafe(true);
Options.setEnableOpenssl(true);
Options.setBufThreadYield(true);
Options.setDebugError(true);
@@ -64,8 +69,8 @@ public void bootstrap(final String rootPath, final String mode) throws Exception
ConfigurationParser.parseConfiguration("server.", context, properties);
ConfigurationParser.parseConfiguration("server.", group, properties);
context.setIoEventHandle(handle);
- context.addChannelEventListener(new WebSocketChannelListener());
context.addChannelIdleEventListener(new ChannelAliveListener());
+ context.addChannelEventListener(new WebSocketChannelListener());
context.addChannelEventListener(new LoggerChannelOpenListener());
context.addChannelEventListener(new CountChannelListener());
context.setExecutorGroup(new ThreadEventLoopGroup());
@@ -92,7 +97,20 @@ public void lifeCycleStopped(LifeCycle lifeCycle) {
context.addProtocolCodec(new WebSocketCodec());
}
context.bind();
- NetDataTransferServer.get().startup(group, 18088);
+ if (properties.getBooleanProperty("app.proxy")) {
+ NetDataTransferServer.get().startup(group, 18088);
+ }
+ Util.exec(() -> {
+ Util.sleep(1000 * 60 * 30);
+ for (; ; ) {
+ Util.sleep(1000 * 60);
+ logger.info("server is running....:" + (Runtime.getRuntime().totalMemory() / 1024 / 1024));
+ }
+ });
+ Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+ logger.info("server shutdown....");
+ }));
+
}
}
diff --git a/firenio-sample/sample-http/src/main/resources/app/html/favicon.ico b/firenio-sample/sample-http/src/main/resources/app/html/favicon.ico
index 57356136d..3dd6d4be8 100644
Binary files a/firenio-sample/sample-http/src/main/resources/app/html/favicon.ico and b/firenio-sample/sample-http/src/main/resources/app/html/favicon.ico differ
diff --git a/firenio-sample/sample-http/src/main/resources/server.properties b/firenio-sample/sample-http/src/main/resources/server.properties
index c8084b6af..8ba266850 100644
--- a/firenio-sample/sample-http/src/main/resources/server.properties
+++ b/firenio-sample/sample-http/src/main/resources/server.properties
@@ -1,16 +1,16 @@
###################################### server basic properties ######################################
server.host=0.0.0.0
server.port=
-server.bufRecycleSize
+server.bufRecycleSize=
server.charset=utf-8
server.channelReadBuffer=524288
server.enableMemoryPool=true
-server.enableMemoryPoolDirect=true
+server.enableMemoryPoolDirect=
server.enableHeartbeatLog=true
server.enableWorkEventLoop=true
server.eventLoopSize=2
server.idleTime=300000
-server.memoryPoolRate
+server.memoryPoolRate=
server.memoryPoolUnit=16
server.memoryPoolCapacity=512000
server.maxWriteBacklog=64
@@ -26,3 +26,4 @@ server.writeBuffers=8
app.enableHttp2=false
#app.webRoot=C:\\工作仓库\\yxaAdmin\\docs
#app.welcome=/index.html
+app.proxy=false
diff --git a/firenio-test/pom.xml b/firenio-test/pom.xml
index 5da8b6cd8..e1de88335 100644
--- a/firenio-test/pom.xml
+++ b/firenio-test/pom.xml
@@ -93,13 +93,13 @@
io.netty
netty-all
- 4.1.36.Final
+ 4.1.43.Final
io.undertow
undertow-core
- 2.0.16.Final
+ 2.0.28.Final
@@ -117,13 +117,19 @@
com.alibaba
fastjson
- 1.2.49
+ 1.2.62
org.elasticsearch.client
transport
6.4.2
+
+
+ io.netty
+ *
+
+
diff --git a/firenio-test/src/main/java/test/io/Test1.java b/firenio-test/src/main/java/test/io/Test1.java
index 5d65e8944..f1963694e 100644
--- a/firenio-test/src/main/java/test/io/Test1.java
+++ b/firenio-test/src/main/java/test/io/Test1.java
@@ -11,61 +11,8 @@ public class Test1 {
public static void main(String[] args) {
- // testMyMap();
- // testNettyMap();
- Options.setSysClockStep(1);
- System.out.println("t1:" + Util.now());
- Util.sleep(100);
- System.out.println("t2:" + Util.now());
- long old = Util.now_f();
- long count = 1024 * 1024 * 512;
- for (long i = 0; i < count; i++) {
- Util.now();
- }
- long past = Util.past(old);
- System.out.println("Time:" + past);
- }
-
- static void testNettyMap() {
- Random r = new Random();
- IntMap map = new IntMap<>(4, 0.75f);
- for (int i = 0; i < 1000; i++) {
- int k = r.nextInt(Integer.MAX_VALUE);
- String v = String.valueOf(k);
- map.put(k, v);
- }
- DebugUtil.info("c:{}", map.conflict());
- }
- static void testMyMap() {
- Random r = new Random();
- IntMap map = new IntMap<>(4, 0.75f);
- for (int i = 0; i < 20; i++) {
- int k = r.nextInt(Integer.MAX_VALUE);
- String v = String.valueOf(k);
- map.put(k, v);
- }
- DebugUtil.info("c:{}", map.conflict());
- int s = 0;
- for (map.scan(); map.hasNext(); ) {
- s++;
- int i = map.next();
- int k = map.indexKey(i);
- String v = map.indexValue(i);
- if (i % 2 == 0) {
- int idx = map.indexKey(i + 1);
- if (idx != -1) {
- String res = map.remove(idx);
- if (res != null) {
- s++;
- }
- }
- } else {
- map.remove(k);
- }
- }
- DebugUtil.info("s:{}", s);
}
}
diff --git a/firenio-test/src/main/java/test/io/Test7.java b/firenio-test/src/main/java/test/io/Test7.java
new file mode 100644
index 000000000..3ad4a4d56
--- /dev/null
+++ b/firenio-test/src/main/java/test/io/Test7.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.io;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.util.Base64;
+
+import sun.reflect.misc.FieldUtil;
+
+import com.firenio.common.Cryptos;
+import com.firenio.common.FileUtil;
+import com.firenio.common.Unsafe;
+import com.firenio.common.Util;
+
+/**
+ * @author: wangkai
+ **/
+public class Test7 {
+
+ public static void main(String[] args) throws Exception {
+ String str = "{\"X03\":\"G418Response\",\"X11\":false,\"X13\":true,\"X15\":4168,\"X17\":\"74137377\",\"X18\":\"zj003\",\"X19\":\"C\",\"X39\":\"00000000\",\"listData\":[{\"CUSTTRADEID\":\"0025110000000025\",\"INNERCLIENTID\":\"0000000001\",\"USERCODE\":\"_ST_0000000001\",\"CLIENTABBR\":\"自营紫金矿业\",\"SEATID\":\"002511\",\"CLIENTNAME\":\"紫金矿业\"},{\"CUSTTRADEID\":\"0025210100000900\",\"INNERCLIENTID\":\"0000000002\",\"USERCODE\":\"_ST_0000000002\",\"CLIENTABBR\":\"代理泉州宝辉\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"泉州宝辉\"},{\"CUSTTRADEID\":\"0025210100003161\",\"INNERCLIENTID\":\"0000000003\",\"USERCODE\":\"_ST_0000000003\",\"CLIENTABBR\":\"代理贵州紫金\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"贵州紫金\"},{\"CUSTTRADEID\":\"0025210100003251\",\"INNERCLIENTID\":\"0000000004\",\"USERCODE\":\"_ST_0000000004\",\"CLIENTABBR\":\"代理上杭金山\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"上杭金山\"},{\"CUSTTRADEID\":\"0025210100003374\",\"INNERCLIENTID\":\"0000000005\",\"USERCODE\":\"_ST_0000000005\",\"CLIENTABBR\":\"代理上杭华辉\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"上杭华辉\"},{\"CUSTTRADEID\":\"0025210100005310\",\"INNERCLIENTID\":\"0000000006\",\"USERCODE\":\"_ST_0000000006\",\"CLIENTABBR\":\"代理厦门紫金\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"厦门紫金\"},{\"CUSTTRADEID\":\"0025210100007075\",\"INNERCLIENTID\":\"0000000007\",\"USERCODE\":\"_ST_0000000007\",\"CLIENTABBR\":\"代理福建金怡\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"福建金怡\"},{\"CUSTTRADEID\":\"0025210100007693\",\"INNERCLIENTID\":\"0000000008\",\"USERCODE\":\"_ST_0000000008\",\"CLIENTABBR\":\"代理四川紫金\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"四川紫金\"},{\"CUSTTRADEID\":\"0025210100009459\",\"INNERCLIENTID\":\"0000000009\",\"USERCODE\":\"_ST_0000000009\",\"CLIENTABBR\":\"代理珲春紫金\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"珲春紫金\"},{\"CUSTTRADEID\":\"0025210100012093\",\"INNERCLIENTID\":\"0000000010\",\"USERCODE\":\"_ST_0000000010\",\"CLIENTABBR\":\"代理隆兴矿业\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"隆兴矿业\"},{\"CUSTTRADEID\":\"0025210100012543\",\"INNERCLIENTID\":\"0000000011\",\"USERCODE\":\"_ST_0000000011\",\"CLIENTABBR\":\"代理和昱树脂\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"和昱树脂\"},{\"CUSTTRADEID\":\"0025210100013061\",\"INNERCLIENTID\":\"0000000012\",\"USERCODE\":\"_ST_0000000012\",\"CLIENTABBR\":\"代理上杭鸿阳\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"上杭鸿阳\"},{\"CUSTTRADEID\":\"0025210100015973\",\"INNERCLIENTID\":\"0000000013\",\"USERCODE\":\"_ST_0000000013\",\"CLIENTABBR\":\"代理上杭万祥\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"上杭万祥\"},{\"CUSTTRADEID\":\"0025210100017436\",\"INNERCLIENTID\":\"0000000014\",\"USERCODE\":\"_ST_0000000014\",\"CLIENTABBR\":\"代理正龙金矿\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"正龙金矿\"},{\"CUSTTRADEID\":\"0025210100018932\",\"INNERCLIENTID\":\"0000000015\",\"USERCODE\":\"_ST_0000000015\",\"CLIENTABBR\":\"代理金山黄金\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"金山黄金\"},{\"CUSTTRADEID\":\"0025210100019270\",\"INNERCLIENTID\":\"0000000016\",\"USERCODE\":\"_ST_0000000016\",\"CLIENTABBR\":\"代理曙光化工\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"曙光化工\"},{\"CUSTTRADEID\":\"0025210100023747\",\"INNERCLIENTID\":\"0000000017\",\"USERCODE\":\"_ST_0000000017\",\"CLIENTABBR\":\"代理凯韦投资\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"凯韦投资\"},{\"CUSTTRADEID\":\"0025210100024704\",\"INNERCLIENTID\":\"0000000018\",\"USERCODE\":\"_ST_0000000018\",\"CLIENTABBR\":\"代理紫金矿冶\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"紫金矿冶\"},{\"CUSTTRADEID\":\"0025210100024861\",\"INNERCLIENTID\":\"0000000019\",\"USERCODE\":\"_ST_0000000019\",\"CLIENTABBR\":\"代理石狮新成\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"石狮新成\"},{\"CUSTTRADEID\":\"0025210100025581\",\"INNERCLIENTID\":\"0000000020\",\"USERCODE\":\"_ST_0000000020\",\"CLIENTABBR\":\"代理紫金投资\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"紫金投资\"},{\"CUSTTRADEID\":\"0025210100027763\",\"INNERCLIENTID\":\"0000000021\",\"USERCODE\":\"_ST_0000000021\",\"CLIENTABBR\":\"代理梅州海鑫\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"梅州海鑫\"},{\"CUSTTRADEID\":\"0025210100032488\",\"INNERCLIENTID\":\"0000000022\",\"USERCODE\":\"_ST_0000000022\",\"CLIENTABBR\":\"代理龙岩金鼎象\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"龙岩金鼎象\"},{\"CUSTTRADEID\":\"0025210100032602\",\"INNERCLIENTID\":\"0000000023\",\"USERCODE\":\"_ST_0000000023\",\"CLIENTABBR\":\"代理信宜东坑\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"信宜东坑\"},{\"CUSTTRADEID\":\"0025210100033074\",\"INNERCLIENTID\":\"0000000024\",\"USERCODE\":\"_ST_0000000024\",\"CLIENTABBR\":\"代理深圳名象\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"深圳名象\"},{\"CUSTTRADEID\":\"0025210100034008\",\"INNERCLIENTID\":\"0000000025\",\"USERCODE\":\"_ST_0000000025\",\"CLIENTABBR\":\"代理龙岩兴隆鑫\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"龙岩兴隆鑫\"},{\"CUSTTRADEID\":\"0025210100035740\",\"INNERCLIENTID\":\"0000000026\",\"USERCODE\":\"_ST_0000000026\",\"CLIENTABBR\":\"代理龙岩鑫晖\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"龙岩鑫晖\"},{\"CUSTTRADEID\":\"0025210100037876\",\"INNERCLIENTID\":\"0000000027\",\"USERCODE\":\"_ST_0000000027\",\"CLIENTABBR\":\"代理厦门敦豪\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"厦门敦豪\"},{\"CUSTTRADEID\":\"0025210100037887\",\"INNERCLIENTID\":\"0000000028\",\"USERCODE\":\"_ST_0000000028\",\"CLIENTABBR\":\"代理永安格力\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"永安格力\"},{\"CUSTTRADEID\":\"0025210100038057\",\"INNERCLIENTID\":\"0000000029\",\"USERCODE\":\"_ST_0000000029\",\"CLIENTABBR\":\"代理厦门广颐\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"厦门广颐\"},{\"CUSTTRADEID\":\"0025210100038271\",\"INNERCLIENTID\":\"0000000030\",\"USERCODE\":\"_ST_0000000030\",\"CLIENTABBR\":\"代理顺裕公司\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"顺裕公司\"},{\"CUSTTRADEID\":\"0025210100038417\",\"INNERCLIENTID\":\"0000000031\",\"USERCODE\":\"_ST_0000000031\",\"CLIENTABBR\":\"代理厦门速帆\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"厦门速帆\"},{\"CUSTTRADEID\":\"0025210100038518\",\"INNERCLIENTID\":\"0000000032\",\"USERCODE\":\"_ST_0000000032\",\"CLIENTABBR\":\"代理龙岩天利\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"龙岩天利\"},{\"CUSTTRADEID\":\"0025210100041309\",\"INNERCLIENTID\":\"0000000033\",\"USERCODE\":\"_ST_0000000033\",\"CLIENTABBR\":\"代理龙岩顺裕\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"龙岩顺裕\"},{\"CUSTTRADEID\":\"0025210100041781\",\"INNERCLIENTID\":\"0000000034\",\"USERCODE\":\"_ST_0000000034\",\"CLIENTABBR\":\"代理元阳华西\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"元阳华西\"},{\"CUSTTRADEID\":\"0025210100051197\",\"INNERCLIENTID\":\"0000000035\",\"USERCODE\":\"_ST_0000000035\",\"CLIENTABBR\":\"代理丘北拓岩\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"丘北拓岩\"},{\"CUSTTRADEID\":\"0025210100055124\",\"INNERCLIENTID\":\"0000000036\",\"USERCODE\":\"_ST_0000000036\",\"CLIENTABBR\":\"代理上杭威特\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"上杭威特\"},{\"CUSTTRADEID\":\"0025210100055966\",\"INNERCLIENTID\":\"0000000037\",\"USERCODE\":\"_ST_0000000037\",\"CLIENTABBR\":\"代理龙岩永清\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"龙岩永清\"},{\"CUSTTRADEID\":\"0025210100057306\",\"INNERCLIENTID\":\"0000000038\",\"USERCODE\":\"_ST_0000000038\",\"CLIENTABBR\":\"代理上杭绿之源\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"上杭绿之源\"},{\"CUSTTRADEID\":\"0025210100057317\",\"INNERCLIENTID\":\"0000000039\",\"USERCODE\":\"_ST_0000000039\",\"CLIENTABBR\":\"代理龙岩石壁龙\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"龙岩石壁龙\"},{\"CUSTTRADEID\":\"0025210100060670\",\"INNERCLIENTID\":\"0000000040\",\"USERCODE\":\"_ST_0000000040\",\"CLIENTABBR\":\"代理龙岩鼎鑫\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"龙岩鼎鑫\"},{\"CUSTTRADEID\":\"0025210100074204\",\"INNERCLIENTID\":\"0000000041\",\"USERCODE\":\"_ST_0000000041\",\"CLIENTABBR\":\"代理紫金黄金珠宝\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"紫金矿业集团黄金珠宝有限公司\"},{\"CUSTTRADEID\":\"0025210100078590\",\"INNERCLIENTID\":\"0000000042\",\"USERCODE\":\"_ST_0000000042\",\"CLIENTABBR\":\"代理内蒙金中\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"内蒙金中\"},{\"CUSTTRADEID\":\"0025210100078961\",\"INNERCLIENTID\":\"0000000043\",\"USERCODE\":\"_ST_0000000043\",\"CLIENTABBR\":\"代理紫金铜业\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"紫金铜业\"},{\"CUSTTRADEID\":\"0025210100084070\",\"INNERCLIENTID\":\"0000000044\",\"USERCODE\":\"_ST_0000000044\",\"CLIENTABBR\":\"代理陇南紫金\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"陇南紫金\"},{\"CUSTTRADEID\":\"0025210100091539\",\"INNERCLIENTID\":\"0000000045\",\"USERCODE\":\"_ST_0000000045\",\"CLIENTABBR\":\"代理漳平银丰\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"漳平银丰\"},{\"CUSTTRADEID\":\"0025210100096309\",\"INNERCLIENTID\":\"0000000046\",\"USERCODE\":\"_ST_0000000046\",\"CLIENTABBR\":\"代理贵州西南紫金\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"贵州西南紫金\"},{\"CUSTTRADEID\":\"0025210100123816\",\"INNERCLIENTID\":\"0000000047\",\"USERCODE\":\"_ST_0000000047\",\"CLIENTABBR\":\"代理紫金贸易\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"紫金贸易\"},{\"CUSTTRADEID\":\"0025210100139981\",\"INNERCLIENTID\":\"0000000048\",\"USERCODE\":\"_ST_0000000048\",\"CLIENTABBR\":\"代理紫金环球\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"紫金环球\"},{\"CUSTTRADEID\":\"0025210100146372\",\"INNERCLIENTID\":\"0000000049\",\"USERCODE\":\"_ST_0000000049\",\"CLIENTABBR\":\"代理紫金矿业进口\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"紫金矿业进口\"},{\"CUSTTRADEID\":\"0025210100147025\",\"INNERCLIENTID\":\"0000000050\",\"USERCODE\":\"_ST_0000000050\",\"CLIENTABBR\":\"代理黄金冶炼\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"黄金冶炼\"},{\"CUSTTRADEID\":\"0025210100149421\",\"INNERCLIENTID\":\"0000000051\",\"USERCODE\":\"_ST_0000000051\",\"CLIENTABBR\":\"代理紫金金行\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"紫金金行\"},{\"CUSTTRADEID\":\"0025210100157374\",\"INNERCLIENTID\":\"0000000052\",\"USERCODE\":\"_ST_0000000052\",\"CLIENTABBR\":\"代理厦金宝\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"厦金宝\"},{\"CUSTTRADEID\":\"0025210100165632\",\"INNERCLIENTID\":\"0000000101\",\"USERCODE\":\"_ST_0000000101\",\"CLIENTABBR\":\"代理厦门华万腾\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"厦门华万腾\"},{\"CUSTTRADEID\":\"0025210100184868\",\"INNERCLIENTID\":\"0000000121\",\"USERCODE\":\"_ST_0000000121\",\"CLIENTABBR\":\"代理福建紫金贵金属材料有限公司\",\"SEATID\":\"002521\",\"CLIENTNAME\":\"福建紫金贵金属材料有限公司\"}]}";
+ byte[] bytes = str.getBytes(Util.GBK);
+ System.out.println(bytes.length);
+ }
+
+ static void printInputStream(String clazz) {
+ try {
+ String name = clazz.replace(".", "/") + ".class";
+ InputStream is = Test7.class.getClassLoader().getResourceAsStream(name);
+ int len = is.available();
+ byte[] bb = new byte[len];
+ int r_len = 0;
+ for (; r_len != len; ) {
+ r_len += is.read(bb, r_len, len - r_len);
+ }
+ System.out.println(clazz + ">>" + Base64.getEncoder().encodeToString(bb));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/firenio-test/src/main/java/test/io/Test8.java b/firenio-test/src/main/java/test/io/Test8.java
new file mode 100644
index 000000000..234c08533
--- /dev/null
+++ b/firenio-test/src/main/java/test/io/Test8.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.io;
+
+import java.util.Arrays;
+
+import com.firenio.common.ByteUtil;
+import com.firenio.common.Util;
+
+/**
+ * @author: wangkai
+ **/
+public class Test8 {
+
+ public static void main(String[] args) {
+
+ int count = 10;
+ byte[] data = new byte[1024 * 1024 * 1024];
+
+ // for (int i = 0; i < data.length; i++) {
+ // data[i] = (byte) i;
+ // }
+
+ Arrays.fill(data, (byte) 1);
+
+ long start = System.nanoTime();
+
+ long res = test_normal(data, count);
+
+ long past = System.nanoTime() - start;
+
+ System.out.println("res: " + res);
+
+ System.out.println("past: " + (past / 1000_1000));
+
+ }
+
+
+ static long test_normal(byte[] data, int count) {
+ long sum = 0;
+ for (int i = 0; i < count; i++) {
+ for (int j = 0; j < data.length; j++) {
+ sum += data[j];
+ }
+ }
+ return sum;
+ }
+
+
+ static long test_exp(byte[] data, int count) {
+ long sum1 = 0;
+ long sum2 = 0;
+ long sum3 = 0;
+ long sum4 = 0;
+ for (int i = 0; i < count; i++) {
+ for (int j = 0; j < data.length; j += 4) {
+ sum1 += data[j];
+ sum2 += data[j + 1];
+ sum3 += data[j + 2];
+ sum4 += data[j + 3];
+ }
+ }
+ return sum1 + sum2 + sum3 + sum4;
+ }
+
+}
diff --git a/firenio-test/src/main/java/test/io/TestByteBufSkip.java b/firenio-test/src/main/java/test/io/TestByteBufSkip.java
new file mode 100644
index 000000000..d708ba2b5
--- /dev/null
+++ b/firenio-test/src/main/java/test/io/TestByteBufSkip.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.io;
+
+
+import com.firenio.log.LoggerFactory;
+
+/**
+ * @author: wangkai
+ **/
+public class TestByteBufSkip {
+
+ public static void main(String[] args) {
+
+ LoggerFactory.setEnableSLF4JLogger(false);
+
+ test_firenio();
+ test_netty();
+
+ }
+
+ static void test_firenio() {
+ com.firenio.buffer.ByteBuf out = com.firenio.buffer.ByteBuf.buffer(100);
+
+ int write_index = out.writeIndex();
+ out.skipWrite(4);
+ out.writeInt(100);
+ out.writeInt(200);
+ out.setInt(write_index, out.readableBytes() - 4);
+
+ System.out.println("firenio: ");
+ System.out.println(out.readInt());
+ System.out.println(out.readInt());
+ System.out.println(out.readInt());
+
+
+ }
+
+
+ static void test_netty() {
+
+ io.netty.buffer.ByteBuf out = io.netty.buffer.Unpooled.buffer();
+
+ int writerIndex = out.writerIndex();
+ out.writerIndex(out.writerIndex() + 4);
+ out.writeInt(100);
+ out.writeInt(200);
+ out.setInt(writerIndex, out.readableBytes() - 4);
+
+ System.out.println("netty: ");
+ System.out.println(out.readInt());
+ System.out.println(out.readInt());
+ System.out.println(out.readInt());
+
+ }
+
+
+}
diff --git a/firenio-test/src/main/java/test/io/TestDio.java b/firenio-test/src/main/java/test/io/TestDio.java
new file mode 100644
index 000000000..497319f89
--- /dev/null
+++ b/firenio-test/src/main/java/test/io/TestDio.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.io;
+
+import com.firenio.DevelopConfig;
+import com.firenio.common.Unsafe;
+import com.firenio.component.Native;
+import com.firenio.log.LoggerFactory;
+
+/**
+ * @program: firenio
+ * @description:
+ * @author: wangkai
+ * @create: 2019-09-11 16:18
+ **/
+public class TestDio {
+
+ static {
+ LoggerFactory.setEnableSLF4JLogger(false);
+ DevelopConfig.EPOLL_DEBUG = true;
+ DevelopConfig.NATIVE_DEBUG = true;
+ }
+
+ static final int PS = 1024 * 4;
+
+ static final String path = "/home/test/temp/test_direct2.txt";
+
+ public static void main(String[] args) throws Exception {
+
+ test_direct_write();
+ test_direct_read();
+ }
+
+ static void test_direct_write() {
+ long address = Native.posix_memalign_allocate(PS, PS);
+ int fd = Native.open(path, Native.O_WRONLY | Native.O_CREAT | Native.O_DIRECT | Native.O_TRUNC, 0755);
+ System.out.println("file len: " + Native.file_length(fd));
+ byte[] data = "hello world!0".getBytes();
+ do_write_data(fd, address, data, 0);
+ do_write_data(fd, address, data, 1);
+ do_write_data(fd, address, data, 2);
+ do_write_data(fd, address, data, 3);
+ System.out.println("file len: " + Native.file_length(fd));
+ Unsafe.free(address);
+ Native.close(fd);
+ }
+
+ static void do_write_data(int fd, long address, byte[] data, int index) {
+ data[data.length - 1] = (byte) (index);
+ Unsafe.copyFromArray(data, 0, address, data.length);
+ if (index > 0) {
+ Native.pwrite(fd, address, PS, index * PS);
+ } else {
+ Native.write(fd, address, PS);
+ }
+
+ }
+
+ static void test_direct_read() {
+ long address = Native.posix_memalign_allocate(PS, PS);
+ int fd = Native.open(path, Native.O_RDONLY | Native.O_CREAT | Native.O_DIRECT, 0755);
+ long file_len = Native.file_length(fd);
+ byte[] data = new byte[16];
+ System.out.println("file len: " + file_len);
+ Native.lseek(fd, file_len, Native.SEEK_SET);
+ do_read_data(fd, address, data, 0);
+ do_read_data(fd, address, data, PS * 2);
+ Unsafe.free(address);
+ Native.close(fd);
+ }
+
+ static void do_read_data(int fd, long address, byte[] data, long pos) {
+ int read;
+ if (pos == 0) {
+ Native.lseek(fd, pos, Native.SEEK_SET);
+ read = Native.read(fd, address, PS);
+ } else {
+ read = Native.pread(fd, address, PS, pos);
+ }
+ System.out.println("read len: " + read);
+ Unsafe.copyToArray(address, data, 0, 16);
+ String content = new String(data);
+ System.out.println("content: " + content);
+
+ }
+
+}
diff --git a/firenio-test/src/main/java/test/io/TestFloat.java b/firenio-test/src/main/java/test/io/TestFloat.java
new file mode 100644
index 000000000..d3efd84d4
--- /dev/null
+++ b/firenio-test/src/main/java/test/io/TestFloat.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.io;
+
+import com.firenio.buffer.ByteBuf;
+import com.firenio.common.ByteUtil;
+
+/**
+ * @author: wangkai
+ **/
+public class TestFloat {
+
+ public static void main(String[] args) {
+ System.out.println("2.03f: " + Float.floatToIntBits(2.03f));
+ System.out.println("0.5f: " + Float.floatToIntBits(0.5f));
+ System.out.println("0.9f: " + Float.floatToIntBits(0.9f));
+ System.out.println("1.0f: " + Float.floatToIntBits(1.0f));
+ System.out.println("12.34f: " + Float.floatToIntBits(12.34f));
+ System.out.println("1.5f: " + Float.floatToIntBits(1.5f));
+ System.out.println("0.1f: " + Float.floatToIntBits(1f - 0.9f));
+ System.out.println(1 - 0.9f);
+ System.out.println(1f + 0.5f);
+
+ int v = 0b00111101100010011001100110011010;
+ System.out.println(v);
+
+ long l = 34;
+ for (int i = 0; i < 23; i++) {
+ l *= 2;
+ }
+ System.out.println(l);
+
+ float f2 = 0.01f;
+ float f3 = f2 + 1;
+ for (int i = 0; i < 999999; i++) {
+ f3 += f2;
+ int f4 = Float.floatToIntBits(f3);
+ if ((f4 & 1) == 1) {
+ System.out.println(f3 + "------ & 1 =====1");
+ break;
+ }
+ }
+ System.out.println("end...");
+
+ }
+}
diff --git a/firenio-test/src/main/java/test/io/TestJDKBug1.java b/firenio-test/src/main/java/test/io/TestJDKBug1.java
new file mode 100644
index 000000000..7b0d02d35
--- /dev/null
+++ b/firenio-test/src/main/java/test/io/TestJDKBug1.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.io;
+
+/**
+ * @author: wangkai
+ **/
+public class TestJDKBug1 {
+
+ public void test() {
+ int i = -1;
+// while ((i -= 3) > 0);
+ System.out.println("i = " + i);
+ }
+
+ public static void main(String[] args) {
+ TestJDKBug1 hello = new TestJDKBug1();
+ for (int i = 0; i < 50_000; i++) {
+ hello.test();
+ }
+ }
+
+
+
+}
diff --git a/firenio-test/src/main/java/test/io/TestLoad.java b/firenio-test/src/main/java/test/io/TestLoad.java
new file mode 100644
index 000000000..25a6effc0
--- /dev/null
+++ b/firenio-test/src/main/java/test/io/TestLoad.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.io;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.elasticsearch.common.recycler.Recycler.C;
+
+import com.firenio.common.FileUtil;
+
+/**
+ * @author: wangkai
+ **/
+public class TestLoad {
+
+ public static void main(String[] args) throws Exception {
+
+ String s_128_0 = "1280141.0028337";
+ String s_128_1 = "1281063.0028301";
+ String s_128_930 = "1289307.0028297";
+ String s_128_938 = "1289385.0028258";
+ String s_130_0 = "1300290.0028466";
+ String s_130_2 = "1302952.0028294";
+ cal(s_128_0);
+ cal(s_128_1);
+ cal(s_128_930);
+ cal(s_128_938);
+ cal(s_130_0);
+ cal(s_130_2);
+
+ }
+
+
+ static void cal(String dic) throws Exception {
+ int count = 10;
+ File s_file = new File("C:\\Users\\wangkai\\Downloads\\" + dic + "\\z-small.txt");
+ File m_file = new File("C:\\Users\\wangkai\\Downloads\\" + dic + "\\z-medium.txt");
+ File l_file = new File("C:\\Users\\wangkai\\Downloads\\" + dic + "\\z-large.txt");
+
+ List s_c = getQPS(s_file, count, 0);
+ List m_c = getQPS(m_file, count, 1);
+ List l_c = getQPS(l_file, count, 2);
+
+ int[] abs_cnt = new int[3];
+ double abs_cut = 0;
+ double abs_sum = 0;
+ List max_con = new ArrayList<>();
+ List max_qps = new ArrayList<>(count);
+ List temp = new ArrayList<>(3);
+
+ for (int i = 0; i < count; i++) {
+ temp.clear();
+ temp.add(s_c.get(i));
+ temp.add(m_c.get(i));
+ temp.add(l_c.get(i));
+ Collections.sort(temp, new Comparator() {
+ @Override
+ public int compare(Cfg o1, Cfg o2) {
+ return (int) ((o1.rtt * 100) - (o2.rtt * 100));
+ }
+ });
+ double qps = 0;
+ int r_con = 1024;
+ for (int j = 0; j < temp.size(); j++) {
+ Cfg c = temp.get(j);
+ double _qps = (Math.min(r_con, c.con) * (1000 / c.rtt));
+ qps += _qps;
+ r_con -= c.con;
+ c.qps = _qps;
+ abs_cnt[c.type] += _qps;
+ }
+ abs_sum += qps * 6;
+ max_qps.add((int) qps);
+
+ int base = 1900;
+ double s_qps = s_c.get(i).qps;
+ double m_qps = m_c.get(i).qps;
+ double l_qps = l_c.get(i).qps;
+ double a_qps = s_qps + m_qps + l_qps;
+ if (s_qps - (a_qps * 1 / 6) > 0) {
+ abs_cut += (s_qps - (a_qps * 1 / 6));
+ // abs_cut += (s_qps - (a_qps * 1 / 6)) / (a_qps * 1 / 6);
+ }
+ if (m_qps - (a_qps * 2 / 6) > 0) {
+ abs_cut += (m_qps - (a_qps * 2 / 6));
+ // abs_cut += (m_qps - (a_qps * 2 / 6)) / (a_qps * 2 / 6);
+ }
+ if (l_qps - (a_qps * 3 / 6) > 0) {
+ abs_cut += (l_qps - (a_qps * 3 / 6));
+ // abs_cut += (l_qps - (a_qps * 3 / 6)) / (a_qps * 3 / 6);
+ }
+ max_con.add(s_c.get(i).con + m_c.get(i).con + l_c.get(i).con);
+ }
+ System.out.println("abs_sum:" + abs_sum);
+ System.out.println("sc:" + s_c);
+ System.out.println("mc:" + m_c);
+ System.out.println("lc:" + l_c);
+ System.out.println("ac:" + max_qps);
+ System.out.println("max_con: " + max_con);
+ System.out.println("abs_cut: " + abs_cut);
+ System.out.println(dic + ">>abs_cnt: " + (abs_cnt[0] + abs_cnt[1] + abs_cnt[2]) + ",abs_cnt_s:" + abs_cnt[0] + ",abs_cnt_m:" + abs_cnt[1] + ",abs_cnt_l:" + abs_cnt[2]);
+ System.out.println();
+ }
+
+ static int mask(double q, double v, double base) {
+ if (q < base) {
+ return (int) v;
+ }
+ return (int) (v * (1 + (((q - base) / base) * ((q - base) / base))));
+ }
+
+ static List getQPS(File file, int count, int type) throws Exception {
+ List ss = FileUtil.readLines(file);
+ List res = new ArrayList<>(count);
+ for (int i = 0; i < count; i++) {
+ String s = ss.get(i);
+ int avg_rtt_idx = s.indexOf("avg_rtt") + 8;
+ int avg_rtt_idx_end = s.indexOf(',', avg_rtt_idx);
+ int c = Integer.parseInt(s.substring(s.length() - 3));
+ double rtt = Double.parseDouble(s.substring(avg_rtt_idx, avg_rtt_idx_end));
+ if (c < 100 || c > 650 || rtt < 10 || rtt > 100) {
+ System.out.println("error");
+ }
+ Cfg cfg = new Cfg();
+ cfg.con = c;
+ cfg.rtt = rtt;
+ cfg.type = type;
+ res.add(cfg);
+ }
+ return res;
+ }
+
+ static class Cfg {
+
+ double rtt;
+ int con;
+ int type;
+ double qps;
+
+ @Override
+ public String toString() {
+ return String.valueOf((int)qps);
+ }
+ }
+
+
+}
diff --git a/firenio-test/src/main/java/test/io/TestLoad1.java b/firenio-test/src/main/java/test/io/TestLoad1.java
new file mode 100644
index 000000000..8ffd8084f
--- /dev/null
+++ b/firenio-test/src/main/java/test/io/TestLoad1.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.io;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import com.firenio.common.Cryptos;
+import com.firenio.common.FileUtil;
+
+/**
+ * @author: wangkai
+ **/
+public class TestLoad1 {
+
+
+ public static void main(String[] args) throws Exception {
+
+ double dd = 10.55d;
+ int aa = (int)dd;
+ System.out.println(aa);
+
+ String clazz = "yv66vgAAADQAYQoAGAA3CQANADgJAA0AOQcAOgoABAA7CQANADwHAD0LAD4APwoABwA7CwA+AEALAEEAQgsAQQBDBwBECgANAEULAD4ARgcARwoAEAA3CABICgAQAEkKABAASggASwoAEABMCgAQAE0HAE4BAA5tYXhfY29uY3VycmVudAEAAUkBAAdhdmdfcnR0AQABRAEABnBlcm1pdAEAIExqYXZhL3V0aWwvY29uY3VycmVudC9TZW1hcGhvcmU7AQAGPGluaXQ+AQAFKElEKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAIkxjb20vYWxpd2FyZS90aWFuY2hpL1Byb3ZpZGVyQ29uZjsBAAdjb252ZXJ0AQAiKExqYXZhL3V0aWwvTGlzdDspTGphdmEvdXRpbC9MaXN0OwEADHByb3ZpZGVyQ29uZgEAB2NvbmZpZ3MBABBMamF2YS91dGlsL0xpc3Q7AQAEY29uZgEAFkxvY2FsVmFyaWFibGVUeXBlVGFibGUBADRMamF2YS91dGlsL0xpc3Q8TGNvbS9hbGl3YXJlL3RpYW5jaGkvUHJvdmlkZXJDb25mOz47AQANU3RhY2tNYXBUYWJsZQcATwcAUAEACVNpZ25hdHVyZQEAaihMamF2YS91dGlsL0xpc3Q8TGNvbS9hbGl3YXJlL3RpYW5jaGkvUHJvdmlkZXJDb25mOz47KUxqYXZhL3V0aWwvTGlzdDxMY29tL2FsaXdhcmUvdGlhbmNoaS9Qcm92aWRlckNvbmY7PjsBAAh0b1N0cmluZwEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAKU291cmNlRmlsZQEAEVByb3ZpZGVyQ29uZi5qYXZhDAAfAFEMABkAGgwAGwAcAQAeamF2YS91dGlsL2NvbmN1cnJlbnQvU2VtYXBob3JlDAAfAFIMAB0AHgEAE2phdmEvdXRpbC9BcnJheUxpc3QHAE8MAFMAVAwAVQBWBwBQDABXAFgMAFkAWgEAIGNvbS9hbGl3YXJlL3RpYW5jaGkvUHJvdmlkZXJDb25mDAAfACAMAFsAXAEAF2phdmEvbGFuZy9TdHJpbmdCdWlsZGVyAQAOY29uZjogYXZnX3J0dDoMAF0AXgwAXQBfAQARLCBtYXhfY29uY3VycmVudDoMAF0AYAwAMwA0AQAQamF2YS9sYW5nL09iamVjdAEADmphdmEvdXRpbC9MaXN0AQASamF2YS91dGlsL0l0ZXJhdG9yAQADKClWAQAEKEkpVgEABHNpemUBAAMoKUkBAAhpdGVyYXRvcgEAFigpTGphdmEvdXRpbC9JdGVyYXRvcjsBAAdoYXNOZXh0AQADKClaAQAEbmV4dAEAFCgpTGphdmEvbGFuZy9PYmplY3Q7AQADYWRkAQAVKExqYXZhL2xhbmcvT2JqZWN0OylaAQAGYXBwZW5kAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAcKEQpTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEAHChJKUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsAIQANABgAAAADABEAGQAaAAAAEQAbABwAAAARAB0AHgAAAAMAAQAfACAAAQAhAAAAaQAEAAQAAAAbKrcAASobtQACKii1AAMquwAEWRu3AAW1AAaxAAAAAgAiAAAAFgAFAAAADwAEABAACQARAA4AEgAaABMAIwAAACAAAwAAABsAJAAlAAAAAAAbABkAGgABAAAAGwAbABwAAgAJACYAJwACACEAAADBAAYABAAAAEO7AAdZKrkACAEAtwAJTCq5AAoBAE0suQALAQCZACYsuQAMAQDAAA1OK7sADVkttAACLbQAA7cADrkADwIAV6f/1yuwAAAABAAiAAAAFgAFAAAAFgAOABcAKAAYAD4AGQBBABoAIwAAACAAAwAoABYAKAAlAAMAAABDACkAKgAAAA4ANQArACoAAQAsAAAAFgACAAAAQwApAC0AAAAOADUAKwAtAAEALgAAAA4AAv0AFQcALwcAMPoAKwAxAAAAAgAyAAEAMwA0AAEAIQAAAE0AAwABAAAAI7sAEFm3ABESErYAEyq0AAO2ABQSFbYAEyq0AAK2ABa2ABewAAAAAgAiAAAABgABAAAAHwAjAAAADAABAAAAIwAkACUAAAABADUAAAACADY=";
+
+ FileUtil.writeByFile(new File("C://temp/a.class"), Cryptos.base64_de(clazz));
+
+
+ }
+
+
+}
diff --git a/firenio-test/src/main/java/test/io/TestMMap.java b/firenio-test/src/main/java/test/io/TestMMap.java
new file mode 100644
index 000000000..bc2f7bb79
--- /dev/null
+++ b/firenio-test/src/main/java/test/io/TestMMap.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.io;
+
+import java.io.File;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileChannel.MapMode;
+import java.nio.file.OpenOption;
+import java.nio.file.StandardOpenOption;
+
+import com.firenio.common.Unsafe;
+
+/**
+ * @author: wangkai
+ **/
+public class TestMMap {
+
+ static OpenOption[] FC_OPS = new OpenOption[]{StandardOpenOption.CREATE, StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING};
+
+ public static void main(String[] args) throws Exception {
+ File file1 = new File("C://temp/test_mmap1.txt");
+ File file2 = new File("C://temp/test_mmap2.txt");
+ FileChannel ch1 = FileChannel.open(file1.toPath(), FC_OPS);
+ FileChannel ch2 = FileChannel.open(file2.toPath(), FC_OPS);
+ MappedByteBuffer buf1 = ch1.map(MapMode.READ_WRITE, 0, 32);
+ MappedByteBuffer buf2 = ch2.map(MapMode.READ_WRITE, 0, 32);
+ byte[] data = "abc123456".getBytes();
+ buf1.put(data);
+ buf1.put((byte) 1);
+ buf1.put((byte) 2);
+ buf1.put((byte) 3);
+ buf1.put((byte) 4);
+ Unsafe.copyFromArray(data, 0, Unsafe.address(buf2), data.length);
+ Unsafe.copyFromArray(data, 0, Unsafe.address(buf1) + 15, data.length);
+ Unsafe.copyFromArray(data, 0, Unsafe.address(buf2) + 15, data.length);
+ System.out.println("finish...");
+ System.exit(0);
+ }
+
+
+}
diff --git a/firenio-test/src/main/java/test/io/TestMulticastSocket.java b/firenio-test/src/main/java/test/io/TestMulticastSocket.java
new file mode 100644
index 000000000..9f8806430
--- /dev/null
+++ b/firenio-test/src/main/java/test/io/TestMulticastSocket.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.io;
+
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+
+/**
+ * @program: firenio
+ * @description:
+ * @author: wangkai
+ * @create: 2019-05-22 16:21
+ **/
+public class TestMulticastSocket {
+
+
+ public static void main(String[] args) throws Exception {
+
+ System.out.println(1f - 9.0 / 10);
+
+
+ }
+
+
+}
diff --git a/firenio-test/src/main/java/test/io/buffer/TestByteBufCopy.java b/firenio-test/src/main/java/test/io/buffer/TestByteBufCopy.java
index b3d5b3993..c98a3d471 100644
--- a/firenio-test/src/main/java/test/io/buffer/TestByteBufCopy.java
+++ b/firenio-test/src/main/java/test/io/buffer/TestByteBufCopy.java
@@ -17,22 +17,27 @@
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
+import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import org.junit.Test;
import com.firenio.buffer.ByteBuf;
+import com.firenio.common.Assert;
import com.firenio.common.Unsafe;
import com.firenio.common.Util;
-
-import junit.framework.Assert;
+import com.firenio.log.LoggerFactory;
/**
* @author wangkai
*/
public class TestByteBufCopy {
+ static {
+ LoggerFactory.setEnableSLF4JLogger(false);
+ }
+
static final byte[] _data = "abc123abc123".getBytes();
static final ByteBuf arrayData;
static final ByteBuf directData;
@@ -44,16 +49,16 @@ public class TestByteBufCopy {
jDirectData = Unsafe.allocateDirectByteBuffer(12);
jArrayData.position(6);
jDirectData.put(_data).position(6);
- arrayData = ByteBuf.wrap(jArrayData).skip(6);
- directData = ByteBuf.wrap(jDirectData).skip(6);
+ arrayData = ByteBuf.wrap(jArrayData).skipWrite(6);
+ directData = ByteBuf.wrap(jDirectData).skipWrite(6);
}
static ByteBuf _array() {
- return ByteBuf.heap(12).position(6);
+ return ByteBuf.heap(12).writeIndex(6);
}
static ByteBuf _direct() {
- return ByteBuf.direct(12).position(6);
+ return ByteBuf.direct(12).writeIndex(6);
}
static ByteBuffer _jArray() {
@@ -65,11 +70,11 @@ static ByteBuffer _jDirect() {
}
static ByteBuf arrayData() {
- return arrayData.limit(12).position(6);
+ return arrayData.writeIndex(12).readIndex(6);
}
static ByteBuf directData() {
- return directData.limit(12).position(6);
+ return directData.writeIndex(12).readIndex(6);
}
static ByteBuffer jArrayData() {
@@ -83,16 +88,11 @@ static ByteBuffer jDirectData() {
}
void _invoke(Method m) throws Exception {
- String name = m.getName();
- if (name == null) {
- System.out.println();
- }
Object res = m.invoke(this, (Object[]) null);
byte[] bytes;
if (res instanceof ByteBuf) {
- ((ByteBuf) res).flip();
- ((ByteBuf) res).position(((ByteBuf) res).limit() - 6);
- bytes = ((ByteBuf) res).getBytes();
+ ((ByteBuf) res).readIndex(((ByteBuf) res).writeIndex() - 6);
+ bytes = ((ByteBuf) res).readBytes();
} else if (res instanceof ByteBuffer) {
((ByteBuffer) res).flip();
((ByteBuffer) res).position(((ByteBuffer) res).limit() - 6);
@@ -101,7 +101,7 @@ void _invoke(Method m) throws Exception {
} else {
bytes = "1".getBytes();
}
- Assert.assertEquals("abc123", new String(bytes));
+ Assert.expectEquals("abc123", new String(bytes));
}
@Test
@@ -109,7 +109,7 @@ void _invoke(Method m) throws Exception {
public void _testAll() throws Exception {
Method[] ms = TestByteBufCopy.class.getDeclaredMethods();
- List list = Util.array2List(ms);
+ List list = Arrays.asList(ms);
list.sort(Comparator.comparing(Method::getName));
for (int i = 0; i < list.size(); i++) {
@@ -126,97 +126,97 @@ public void _testAll() throws Exception {
Object arrayGetArray() {
ByteBuf buf = _array();
- arrayData().getBytes(buf);
+ arrayData().readBytes(buf);
return buf;
}
Object arrayGetDirect() {
ByteBuf buf = _direct();
- arrayData().getBytes(buf);
+ arrayData().readBytes(buf);
return buf;
}
Object arrayGetJArray() {
ByteBuffer buf = _jArray();
- arrayData().getBytes(buf);
+ arrayData().readBytes(buf);
return buf;
}
Object arrayGetJDirect() {
ByteBuffer buf = _jDirect();
- arrayData().getBytes(buf);
+ arrayData().readBytes(buf);
return buf;
}
Object arrayPutArray() {
ByteBuf buf = _array();
- buf.putBytes(arrayData());
+ buf.writeBytes(arrayData());
return buf;
}
Object arrayPutDirect() {
ByteBuf buf = _array();
- buf.putBytes(directData());
+ buf.writeBytes(directData());
return buf;
}
Object arrayPutJArray() {
ByteBuf buf = _array();
- buf.putBytes(jArrayData());
+ buf.writeBytes(jArrayData());
return buf;
}
Object arrayPutJDirect() {
ByteBuf buf = _array();
- buf.putBytes(jDirectData());
+ buf.writeBytes(jDirectData());
return buf;
}
Object directGetArray() {
ByteBuf buf = _array();
- directData().getBytes(buf);
+ directData().readBytes(buf);
return buf;
}
Object directGetDirect() {
ByteBuf buf = _direct();
- directData().getBytes(buf);
+ directData().readBytes(buf);
return buf;
}
Object directGetJArray() {
ByteBuffer buf = _jArray();
- directData().getBytes(buf);
+ directData().readBytes(buf);
return buf;
}
Object directGetJDirect() {
ByteBuffer buf = _jDirect();
- directData().getBytes(buf);
+ directData().readBytes(buf);
return buf;
}
Object directPutArray() {
ByteBuf buf = _direct();
- buf.putBytes(arrayData());
+ buf.writeBytes(arrayData());
return buf;
}
Object directPutDirect() {
ByteBuf buf = _direct();
- buf.putBytes(directData());
+ buf.writeBytes(directData());
return buf;
}
Object directPutJArray() {
ByteBuf buf = _direct();
- buf.putBytes(jArrayData());
+ buf.writeBytes(jArrayData());
return buf;
}
Object directPutJDirect() {
ByteBuf buf = _direct();
- buf.putBytes(jDirectData());
+ buf.writeBytes(jDirectData());
return buf;
}
diff --git a/firenio-test/src/main/java/test/io/buffer/TestBytebufAllocator.java b/firenio-test/src/main/java/test/io/buffer/TestBytebufAllocator.java
index eacbc503f..7d58fd71b 100644
--- a/firenio-test/src/main/java/test/io/buffer/TestBytebufAllocator.java
+++ b/firenio-test/src/main/java/test/io/buffer/TestBytebufAllocator.java
@@ -18,28 +18,31 @@
import org.junit.Test;
import com.firenio.buffer.ByteBuf;
+import com.firenio.common.Assert;
+import com.firenio.log.LoggerFactory;
-import junit.framework.Assert;
public class TestBytebufAllocator {
+ static {
+ LoggerFactory.setEnableSLF4JLogger(false);
+ }
+
static final String data = "hello;hello;";
static final String data1 = "hello;";
static void v(ByteBuf buf) {
- byte[] res = buf.getBytes();
- Assert.assertEquals(new String(res), data);
+ byte[] res = buf.readBytes();
+ Assert.expectEquals(new String(res), data);
}
@Test
public void testput0() {
ByteBuf src = ByteBuf.direct(1024);
- src.putBytes(data.getBytes());
- src.flip();
+ src.writeBytes(data.getBytes());
ByteBuf dst = ByteBuf.direct(1024);
- dst.putBytes(src);
- dst.flip();
+ dst.writeBytes(src);
v(dst);
}
@@ -47,84 +50,83 @@ public void testput0() {
public void testput1() {
ByteBuf src = ByteBuf.direct(1024);
- src.putBytes(data.getBytes());
- src.flip();
+ src.writeBytes(data.getBytes());
ByteBuf dst = ByteBuf.direct(data1.length());
- dst.putBytes(src);
- dst.flip();
+ dst.writeBytes(src);
+
v(dst);
}
@Test
public void testput2() {
ByteBuf src = ByteBuf.heap(1024);
- src.putBytes(data.getBytes());
- src.flip();
+ src.writeBytes(data.getBytes());
+
ByteBuf dst = ByteBuf.direct(1024);
- dst.putBytes(src);
- dst.flip();
+ dst.writeBytes(src);
+
v(dst);
}
@Test
public void testPut3() {
ByteBuf src = ByteBuf.heap(1024);
- src.putBytes(data.getBytes());
- src.flip();
+ src.writeBytes(data.getBytes());
+
ByteBuf dst = ByteBuf.direct(data1.length());
- dst.putBytes(src);
- dst.flip();
+ dst.writeBytes(src);
+
v(dst);
}
@Test
public void testPut4() {
ByteBuf src = ByteBuf.heap(1024);
- src.putBytes("hello;hello;".getBytes());
- src.flip();
+ src.writeBytes("hello;hello;".getBytes());
+
ByteBuf dst = ByteBuf.heap(1024);
- dst.putBytes(src);
- dst.flip();
+ dst.writeBytes(src);
+
v(dst);
}
@Test
public void testPut5() {
ByteBuf src = ByteBuf.heap(1024);
- src.putBytes("hello;hello;".getBytes());
- src.flip();
+ src.writeBytes("hello;hello;".getBytes());
+
ByteBuf dst = ByteBuf.heap(data1.length());
- dst.putBytes(src);
- dst.flip();
+ dst.writeBytes(src);
+
v(dst);
}
@Test
public void testPut6() {
ByteBuf src = ByteBuf.direct(1024);
- src.putBytes("hello;hello;".getBytes());
- src.flip();
+ src.writeBytes("hello;hello;".getBytes());
+
ByteBuf dst = ByteBuf.heap(1024);
- dst.putBytes(src);
- dst.flip();
+ dst.writeBytes(src);
+
v(dst);
}
@Test
public void testPut7() {
ByteBuf src = ByteBuf.direct(1024);
- src.putBytes("hello;hello;".getBytes());
- src.flip();
+ src.writeBytes("hello;hello;".getBytes());
+
ByteBuf dst = ByteBuf.heap(data1.length());
- dst.putBytes(src);
- dst.flip();
+ dst.writeBytes(src);
+
v(dst);
}
diff --git a/firenio-test/src/main/java/test/io/buffer/TestDuplicatedByteBuf.java b/firenio-test/src/main/java/test/io/buffer/TestDuplicatedHeapByteBuf.java
similarity index 81%
rename from firenio-test/src/main/java/test/io/buffer/TestDuplicatedByteBuf.java
rename to firenio-test/src/main/java/test/io/buffer/TestDuplicatedHeapByteBuf.java
index b61a2d321..b6c3a42b2 100644
--- a/firenio-test/src/main/java/test/io/buffer/TestDuplicatedByteBuf.java
+++ b/firenio-test/src/main/java/test/io/buffer/TestDuplicatedHeapByteBuf.java
@@ -19,19 +19,18 @@
import com.firenio.buffer.ByteBuf;
import com.firenio.buffer.ByteBufAllocator;
-
-import junit.framework.Assert;
+import com.firenio.common.Assert;
/**
* @author wangkai
*/
-public class TestDuplicatedByteBuf {
+public class TestDuplicatedHeapByteBuf {
static final String data = "abcdef";
static void v(ByteBuf buf) {
- Assert.assertEquals(new String(buf.getBytes()), data);
+ Assert.expectEquals(new String(buf.readBytes()), data);
}
@@ -39,8 +38,7 @@ static void v(ByteBuf buf) {
public void testDirect() {
ByteBuf buf = ByteBuf.direct(16);
- buf.putBytes(data.getBytes());
- buf.flip();
+ buf.writeBytes(data.getBytes());
ByteBuf buf2 = buf.duplicate();
v(buf2);
}
@@ -50,8 +48,7 @@ public void testDirectP() throws Exception {
ByteBufAllocator a = TestAllocUtil.direct();
ByteBuf buf = a.allocate(16);
- buf.putBytes(data.getBytes());
- buf.flip();
+ buf.writeBytes(data.getBytes());
ByteBuf buf2 = buf.duplicate();
v(buf2);
}
@@ -60,8 +57,7 @@ public void testDirectP() throws Exception {
public void testHeap() {
ByteBuf buf = ByteBuf.direct(16);
- buf.putBytes(data.getBytes());
- buf.flip();
+ buf.writeBytes(data.getBytes());
ByteBuf buf2 = buf.duplicate();
v(buf2);
}
@@ -71,8 +67,7 @@ public void testHeapP() throws Exception {
ByteBufAllocator a = TestAllocUtil.heap();
ByteBuf buf = a.allocate(16);
- buf.putBytes(data.getBytes());
- buf.flip();
+ buf.writeBytes(data.getBytes());
ByteBuf buf2 = buf.duplicate();
v(buf2);
}
diff --git a/firenio-test/src/main/java/test/io/buffer/TestExpansion.java b/firenio-test/src/main/java/test/io/buffer/TestExpansion.java
index 8d09696f3..2e6ffab17 100644
--- a/firenio-test/src/main/java/test/io/buffer/TestExpansion.java
+++ b/firenio-test/src/main/java/test/io/buffer/TestExpansion.java
@@ -31,8 +31,7 @@ public class TestExpansion {
static final byte[] data = "aaaa".getBytes();
private static boolean v(ByteBuf buf) {
- buf.flip();
- String s = new String(buf.getBytes());
+ String s = new String(buf.readBytes());
if (s.length() != 50) {
return false;
}
@@ -49,8 +48,8 @@ public void arrayPool() throws Exception {
ByteBufAllocator alloc = TestAllocUtil.heap(1024 * 4);
ByteBuf buf = alloc.allocate(2);
for (int i = 0; i < 10; i++) {
- buf.putBytes(data);
- buf.putByte(a);
+ buf.writeBytes(data);
+ buf.writeByte(a);
alloc.allocate(1);
}
Assert.assertTrue(v(buf));
@@ -60,8 +59,8 @@ public void arrayPool() throws Exception {
public void arrayUnPool() {
ByteBuf buf = ByteBuf.heap(2);
for (int i = 0; i < 10; i++) {
- buf.putBytes(data);
- buf.putByte(a);
+ buf.writeBytes(data);
+ buf.writeByte(a);
}
Assert.assertTrue(v(buf));
}
@@ -71,8 +70,8 @@ public void directPool() throws Exception {
ByteBufAllocator alloc = TestAllocUtil.direct(1024 * 4);
ByteBuf buf = alloc.allocate(2);
for (int i = 0; i < 10; i++) {
- buf.putBytes(data);
- buf.putByte(a);
+ buf.writeBytes(data);
+ buf.writeByte(a);
alloc.allocate(1);
}
Assert.assertTrue(v(buf));
@@ -82,8 +81,8 @@ public void directPool() throws Exception {
public void directUnPool() {
ByteBuf buf = ByteBuf.direct(2);
for (int i = 0; i < 10; i++) {
- buf.putBytes(data);
- buf.putByte(a);
+ buf.writeBytes(data);
+ buf.writeByte(a);
}
Assert.assertTrue(v(buf));
}
diff --git a/firenio-test/src/main/java/test/io/buffer/TestPooledBytebuf.java b/firenio-test/src/main/java/test/io/buffer/TestPooledBytebuf.java
index 74e08e87b..f6a36d9df 100644
--- a/firenio-test/src/main/java/test/io/buffer/TestPooledBytebuf.java
+++ b/firenio-test/src/main/java/test/io/buffer/TestPooledBytebuf.java
@@ -50,10 +50,10 @@ public void testAlloc() throws Exception {
ByteBuf buf = a.allocate(pa);
a.toString();
bufs.add(buf);
- alloc += buf.limit();
- if (buf.limit() % 3 != 0) {
+ alloc += buf.writeIndex();
+ if (buf.writeIndex() % 3 != 0) {
buf.release();
- alloc -= buf.limit();
+ alloc -= buf.writeIndex();
bufs.remove(buf);
}
}
diff --git a/firenio-test/src/main/java/test/io/http11/TestSimpleHttpClient.java b/firenio-test/src/main/java/test/io/http11/TestSimpleHttpClient.java
index 3befc45cd..a80d5c3e3 100644
--- a/firenio-test/src/main/java/test/io/http11/TestSimpleHttpClient.java
+++ b/firenio-test/src/main/java/test/io/http11/TestSimpleHttpClient.java
@@ -58,7 +58,7 @@ public void accept(Channel ch, Frame frame) {
context.addChannelEventListener(new LoggerChannelOpenListener());
context.setSslContext(sslContext);
long start = Util.now();
- Channel ch = context.connect();
+ Channel ch = context.connect(9999999);
ch.writeAndFlush(new ClientHttpFrame("/test?p=2222"));
w.await(3000);
System.out.println(Util.past(start));
diff --git a/firenio-test/src/main/java/test/io/http11/TestSimpleHttpClient2.java b/firenio-test/src/main/java/test/io/http11/TestSimpleHttpClient2.java
index 9657ca2c0..097193f33 100644
--- a/firenio-test/src/main/java/test/io/http11/TestSimpleHttpClient2.java
+++ b/firenio-test/src/main/java/test/io/http11/TestSimpleHttpClient2.java
@@ -77,7 +77,7 @@ public void channelOpened(Channel ch) throws Exception {
Channel ch = context.connect(999999);
ClientHttpFrame f = new ClientHttpFrame(url, HttpMethod.GET);
// f.setRequestHeader(HttpHeader.Host, host);
- // f.setContent("abc123".getBytes());
+ // f.setContent("abc123".readBytes());
ch.write(f);
ch.writeAndFlush(f);
diff --git a/firenio-test/src/main/java/test/io/http11/TestSimpleWebSocketClient.java b/firenio-test/src/main/java/test/io/http11/TestSimpleWebSocketClient.java
index 6ee9f86e6..3b29a258b 100644
--- a/firenio-test/src/main/java/test/io/http11/TestSimpleWebSocketClient.java
+++ b/firenio-test/src/main/java/test/io/http11/TestSimpleWebSocketClient.java
@@ -18,6 +18,8 @@
import java.util.HashMap;
import java.util.Map;
+import test.test.TestUtil;
+
import com.alibaba.fastjson.JSON;
import com.firenio.codec.http11.ClientHttpCodec;
import com.firenio.codec.http11.ClientHttpFrame;
@@ -61,7 +63,7 @@ public void accept(Channel ch, Frame frame) throws Exception {
}
};
- String host = "www.firenio.com";
+ String host = "firenio.com";
int port = 443;
NioEventLoopGroup g = new NioEventLoopGroup();
g.setEnableMemoryPool(false);
@@ -82,6 +84,13 @@ public void accept(Channel ch, Frame frame) throws Exception {
frame.setRequestHeader(HttpHeader.Accept_Encoding, "gzip, deflate, sdch");
frame.setRequestHeader(HttpHeader.Accept_Language, "zh-CN,zh;q=0.8");
ch.writeAndFlush(frame);
+ Util.sleep(100);
+ WebSocketFrame f2 = new WebSocketFrame();
+ Map map = new HashMap<>();
+ map.put("action", "new-message");
+ map.put("message", TestUtil.newString(1024 * 8));
+ f2.setString(JSON.toJSONString(map), ch);
+ ch.writeAndFlush(f2);
Util.sleep(999999999);
Util.close(context);
diff --git a/firenio-core/src/main/java/com/firenio/collection/Attributes.java b/firenio-test/src/main/java/test/io/jni/TestJNA.java
similarity index 64%
rename from firenio-core/src/main/java/com/firenio/collection/Attributes.java
rename to firenio-test/src/main/java/test/io/jni/TestJNA.java
index 2e8d41e5d..cbc73192a 100644
--- a/firenio-core/src/main/java/com/firenio/collection/Attributes.java
+++ b/firenio-test/src/main/java/test/io/jni/TestJNA.java
@@ -13,23 +13,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.firenio.collection;
+package test.io.jni;
-import java.util.Map;
-import java.util.Set;
+/**
+ * @author: wangkai
+ **/
+public class TestJNA {
-public interface Attributes {
- Map attributes();
+ public static void main(String[] args) {
- void clearAttributes();
- Object getAttribute(Object key);
- Set getAttributeNames();
- Object removeAttribute(Object key);
- void setAttribute(Object key, Object value);
+ }
+
}
diff --git a/firenio-test/src/main/java/test/io/lenthvalue/TestByteBufPool.java b/firenio-test/src/main/java/test/io/lenthvalue/TestByteBufPool.java
new file mode 100644
index 000000000..bfb47e44b
--- /dev/null
+++ b/firenio-test/src/main/java/test/io/lenthvalue/TestByteBufPool.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.io.lenthvalue;
+
+import com.firenio.buffer.ByteBuf;
+import com.firenio.codec.lengthvalue.LengthValueCodec;
+import com.firenio.codec.lengthvalue.LengthValueFrame;
+import com.firenio.component.Channel;
+import com.firenio.component.ChannelConnector;
+import com.firenio.component.Frame;
+import com.firenio.component.IoEventHandle;
+import com.firenio.component.LoggerChannelOpenListener;
+
+/**
+ * @author: wangkai
+ **/
+public class TestByteBufPool {
+
+ public static void main(String[] args) throws Exception {
+
+ ChannelConnector context = new ChannelConnector("192.168.1.102", 6500);
+ context.addChannelEventListener(new LoggerChannelOpenListener());
+ context.addProtocolCodec(new LengthValueCodec());
+ Channel ch = context.connect(3000);
+ ByteBuf buf = ch.allocate();
+ ch.close();
+ buf.release();
+
+ }
+
+
+}
diff --git a/firenio-test/src/main/java/test/io/load/http11/TestHttpLoadServerTFB.java b/firenio-test/src/main/java/test/io/load/http11/TestHttpLoadServerTFB.java
index 72d76eea2..fc4847fbb 100644
--- a/firenio-test/src/main/java/test/io/load/http11/TestHttpLoadServerTFB.java
+++ b/firenio-test/src/main/java/test/io/load/http11/TestHttpLoadServerTFB.java
@@ -15,22 +15,23 @@
*/
package test.io.load.http11;
-import java.io.IOException;
-import java.util.Arrays;
-
import com.firenio.Options;
+import com.firenio.buffer.ByteBuf;
import com.firenio.codec.http11.HttpCodec;
import com.firenio.codec.http11.HttpConnection;
import com.firenio.codec.http11.HttpContentType;
import com.firenio.codec.http11.HttpDateUtil;
import com.firenio.codec.http11.HttpFrame;
import com.firenio.codec.http11.HttpStatus;
+import com.firenio.collection.AttributeKey;
+import com.firenio.collection.AttributeMap;
import com.firenio.collection.ByteTree;
import com.firenio.common.Util;
import com.firenio.component.Channel;
import com.firenio.component.ChannelAcceptor;
import com.firenio.component.ChannelEventListener;
import com.firenio.component.ChannelEventListenerAdapter;
+import com.firenio.component.FastThreadLocal;
import com.firenio.component.Frame;
import com.firenio.component.IoEventHandle;
import com.firenio.component.NioEventLoopGroup;
@@ -40,14 +41,15 @@
import com.firenio.log.LoggerFactory;
import com.jsoniter.output.JsonStream;
import com.jsoniter.output.JsonStreamPool;
-import com.jsoniter.spi.JsonException;
+import com.jsoniter.spi.Slice;
/**
* @author wangkai
*/
public class TestHttpLoadServerTFB {
- static final byte[] STATIC_PLAINTEXT = "Hello, World!".getBytes();
+ static final AttributeKey JSON_BUF = newByteBufKey();
+ static final byte[] STATIC_PLAINTEXT = "Hello, World!".getBytes();
public static void main(String[] args) throws Exception {
boolean lite = Util.getBooleanProperty("lite");
@@ -90,9 +92,23 @@ public void accept(Channel ch, Frame frame) throws Exception {
f.setContentType(HttpContentType.text_plain);
f.setConnection(HttpConnection.NONE);
} else if ("/json".equals(action)) {
- f.setContent(serializeMsg(new Message("Hello, World!")));
- f.setContentType(HttpContentType.application_json);
- f.setConnection(HttpConnection.NONE);
+ ByteBuf temp = FastThreadLocal.get().getAttributeUnsafe(JSON_BUF);
+ JsonStream stream = JsonStreamPool.borrowJsonStream();
+ try {
+ stream.reset(null);
+ stream.writeVal(Message.class, new Message("Hello, World!"));
+ Slice slice = stream.buffer();
+ temp.reset(slice.data(), slice.head(), slice.tail());
+ f.setContent(temp);
+ f.setContentType(HttpContentType.application_json);
+ f.setConnection(HttpConnection.NONE);
+ f.setDate(HttpDateUtil.getDateLine());
+ ch.writeAndFlush(f);
+ ch.release(f);
+ } finally {
+ JsonStreamPool.returnJsonStream(stream);
+ }
+ return;
} else {
System.err.println("404");
f.setString("404,page not found!", ch);
@@ -146,7 +162,6 @@ public void channelClosed(Channel ch) {
@Override
public void channelOpened(Channel ch) throws Exception {
ch.setOption(SocketOptions.TCP_NODELAY, 1);
- ch.setOption(SocketOptions.TCP_QUICKACK, 1);
ch.setOption(SocketOptions.SO_KEEPALIVE, 0);
}
});
@@ -154,17 +169,8 @@ public void channelOpened(Channel ch) throws Exception {
context.bind();
}
- private static byte[] serializeMsg(Message obj) {
- JsonStream stream = JsonStreamPool.borrowJsonStream();
- try {
- stream.reset(null);
- stream.writeVal(Message.class, obj);
- return Arrays.copyOfRange(stream.buffer().data(), 0, stream.buffer().tail());
- } catch (IOException e) {
- throw new JsonException(e);
- } finally {
- JsonStreamPool.returnJsonStream(stream);
- }
+ static AttributeKey newByteBufKey() {
+ return FastThreadLocal.valueOfKey("JSON_BUF", (AttributeMap map, int key) -> map.setAttribute(key, ByteBuf.heap(0)));
}
static class Message {
diff --git a/firenio-test/src/main/java/test/io/load/http11/TestLoadClient.java b/firenio-test/src/main/java/test/io/load/http11/TestLoadClient.java
index ce84734cd..5038c4b2d 100644
--- a/firenio-test/src/main/java/test/io/load/http11/TestLoadClient.java
+++ b/firenio-test/src/main/java/test/io/load/http11/TestLoadClient.java
@@ -16,6 +16,7 @@
package test.io.load.http11;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicInteger;
import com.firenio.buffer.ByteBuf;
import com.firenio.codec.http11.ClientHttpCodec;
@@ -38,72 +39,82 @@ public static void main(String[] args) throws Exception {
String request = "GET /plaintext HTTP/1.1\r\n" + "Host: localhost:8080\r\n" + "Connection: keep-alive\r\n" + "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36\r\n" + "Accept: text/plain,text/html;q=0.9,application/xhtml+xml;q=0.9,application/xml;q=0.8,*/*;q=0.7\r\n\r\n";
- request = "GET /plaintext HTTP/1.1\r\n" + "Host: localhost:8080\r\n" + "Connection: keep-alive\r\n" + "User-Agent: ApacheBench/2.3\r\n" + "Accept: */*\r\n\r\n";
- final String host = "127.0.0.1";
- final int port = 8080;
- final int rpc = 1024 * 4 * 16;
- final int ts = 2;
- final int cpt = 32;
- final int pipe = 64;
- final ByteBuf req = buildReqest(request, pipe);
+ // request = "GET /plaintext HTTP/1.1\r\n" + "Host: localhost:8080\r\n" + "Connection: keep-alive\r\n" + "User-Agent: ApacheBench/2.3\r\n" + "Accept: */*\r\n\r\n";
- test(host, port, req, rpc, ts, cpt, pipe);
+ TestLoadRound round = new TestLoadRound();
+ round.host = "127.0.0.1";
+ round.port = 8080;
+ round.pipes = 16;
+ round.threads = 4;
+ round.requests = 1024 * 1024 * 1;
+ round.connections = 1024 * 8;
+ round.request_buf = buildRequest(request, round.pipes);
+
+ test(round);
}
- private static ByteBuf buildReqest(String request, int pipe) {
+ private static ByteBuf buildRequest(String request, int pipes) {
byte[] bytes = request.getBytes();
- ByteBuf buf = ByteBuf.direct(bytes.length * pipe);
- for (int i = 0; i < pipe; i++) {
- buf.putBytes(bytes);
+ ByteBuf buf = ByteBuf.direct(bytes.length * pipes);
+ for (int i = 0; i < pipes; i++) {
+ buf.writeBytes(bytes);
}
- return buf.flip();
+ return buf;
}
- public static void test(final String host, final int port, final ByteBuf req, final int rpc, final int ts, final int cpt, final int pipe) throws Exception {
- final int cs = cpt * ts;
- final int count = rpc * cs;
- final int batch = count / pipe;
- DebugUtil.info("ts:" + ts);
- DebugUtil.info("cs:" + cs);
- DebugUtil.info("count:" + count);
- DebugUtil.info("pipe:" + pipe);
+ public static void test(TestLoadRound round) throws Exception {
+ final String host = round.host;
+ final ByteBuf buf = round.request_buf;
+ final int port = round.port;
+ final int pipes = round.pipes;
+ final int threads = round.threads;
+ final int requests = round.requests;
+ final int connections = round.connections;
+ final int batch = requests / pipes;
+ DebugUtil.info("requests:" + requests);
+ DebugUtil.info("threads:" + threads);
+ DebugUtil.info("connections:" + connections);
+ DebugUtil.info("pipes:" + pipes);
DebugUtil.info("batch:" + batch);
- NioEventLoopGroup g = new NioEventLoopGroup(true, ts, Integer.MAX_VALUE);
+ NioEventLoopGroup g = new NioEventLoopGroup(true, threads, Integer.MAX_VALUE);
g.start();
- Channel[] chs = new Channel[cs];
+ Channel[] chs = new Channel[connections];
DebugUtil.info("build connections...");
- long last = Util.now();
- CountDownLatch c_latch = new CountDownLatch(cs);
- CountDownLatch b_latch = new CountDownLatch(batch);
- for (int i = 0; i < cs; i++) {
+ CountDownLatch c_latch = new CountDownLatch(connections);
+ CountDownLatch b_latch = new CountDownLatch(batch);
+ AtomicInteger c_complete = new AtomicInteger();
+ long last = Util.now();
+ for (int i = 0; i < connections; i++) {
ChannelConnector context = new ChannelConnector(g.getNext(), host, port);
context.setPrintConfig(false);
context.addProtocolCodec(new ClientHttpCodec());
context.setIoEventHandle(new IoEventHandle() {
int c = 0;
- int b = batch / cs;
+ int b = batch / connections;
@Override
- public void accept(Channel ch, Frame frame) throws Exception {
- if (++c == pipe) {
+ public void accept(Channel ch, Frame frame) {
+ if (++c == pipes) {
c = 0;
b_latch.countDown();
- if (--b == 0) {
- // DebugUtil.info("c complate......");
+ if (--b > 0) {
+ ch.writeAndFlush(buf.duplicate());
} else {
- ch.writeAndFlush(req.duplicate());
+ DebugUtil.info("c complate......" + c_complete.incrementAndGet());
}
}
}
});
- final int ii = i;
- // context.addChannelEventListener(new LoggerChannelOpenListener());
+ final int i_copy = i;
context.connect((ch, ex) -> {
- chs[ii] = ch;
+ if (ex != null) {
+ ex.printStackTrace();
+ }
+ chs[i_copy] = ch;
c_latch.countDown();
- });
+ }, 9000);
}
c_latch.await();
DebugUtil.info("build connections cost:" + (Util.now() - last));
@@ -111,16 +122,28 @@ public void accept(Channel ch, Frame frame) throws Exception {
DebugUtil.info("start request...");
last = Util.now();
for (int i = 0; i < chs.length; i++) {
- chs[i].writeAndFlush(req.duplicate());
+ chs[i].writeAndFlush(buf.duplicate());
}
b_latch.await();
long cost = (Util.now() - last);
DebugUtil.info("request cost:" + cost);
- DebugUtil.info("request rps:" + (count * 1000d / cost));
+ DebugUtil.info("request rps:" + (requests * 1000d / cost));
for (int i = 0; i < chs.length; i++) {
chs[i].close();
}
g.stop();
}
+ static class TestLoadRound {
+
+ String host;
+ ByteBuf request_buf;
+ int port;
+ int threads;
+ int pipes;
+ int requests;
+ int connections;
+
+ }
+
}
diff --git a/firenio-test/src/main/java/test/io/udp/TestUDPClient.java b/firenio-test/src/main/java/test/io/udp/TestUDPClient.java
index e6a03ebc1..74baac58f 100644
--- a/firenio-test/src/main/java/test/io/udp/TestUDPClient.java
+++ b/firenio-test/src/main/java/test/io/udp/TestUDPClient.java
@@ -37,7 +37,7 @@ public static void main(String[] args) throws Exception {
//
// DatagramChannel ch = connector.connect();
//
- // DatagramPacket packet = DatagramPacket.createSendPacket("hello world!".getBytes());
+ // DatagramPacket packet = DatagramPacket.createSendPacket("hello world!".readBytes());
//
// ch.sendPacket(packet);
//
diff --git a/firenio-test/src/main/java/test/io/udp/TestUDPReceiveHandle.java b/firenio-test/src/main/java/test/io/udp/TestUDPReceiveHandle.java
index 32c14eccf..374099102 100644
--- a/firenio-test/src/main/java/test/io/udp/TestUDPReceiveHandle.java
+++ b/firenio-test/src/main/java/test/io/udp/TestUDPReceiveHandle.java
@@ -66,7 +66,7 @@ public class TestUDPReceiveHandle {
//
// for (int i = 0; i < 10000000; i++) {
//
- // byte[] data = (inviteUsername + i).getBytes();
+ // byte[] data = (inviteUsername + i).readBytes();
//
// DatagramPacket packet = factory.createDatagramPacket(data);
//
@@ -103,7 +103,7 @@ public class TestUDPReceiveHandle {
//
// for (int i = 0; i < 10000000; i++) {
//
- // byte[] data = (client.getInviteUsername() + i).getBytes();
+ // byte[] data = (client.getInviteUsername() + i).readBytes();
//
// DatagramPacket packet = factory.createDatagramPacket(data);
//
diff --git a/firenio-test/src/main/java/test/io/udp/TestUDPServer.java b/firenio-test/src/main/java/test/io/udp/TestUDPServer.java
index 1465cc8c1..ddfeb4491 100644
--- a/firenio-test/src/main/java/test/io/udp/TestUDPServer.java
+++ b/firenio-test/src/main/java/test/io/udp/TestUDPServer.java
@@ -29,7 +29,7 @@ public static void main(String[] args) throws IOException {
//
// DebugUtil.debug(req);
//
- // byte[] resMsg = ("yes ," + req).getBytes(Encoding.UTF8);
+ // byte[] resMsg = ("yes ," + req).readBytes(Encoding.UTF8);
//
// DatagramPacket res = DatagramPacket.createSendPacket(resMsg);
//
diff --git a/firenio-test/src/main/java/test/others/FibonacciSeq.java b/firenio-test/src/main/java/test/others/FibonacciSeq.java
index 95f23611a..b41cacfd7 100644
--- a/firenio-test/src/main/java/test/others/FibonacciSeq.java
+++ b/firenio-test/src/main/java/test/others/FibonacciSeq.java
@@ -31,7 +31,7 @@ static long fi(long n) {
long n_2 = 0;
long n_1 = 1;
long sum = n_2 + n_1;
- for (int i = 1; i < n; i++) {
+ for (; n > 0; n--) {
n_2 = n_1;
n_1 = sum;
sum = n_2 + n_1;
diff --git a/firenio-test/src/main/java/test/others/GraphicsTest.java b/firenio-test/src/main/java/test/others/GraphicsTest.java
index 44a919bec..cb9616b37 100644
--- a/firenio-test/src/main/java/test/others/GraphicsTest.java
+++ b/firenio-test/src/main/java/test/others/GraphicsTest.java
@@ -279,14 +279,14 @@ void drawTest(Graphics gra) {
boolean[] tar = bits[i];
for (int j = 0; j < width; j++) {
byte b = array[bIndex++];
- tar[j * cheng + 0] = ByteUtil.getBoolean(b, 0);
- tar[j * cheng + 1] = ByteUtil.getBoolean(b, 1);
- tar[j * cheng + 2] = ByteUtil.getBoolean(b, 2);
- tar[j * cheng + 3] = ByteUtil.getBoolean(b, 3);
- tar[j * cheng + 4] = ByteUtil.getBoolean(b, 4);
- tar[j * cheng + 5] = ByteUtil.getBoolean(b, 5);
- tar[j * cheng + 6] = ByteUtil.getBoolean(b, 6);
- tar[j * cheng + 7] = ByteUtil.getBoolean(b, 7);
+ tar[j * cheng + 0] = ByteUtil.getBit(b, 0);
+ tar[j * cheng + 1] = ByteUtil.getBit(b, 1);
+ tar[j * cheng + 2] = ByteUtil.getBit(b, 2);
+ tar[j * cheng + 3] = ByteUtil.getBit(b, 3);
+ tar[j * cheng + 4] = ByteUtil.getBit(b, 4);
+ tar[j * cheng + 5] = ByteUtil.getBit(b, 5);
+ tar[j * cheng + 6] = ByteUtil.getBit(b, 6);
+ tar[j * cheng + 7] = ByteUtil.getBit(b, 7);
tar[j * cheng + 0] = r.nextBoolean();
tar[j * cheng + 1] = r.nextBoolean();
diff --git a/firenio-test/src/main/java/test/others/RBTree.java b/firenio-test/src/main/java/test/others/RBTree.java
new file mode 100644
index 000000000..1060eb98b
--- /dev/null
+++ b/firenio-test/src/main/java/test/others/RBTree.java
@@ -0,0 +1,687 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.others;
+
+/**
+ * @author: wangkai
+ **/
+public class RBTree {
+
+ private RBTNode mRoot; // 根结点
+
+ private static final boolean RED = false;
+ private static final boolean BLACK = true;
+
+ public class RBTNode {
+ boolean color; // 颜色
+ int key; // 关键字(键值)
+ V value;
+ RBTNode left; // 左孩子
+ RBTNode right; // 右孩子
+ RBTNode parent; // 父结点
+
+ public String toString() {
+ return "" + key + (this.color == RED ? "(R)" : "B");
+ }
+ }
+
+ public RBTree() {
+ mRoot = null;
+ }
+
+ private RBTNode parentOf(RBTNode node) {
+ return node != null ? node.parent : null;
+ }
+
+ private boolean colorOf(RBTNode node) {
+ return node != null ? node.color : BLACK;
+ }
+
+ private boolean isRed(RBTNode node) {
+ return ((node != null) && (node.color == RED)) ? true : false;
+ }
+
+ private boolean isBlack(RBTNode node) {
+ return !isRed(node);
+ }
+
+ private void setBlack(RBTNode node) {
+ if (node != null)
+ node.color = BLACK;
+ }
+
+ private void setRed(RBTNode node) {
+ if (node != null)
+ node.color = RED;
+ }
+
+ private void setParent(RBTNode node, RBTNode parent) {
+ if (node != null)
+ node.parent = parent;
+ }
+
+ private void setColor(RBTNode node, boolean color) {
+ if (node != null)
+ node.color = color;
+ }
+
+ /*
+ * 前序遍历"红黑树"
+ */
+ private void preOrder(RBTNode tree) {
+ if (tree != null) {
+ System.out.print(tree.key + " ");
+ preOrder(tree.left);
+ preOrder(tree.right);
+ }
+ }
+
+ public void preOrder() {
+ preOrder(mRoot);
+ }
+
+ /*
+ * 中序遍历"红黑树"
+ */
+ private void inOrder(RBTNode tree) {
+ if (tree != null) {
+ inOrder(tree.left);
+ System.out.print(tree.key + " ");
+ inOrder(tree.right);
+ }
+ }
+
+ public void inOrder() {
+ inOrder(mRoot);
+ }
+
+ /*
+ * 后序遍历"红黑树"
+ */
+ private void postOrder(RBTNode tree) {
+ if (tree != null) {
+ postOrder(tree.left);
+ postOrder(tree.right);
+ System.out.print(tree.key + " ");
+ }
+ }
+
+ public void postOrder() {
+ postOrder(mRoot);
+ }
+
+ /*
+ * (递归实现)查找"红黑树x"中键值为key的节点
+ */
+ private RBTNode search(RBTNode x, int key) {
+ if (x == null)
+ return x;
+
+ int cmp = key - x.key;//TODO
+ if (cmp < 0)
+ return search(x.left, key);
+ else if (cmp > 0)
+ return search(x.right, key);
+ else
+ return x;
+ }
+
+ public RBTNode search(int key) {
+ return search(mRoot, key);
+ }
+
+ /*
+ * (非递归实现)查找"红黑树x"中键值为key的节点
+ */
+ private RBTNode iterativeSearch(RBTNode x, int key) {
+ while (x != null) {
+ int cmp = key - x.key;//TODO
+
+ if (cmp < 0)
+ x = x.left;
+ else if (cmp > 0)
+ x = x.right;
+ else
+ return x;
+ }
+
+ return x;
+ }
+
+ public RBTNode iterativeSearch(int key) {
+ return iterativeSearch(mRoot, key);
+ }
+
+ /*
+ * 查找最小结点:返回tree为根结点的红黑树的最小结点。
+ */
+ private RBTNode minimum(RBTNode tree) {
+ if (tree == null)
+ return null;
+
+ while (tree.left != null)
+ tree = tree.left;
+ return tree;
+ }
+
+ public RBTNode minimum() {
+ return minimum(mRoot);
+ }
+
+ /*
+ * 查找最大结点:返回tree为根结点的红黑树的最大结点。
+ */
+ private RBTNode maximum(RBTNode tree) {
+ if (tree == null)
+ return null;
+
+ while (tree.right != null)
+ tree = tree.right;
+ return tree;
+ }
+
+ public RBTNode maximum() {
+ return maximum(mRoot);
+ }
+
+ /*
+ * 找结点(x)的后继结点。即,查找"红黑树中数据值大于该结点"的"最小结点"。
+ */
+ public RBTNode successor(RBTNode x) {
+ // 如果x存在右孩子,则"x的后继结点"为 "以其右孩子为根的子树的最小结点"。
+ if (x.right != null)
+ return minimum(x.right);
+
+ // 如果x没有右孩子。则x有以下两种可能:
+ // (01) x是"一个左孩子",则"x的后继结点"为 "它的父结点"。
+ // (02) x是"一个右孩子",则查找"x的最低的父结点,并且该父结点要具有左孩子",找到的这个"最低的父结点"就是"x的后继结点"。
+ RBTNode y = x.parent;
+ while ((y != null) && (x == y.right)) {
+ x = y;
+ y = y.parent;
+ }
+
+ return y;
+ }
+
+ /*
+ * 找结点(x)的前驱结点。即,查找"红黑树中数据值小于该结点"的"最大结点"。
+ */
+ public RBTNode predecessor(RBTNode x) {
+ // 如果x存在左孩子,则"x的前驱结点"为 "以其左孩子为根的子树的最大结点"。
+ if (x.left != null)
+ return maximum(x.left);
+
+ // 如果x没有左孩子。则x有以下两种可能:
+ // (01) x是"一个右孩子",则"x的前驱结点"为 "它的父结点"。
+ // (01) x是"一个左孩子",则查找"x的最低的父结点,并且该父结点要具有右孩子",找到的这个"最低的父结点"就是"x的前驱结点"。
+ RBTNode y = x.parent;
+ while ((y != null) && (x == y.left)) {
+ x = y;
+ y = y.parent;
+ }
+
+ return y;
+ }
+
+ /*
+ * 对红黑树的节点(x)进行左旋转
+ *
+ * 左旋示意图(对节点x进行左旋):
+ * px px
+ * / /
+ * x y
+ * / \ --(左旋)-. / \ #
+ * lx y x ry
+ * / \ / \
+ * ly ry lx ly
+ *
+ *
+ */
+ private void leftRotate(RBTNode x) {
+ // 设置x的右孩子为y
+ RBTNode y = x.right;
+
+ // 将 “y的左孩子” 设为 “x的右孩子”;
+ // 如果y的左孩子非空,将 “x” 设为 “y的左孩子的父亲”
+ x.right = y.left;
+ if (y.left != null)
+ y.left.parent = x;
+
+ // 将 “x的父亲” 设为 “y的父亲”
+ y.parent = x.parent;
+
+ if (x.parent == null) {
+ this.mRoot = y; // 如果 “x的父亲” 是空节点,则将y设为根节点
+ } else {
+ if (x.parent.left == x)
+ x.parent.left = y; // 如果 x是它父节点的左孩子,则将y设为“x的父节点的左孩子”
+ else
+ x.parent.right = y; // 如果 x是它父节点的左孩子,则将y设为“x的父节点的左孩子”
+ }
+
+ // 将 “x” 设为 “y的左孩子”
+ y.left = x;
+ // 将 “x的父节点” 设为 “y”
+ x.parent = y;
+ }
+
+ /*
+ * 对红黑树的节点(y)进行右旋转
+ *
+ * 右旋示意图(对节点y进行左旋):
+ * py py
+ * / /
+ * y x
+ * / \ --(右旋)-. / \ #
+ * x ry lx y
+ * / \ / \ #
+ * lx rx rx ry
+ *
+ */
+ private void rightRotate(RBTNode y) {
+ // 设置x是当前节点的左孩子。
+ RBTNode x = y.left;
+
+ // 将 “x的右孩子” 设为 “y的左孩子”;
+ // 如果"x的右孩子"不为空的话,将 “y” 设为 “x的右孩子的父亲”
+ y.left = x.right;
+ if (x.right != null)
+ x.right.parent = y;
+
+ // 将 “y的父亲” 设为 “x的父亲”
+ x.parent = y.parent;
+
+ if (y.parent == null) {
+ this.mRoot = x; // 如果 “y的父亲” 是空节点,则将x设为根节点
+ } else {
+ if (y == y.parent.right)
+ y.parent.right = x; // 如果 y是它父节点的右孩子,则将x设为“y的父节点的右孩子”
+ else
+ y.parent.left = x; // (y是它父节点的左孩子) 将x设为“x的父节点的左孩子”
+ }
+
+ // 将 “y” 设为 “x的右孩子”
+ x.right = y;
+
+ // 将 “y的父节点” 设为 “x”
+ y.parent = x;
+ }
+
+ /*
+ * 红黑树插入修正函数
+ *
+ * 在向红黑树中插入节点之后(失去平衡),再调用该函数;
+ * 目的是将它重新塑造成一颗红黑树。
+ *
+ * 参数说明:
+ * node 插入的结点 // 对应《算法导论》中的z
+ */
+ private void insertFixUp(RBTNode node) {
+ RBTNode parent, gparent;
+
+ // 若“父节点存在,并且父节点的颜色是红色”
+ while (((parent = parentOf(node)) != null) && isRed(parent)) {
+ gparent = parentOf(parent);
+
+ //若“父节点”是“祖父节点的左孩子”
+ if (parent == gparent.left) {
+ // Case 1条件:叔叔节点是红色
+ RBTNode uncle = gparent.right;
+ if ((uncle != null) && isRed(uncle)) {
+ setBlack(uncle);
+ setBlack(parent);
+ setRed(gparent);
+ node = gparent;
+ continue;
+ }
+
+ // Case 2条件:叔叔是黑色,且当前节点是右孩子
+ if (parent.right == node) {
+ RBTNode tmp;
+ leftRotate(parent);
+ tmp = parent;
+ parent = node;
+ node = tmp;
+ }
+
+ // Case 3条件:叔叔是黑色,且当前节点是左孩子。
+ setBlack(parent);
+ setRed(gparent);
+ rightRotate(gparent);
+ } else { //若“z的父节点”是“z的祖父节点的右孩子”
+ // Case 1条件:叔叔节点是红色
+ RBTNode uncle = gparent.left;
+ if ((uncle != null) && isRed(uncle)) {
+ setBlack(uncle);
+ setBlack(parent);
+ setRed(gparent);
+ node = gparent;
+ continue;
+ }
+
+ // Case 2条件:叔叔是黑色,且当前节点是左孩子
+ if (parent.left == node) {
+ RBTNode tmp;
+ rightRotate(parent);
+ tmp = parent;
+ parent = node;
+ node = tmp;
+ }
+
+ // Case 3条件:叔叔是黑色,且当前节点是右孩子。
+ setBlack(parent);
+ setRed(gparent);
+ leftRotate(gparent);
+ }
+ }
+
+ // 将根节点设为黑色
+ setBlack(this.mRoot);
+ }
+
+ /*
+ * 将结点插入到红黑树中
+ *
+ * 参数说明:
+ * node 插入的结点 // 对应《算法导论》中的node
+ */
+ public void insert(RBTNode node) {
+ int cmp;
+ RBTNode y = null;
+ RBTNode x = this.mRoot;
+
+ // 1. 将红黑树当作一颗二叉查找树,将节点添加到二叉查找树中。
+ while (x != null) {
+ y = x;
+ cmp = node.key - x.key; //TODO
+ if (cmp < 0)
+ x = x.left;
+ else
+ x = x.right;
+ }
+
+ node.parent = y;
+ if (y != null) {
+ cmp = node.key - y.key; //TODO
+ if (cmp < 0)
+ y.left = node;
+ else
+ y.right = node;
+ } else {
+ this.mRoot = node;
+ }
+
+ // 2. 设置节点的颜色为红色
+ node.color = RED;
+
+ // 3. 将它重新修正为一颗二叉查找树
+ insertFixUp(node);
+ }
+
+ /*
+ * 新建结点(key),并将其插入到红黑树中
+ *
+ * 参数说明:
+ * key 插入结点的键值
+ */
+ public void insert(int key, V value) {
+ RBTNode node = new RBTNode();
+ node.color = BLACK;
+ node.key = key;
+ node.value = value;
+ insert(node);
+ }
+
+ /*
+ * 红黑树删除修正函数
+ *
+ * 在从红黑树中删除插入节点之后(红黑树失去平衡),再调用该函数;
+ * 目的是将它重新塑造成一颗红黑树。
+ *
+ * 参数说明:
+ * node 待修正的节点
+ */
+ private void removeFixUp(RBTNode node, RBTNode parent) {
+ RBTNode other;
+
+ while ((node == null || isBlack(node)) && (node != this.mRoot)) {
+ if (parent.left == node) {
+ other = parent.right;
+ if (isRed(other)) {
+ // Case 1: x的兄弟w是红色的
+ setBlack(other);
+ setRed(parent);
+ leftRotate(parent);
+ other = parent.right;
+ }
+
+ if ((other.left == null || isBlack(other.left)) && (other.right == null || isBlack(other.right))) {
+ // Case 2: x的兄弟w是黑色,且w的俩个孩子也都是黑色的
+ setRed(other);
+ node = parent;
+ parent = parentOf(node);
+ } else {
+
+ if (other.right == null || isBlack(other.right)) {
+ // Case 3: x的兄弟w是黑色的,并且w的左孩子是红色,右孩子为黑色。
+ setBlack(other.left);
+ setRed(other);
+ rightRotate(other);
+ other = parent.right;
+ }
+ // Case 4: x的兄弟w是黑色的;并且w的右孩子是红色的,左孩子任意颜色。
+ setColor(other, colorOf(parent));
+ setBlack(parent);
+ setBlack(other.right);
+ leftRotate(parent);
+ node = this.mRoot;
+ break;
+ }
+ } else {
+
+ other = parent.left;
+ if (isRed(other)) {
+ // Case 1: x的兄弟w是红色的
+ setBlack(other);
+ setRed(parent);
+ rightRotate(parent);
+ other = parent.left;
+ }
+
+ if ((other.left == null || isBlack(other.left)) && (other.right == null || isBlack(other.right))) {
+ // Case 2: x的兄弟w是黑色,且w的俩个孩子也都是黑色的
+ setRed(other);
+ node = parent;
+ parent = parentOf(node);
+ } else {
+
+ if (other.left == null || isBlack(other.left)) {
+ // Case 3: x的兄弟w是黑色的,并且w的左孩子是红色,右孩子为黑色。
+ setBlack(other.right);
+ setRed(other);
+ leftRotate(other);
+ other = parent.left;
+ }
+
+ // Case 4: x的兄弟w是黑色的;并且w的右孩子是红色的,左孩子任意颜色。
+ setColor(other, colorOf(parent));
+ setBlack(parent);
+ setBlack(other.left);
+ rightRotate(parent);
+ node = this.mRoot;
+ break;
+ }
+ }
+ }
+
+ if (node != null)
+ setBlack(node);
+ }
+
+ /*
+ * 删除结点(node),并返回被删除的结点
+ *
+ * 参数说明:
+ * node 删除的结点
+ */
+ public void remove(RBTNode node) {
+ RBTNode child, parent;
+ boolean color;
+
+ // 被删除节点的"左右孩子都不为空"的情况。
+ if ((node.left != null) && (node.right != null)) {
+ // 被删节点的后继节点。(称为"取代节点")
+ // 用它来取代"被删节点"的位置,然后再将"被删节点"去掉。
+ RBTNode replace = node;
+
+ // 获取后继节点
+ replace = replace.right;
+ while (replace.left != null)
+ replace = replace.left;
+
+ // "node节点"不是根节点(只有根节点不存在父节点)
+ if (parentOf(node) != null) {
+ if (parentOf(node).left == node)
+ parentOf(node).left = replace;
+ else
+ parentOf(node).right = replace;
+ } else {
+ // "node节点"是根节点,更新根节点。
+ this.mRoot = replace;
+ }
+
+ // child是"取代节点"的右孩子,也是需要"调整的节点"。
+ // "取代节点"肯定不存在左孩子!因为它是一个后继节点。
+ child = replace.right;
+ parent = parentOf(replace);
+ // 保存"取代节点"的颜色
+ color = colorOf(replace);
+
+ // "被删除节点"是"它的后继节点的父节点"
+ if (parent == node) {
+ parent = replace;
+ } else {
+ // child不为空
+ if (child != null)
+ setParent(child, parent);
+ parent.left = child;
+
+ replace.right = node.right;
+ setParent(node.right, replace);
+ }
+
+ replace.parent = node.parent;
+ replace.color = node.color;
+ replace.left = node.left;
+ node.left.parent = replace;
+
+ if (color == BLACK)
+ removeFixUp(child, parent);
+
+ node = null;
+ return;
+ }
+
+ if (node.left != null) {
+ child = node.left;
+ } else {
+ child = node.right;
+ }
+
+ parent = node.parent;
+ // 保存"取代节点"的颜色
+ color = node.color;
+
+ if (child != null)
+ child.parent = parent;
+
+ // "node节点"不是根节点
+ if (parent != null) {
+ if (parent.left == node)
+ parent.left = child;
+ else
+ parent.right = child;
+ } else {
+ this.mRoot = child;
+ }
+
+ if (color == BLACK)
+ removeFixUp(child, parent);
+ node = null;
+ }
+
+ /*
+ * 删除结点(z),并返回被删除的结点
+ *
+ * 参数说明:
+ * tree 红黑树的根结点
+ * z 删除的结点
+ */
+ public void remove(int key) {
+ RBTNode node;
+
+ if ((node = search(mRoot, key)) != null)
+ remove(node);
+ }
+
+ /*
+ * 销毁红黑树
+ */
+ private void destroy(RBTNode tree) {
+ if (tree == null)
+ return;
+
+ if (tree.left != null)
+ destroy(tree.left);
+ if (tree.right != null)
+ destroy(tree.right);
+
+ tree = null;
+ }
+
+ public void clear() {
+ destroy(mRoot);
+ mRoot = null;
+ }
+
+ /*
+ * 打印"红黑树"
+ *
+ * key -- 节点的键值
+ * direction -- 0,表示该节点是根节点;
+ * -1,表示该节点是它的父结点的左孩子;
+ * 1,表示该节点是它的父结点的右孩子。
+ */
+ private void print(RBTNode tree, int key, int direction) {
+
+ if (tree != null) {
+
+ if (direction == 0) // tree是根节点
+ System.out.printf("%2d(B) is root\n", tree.key);
+ else // tree是分支节点
+ System.out.printf("%2d(%s) is %2d's %6s child\n", tree.key, isRed(tree) ? "R" : "B", key, direction == 1 ? "right" : "left");
+
+ print(tree.left, tree.key, -1);
+ print(tree.right, tree.key, 1);
+ }
+ }
+
+ public void print() {
+ if (mRoot != null)
+ print(mRoot, mRoot.key, 0);
+ }
+}
diff --git a/firenio-test/src/main/java/test/others/RBTreeTest.java b/firenio-test/src/main/java/test/others/RBTreeTest.java
new file mode 100644
index 000000000..0359bd55d
--- /dev/null
+++ b/firenio-test/src/main/java/test/others/RBTreeTest.java
@@ -0,0 +1,50 @@
+package test.others;
+
+import org.junit.Test;
+import test.others.RBTree.RBTNode;
+
+import static org.junit.Assert.*;
+
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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.
+ */
+public class RBTreeTest {
+
+ public static void main(String[] args) {
+
+ RBTree tree = new RBTree<>();
+
+ tree.insert(5, "5");
+ tree.insert(2, "2");
+ tree.insert(1, "1");
+ tree.insert(2, "2");
+ tree.insert(4, "4");
+ tree.insert(6, "6");
+
+ for(;;){
+ RBTNode n = tree.maximum();
+ if (n == null){
+ break;
+ }
+ System.out.println(n.value);
+ tree.remove(n);
+ }
+
+
+
+
+ }
+
+}
\ No newline at end of file
diff --git a/firenio-test/src/main/java/test/others/TestBitSet.java b/firenio-test/src/main/java/test/others/TestBitSet.java
new file mode 100644
index 000000000..a79a8c07b
--- /dev/null
+++ b/firenio-test/src/main/java/test/others/TestBitSet.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.others;
+
+import java.util.BitSet;
+
+/**
+ * @author: wangkai
+ **/
+public class TestBitSet {
+
+ public static void main(String[] args) {
+
+ int cycle = 256;
+ int count = 1024 * 1024;
+ long startTime = System.currentTimeMillis();
+// BitSet set = new BitSet(count);
+ MyBitSet set = new MyBitSet(count);
+ for (int i = 0; i < cycle; i++) {
+// testJdkBitSet(set, count);
+ testMyBitSet(set,count);
+ }
+ long past = System.currentTimeMillis() - startTime;
+
+ System.out.println("cost: " + past);
+
+
+ }
+
+
+ static void testMyBitSet(MyBitSet set, int count) {
+ for (int i = 0; i < count; i++) {
+ set.setFree(i);
+ }
+ for (int i = 0; i < count; i++) {
+ set.clearFree(i);
+ }
+ }
+
+
+ static void testJdkBitSet(BitSet set, int count) {
+ for (int i = 0; i < count; i++) {
+ set.set(i);
+ }
+ for (int i = 0; i < count; i++) {
+ set.clear(i);
+ }
+ }
+
+ static class MyBitSet {
+
+ static final int ADDRESS_BITS_PER_WORD = 6;
+
+ private final long[] frees;
+
+ MyBitSet(int cap) {
+ frees = new long[cap / 8];
+ }
+
+ private static int wordIndex(int bitIndex) {
+ return bitIndex >> ADDRESS_BITS_PER_WORD;
+ }
+
+ private void setFree(int index) {
+ int wordIndex = wordIndex(index);
+ frees[wordIndex] |= (1L << index);
+ }
+
+ private void clearFree(int index) {
+ int wordIndex = wordIndex(index);
+ frees[wordIndex] &= ~(1L << index);
+ }
+
+ private boolean isFree(int index) {
+ int wordIndex = wordIndex(index);
+ return ((frees[wordIndex] & (1L << index)) != 0);
+ }
+
+ }
+
+}
diff --git a/firenio-test/src/main/java/test/others/TestIntMap.java b/firenio-test/src/main/java/test/others/TestIntMap.java
index af406b3cb..1883dfc63 100644
--- a/firenio-test/src/main/java/test/others/TestIntMap.java
+++ b/firenio-test/src/main/java/test/others/TestIntMap.java
@@ -16,7 +16,10 @@
package test.others;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Random;
import org.junit.Before;
@@ -24,66 +27,105 @@
import com.firenio.collection.IntMap;
import com.firenio.common.Assert;
+import com.firenio.log.Logger;
+import com.firenio.log.LoggerFactory;
/**
* @author wangkai
*/
public class TestIntMap {
- IntMap map = new IntMap<>(16);
- List list = new ArrayList<>(16);
+ static {
+ LoggerFactory.setEnableSLF4JLogger(false);
+ }
+
+ Logger logger = LoggerFactory.getLogger(TestIntMap.class);
+
+ int cap = 1000;
+ IntMap map = new IntMap<>(16);
+ List list = new ArrayList<>(16);
@Before
public void before() {
- Random r = new Random();
- for (int i = 0; i < 1000; i++) {
- int k = r.nextInt(Integer.MAX_VALUE);
- String v = String.valueOf(k);
- map.put(k, v);
- list.add(k);
+ list = newDataList();
+ for (Integer i : list) {
+ map.put(i, i);
+ }
+ logger.info("size: " + list.size());
+ logger.info("list: " + list);
+ }
+
+ List newDataList() {
+ boolean random = true;
+ if (random) {
+ Random r = new Random();
+ List list = new ArrayList<>(cap);
+ for (int i = 0; i < cap; i++) {
+ int k = r.nextInt(2000);
+ if (list.contains(k)) {
+ i--;
+ continue;
+ }
+ list.add(k);
+ }
+ return list;
+ } else {
+ Integer[] data = new Integer[]{1817709497, 1020619099, 1759681358, 941541627, 62623315, 508772680, 1298922045, 1361284904, 1807787055, 1736261043, 1533483009, 2069766034, 1175456478, 1493485670, 2145530210, 624325508, 1352607519, 1627640025, 271562923, 277362065, 1285593433, 951112590, 18895618, 327371137, 267540549, 1166392586, 1056315609, 1547479254, 1797755816, 872923760, 1527655293, 1021066745, 1118748990, 954591675, 364696012, 1882523654, 502814131, 411409303, 1630105091, 702509361, 1107872714, 955267293, 272285365, 239231443, 766032801, 1678396841, 1207499992, 1962293781, 1586488331, 128752666, 2035452154, 2067102775, 211036189, 272685222, 1980299665, 927043966, 137601733, 1283953175, 1624734831, 626963384, 1826689683, 332029734, 465608020, 703636845, 124518299, 1519717298, 1996530590, 183665316, 1506942323, 113385373, 411228443, 1075745871, 1440582488, 768784708, 705375231, 692039764, 1330361453, 365909401, 816496113, 66342968, 921874979, 686735326, 296555071, 239347818, 1586967220, 1083835135, 420785459, 1013688874, 1728251336, 1756878477, 655955581, 1791851028, 1737265467, 1175953747, 1644515535, 1336968525, 297897974, 570149783, 2138372232, 1005715272, 1231789306, 449100526, 1415535496, 2025665078, 1053502587, 1916367292, 969079842, 1330621448, 785233193, 1384148040, 1631129903, 1030681122, 88992649, 1395324280, 274707775, 102598045, 1010372994, 157207853, 1426233067, 485466681, 501382132, 2093849149, 22355014, 1337770462, 1895731331, 208093705, 344853362, 754028237, 1406180722, 1898700731, 1206118990, 1561759336, 1982533033, 1288942878, 1131046733, 1322938010, 1696045785, 818876186, 1824800098, 179535844, 1735737270, 101038026, 1344414999, 1285195269, 313773155, 777859132, 29263037, 1880729926, 1446059756, 1879477188, 68071870, 126677599, 2025464300, 59270909, 811447566, 1738431241, 1584517967, 1577522270, 1502717120, 1918770465, 1073919282, 689223796, 446416053, 980978294, 581118695, 1106554817, 77906031, 1368741679, 1497064468, 123287601, 663318531, 1770053852, 1644402683, 1004009525, 1188149805, 889101335, 861631188, 474062207, 890389886, 1269592790, 579319638, 491941208, 1489160880, 1188134225, 1167144532, 796213409, 1260255770, 1877942154, 248536708, 523240804, 1757218366, 1813132670, 1323484764, 484999190, 1399850368, 1490196454, 888943126, 1889642091, 1718975730, 1145693098, 1541060562, 566070742, 80119370, 1152323043, 1128121305, 1163233180, 298984181, 1565716107, 1958338303, 1324983444, 517566020, 1175620548, 859781411, 423787133, 55017669, 1788252097, 1288116689, 1362339068, 1207629485, 1954804565, 226261254, 110828592, 698624880, 2109245206, 1702240787, 469834483, 1413110899, 1986962733, 165470874, 1140715184, 37422297, 558757309, 1446930357, 998681308, 2030691450, 295948270, 1391823671, 781670931, 494748658, 1289511317, 1276834570, 372303567, 1871259605, 1350461314, 360514743, 629839303, 1396000000, 1946017893, 1506561797, 1144687586, 1253353483, 509002845, 1301916600, 1905686998, 1588797914, 1898408735, 1544911738, 1380263778, 1306241875, 110291647, 1876131288, 2106275876, 1952191018, 1060002078, 55371619, 1206461463, 1524457687, 2118154737, 462583799, 1103494573, 1059951529, 1531577193, 96105240, 583155589, 516836596, 1355105156, 2033351800, 1988590538, 367352422, 1139707888, 341539477, 572352295, 1992752504, 1825802903, 1037418879, 1721391466, 480184576, 1467868364, 1707468727, 1057815988, 498927075, 1735322384, 188663603, 358517850, 1893249255, 1483457408, 151211135, 4753500, 258425766, 393144543, 35313149, 1492032128, 1794054814, 319949884, 878511437, 14468106, 726559334, 747382592, 1631978695, 179553049, 1900205563, 202516758, 1781687077, 2085692065, 105568313, 430262263, 1957807934, 106827776, 1314329189, 1019257169, 403824109, 42446911, 2144383463, 310932115, 1656161296, 1490374376, 1952136981, 901239959, 1114525356, 423387263, 462112554, 976126893, 381465390, 1045951134, 363885397, 105832000, 1634283980, 145277872, 1323876078, 1861542952, 473695242, 1620892746, 2065407683, 38903947, 1229648217, 1550918689, 1700203409, 1728252016, 894110682, 728566956, 91586958, 1844901858, 1398945600, 1101007703, 1427318563, 128489405, 1408695251, 130694496, 1372155063, 984749592, 2049132432, 1578446674, 1502320551, 253836111, 1574362990, 1532453404, 66308690, 1444677035, 1031824059, 91015118, 1735867216, 1221268912, 1163911845, 1264062959, 1290890690, 382883076, 1788096469, 1258572669, 299982020, 410837495, 212082742, 2017187970, 1462807551, 298314163, 1272393428, 1617007951, 1049366364, 843627265, 826603487, 810184536, 1549089747, 354745269, 1429811918, 1927377323, 321508193, 1352174264, 1367469216, 1973804814, 1157619224, 745748656, 295167037, 1395823541, 1410302544, 724640078, 242027259, 628590749, 1414188539, 1819479859, 1831553854, 482472584, 2065175, 1447621760, 1198380855, 331159189, 97253692, 1402413561, 1923178957, 1390251643, 1288652373, 159352532, 1197196184, 147478114, 1846411371, 1321394980, 784444937, 2096275038, 1078463133, 455243485, 1536765608, 993327496, 445710124, 1753831299, 814867574, 854336699, 113502387, 1020081780, 297265521, 578764520, 528751731, 1405682126, 34902582, 1180101911, 1130899404, 990931454, 5260736, 1417053179, 914940616, 1629615590, 2145046350, 1150284080, 66968018, 711847850, 198421603, 148553235, 183591044, 23270424, 599914727, 1910646334, 705281950, 144084657, 138656619, 1552145310, 218763282, 1034644568, 693531530, 353940019, 182744379, 1769361046, 1826024555, 2128219492, 1730185262, 144492936, 1752462690, 1990887677, 999548457, 1279030886, 112444086, 437647302, 1947726889, 2057069744, 1558173821, 1447326145, 1950812568, 757871607, 873169316, 6147071, 1618760738, 1841217605, 262927627, 1293317151, 846522024, 1436740394, 821914317, 1970555236, 1814398286, 77310820, 2037154717, 451521906, 1069539503, 1281436970, 1674282060, 1313777317, 328929840, 1910992149, 2051573607, 933465614, 115231602, 482564011, 1577707260, 361128716, 1032440545, 1431181194, 791167101, 846954114, 652822377, 1949752366, 1955697854, 1832648634, 1639720265, 883819359, 962012697, 1808264406, 9627135, 1373187898, 1612699313, 77570286, 2082891107, 2137944793, 1239251, 233292235, 132421072, 885874594, 1286284152, 687118143, 2142735741, 609180969, 161512679, 1433222687, 2017908457, 1517639107, 362188151, 1065668831, 1639978613, 279929256, 1134570610, 944717768, 531838731, 911981251, 688699670, 1335440088, 1071607804, 1927602970, 1887023541, 1334177590, 1360106984, 1513850837, 753621756, 824957520, 260655318, 1340558061, 1910069584, 236442771, 752988516, 87178610, 63454804, 1990804934, 928227096, 1730507896, 1314335879, 1279022340, 1383201236, 97108639, 951636747, 1035298388, 1734252648, 2114338878, 444670848, 2094569446, 855944770, 52882476, 614810639, 1015650541, 2135368256, 2133872426, 1537302403, 121361427, 727990438, 508144624, 1343231377, 522225565, 1295342123, 1616242131, 213478712, 916456733, 931660334, 753657871, 677071683, 419754702, 1924644358, 2078406583, 608931564, 2090076303, 118101879, 338426422, 397678235, 1983406719, 1094460480, 2055428737, 1403719372, 1662264113, 1884271824, 30398171, 1793985806, 1866907532, 1763146777, 187900228, 917281063, 2125852226, 996450942, 1871567999, 817292885, 305911019, 1663915494, 2129862591, 1286577839, 2028776637, 2091583730, 2087209709, 1638646442, 869251306, 241709899, 1747031448, 1511636664, 1711999127, 983598356, 1019765370, 687405323, 297737844, 257138559, 467599779, 998062456, 172439548, 1629062267, 715533125, 290286966, 417631819, 424218507, 1721965851, 1103325765, 1957071511, 259254706, 1537860726, 705326891, 524781644, 1707117195, 1807613669, 1624525273, 1851088584, 509737077, 332667776, 1824071405, 1408666800, 1064704490, 35808977, 1347680401, 680558317, 1292798449, 802777952, 1122917696, 740363591, 741671338, 1870016730, 942624937, 1390732956, 1551599879, 989783005, 149307564, 780551868, 1765392538, 621146211, 550535297, 1462431716, 2065413768, 1357125832, 1228936184, 737018326, 456906909, 416854905, 552905946, 1614932113, 1103672698, 742906171, 845405295, 889207986, 1146117865, 2143350293, 691772185, 204541799, 643194705, 2020904668, 1849321502, 1936768012, 1190548548, 199724377, 1470784387, 972224868, 790913078, 597771544, 285271059, 1980990581, 1992148297, 1710109392, 1803168639, 1188060928, 1580145475, 221534314, 1143011999, 2098150299, 1947906721, 1566939056, 1135339479, 1187991917, 960550597, 2071252371, 639007125, 1694658950, 1377091914, 1207244824, 1224353526, 1331419096, 134492280, 1222070497, 277577864, 1972425174, 1235530451, 892364372, 1038213930, 1257174184, 1473829326, 833871210, 301217552, 292371720, 129017245, 2142791190, 765156579, 1643196, 275487784, 399576143, 1746078469, 328583600, 1874337051, 1524903868, 352058610, 2113198767, 1664263450, 1909591035, 753825474, 118926782, 2120274450, 1187986319, 1717190346, 2074570773, 588192427, 1899249508, 803295075, 1548292027, 1278560985, 1397339391, 866951874, 1748178621, 410318738, 841581894, 546216710, 1210236938, 168180634, 1288173033, 406628433, 1803632622, 832188282, 87828332, 1101131533, 399235625, 763342479, 1426991571, 1835454544, 1898512300, 2102270782, 323580393, 1298486874, 1951354351, 1705178181, 66394412, 1811982139, 18278897, 842673453, 1090515544, 240500626, 1473990861, 1408654299, 2068126862, 371054448, 702240758, 460123462, 1336827681, 1778316122, 1336325903, 1885057859, 1531197438, 588071789, 335811945, 506477949, 1171269301, 1015550620, 321926426, 1788776320, 1010064936, 696723477, 2105963958, 743171572, 711239375, 1736023235, 2066516141, 1307270374, 1000266661, 1780827884, 1474220353, 1492478274, 314444722, 1583742457, 2014874146, 528496477, 1256843830, 1717442646, 321546919, 1842225327, 1796527983, 1211999600, 1376003499, 721980062, 1062562823, 1583089115, 1142995970, 1215340661, 1053626654, 2084021142, 952843415, 741636723, 706465519, 1646898278, 1248930852, 2016306176, 368712737, 894947422, 2106683020, 104665851, 974395308, 1489774208, 1755982808, 113164846, 1112422246, 1337686398, 871746252, 1059471587, 1456608554, 973364889, 1584315173, 230697360, 776119459, 1056282795, 1930652018, 2108658093, 1205975994, 898656576, 157243020, 906798246, 1843754906, 753111518, 2080631988, 1443150828, 291154012, 619046757, 1488669767, 2097325607, 1901727060, 1417902481, 758704672, 1113517958, 967363575, 1786671261, 2069854602, 520297782, 1303980903, 880075522, 1604402144, 971501040, 1795636893, 1273955678, 526872516, 1300615597, 429770546, 552416879, 338639352, 1901062773, 1439316682, 1646496062, 1582694876, 1648691285, 1464562974, 218664792, 905239428, 1839673967, 1597325476, 1832338743, 139082101, 270626603, 1459322844, 394273472, 648724477, 858561932, 54157625, 797143526, 1818604588, 629100957, 1618847659, 2129603948, 1360470130, 2128725514, 1579135429, 1838991815, 2083088599, 1258165450, 1274644880, 502229537, 376023249, 584452346, 363325163, 1327047546, 992859333, 1149959110, 2117971613, 1870008297, 423704861, 1245269632, 1341855737, 504763393, 1413189890, 435172306, 2108244780, 1610242127, 716213942, 459774480, 288139815, 1234802943, 1751732113, 790702247, 157120035, 1477348766, 1932973462, 1665032883, 920347605, 419810041, 1015300274, 1000677548, 1157857328, 2033492261, 1530995088, 774681407, 1544071122, 754489240, 1286070299, 1000415547, 672420620, 1977043317, 879349649, 1888424610, 904124561, 1007715301, 92940865, 1679956704, 1882124474, 1097902240, 910872289, 554185752, 1961288563, 1882158732, 1856059790, 1466457497, 1521117894, 235371132, 123196000, 1822912367, 1681978370, 1660193305, 1877429161, 1293243670, 1647348103, 676055774, 1138059723, 1976435018, 1680625457};
+ List list = new ArrayList<>(cap);
+ list.addAll(Arrays.asList(data));
+ return list;
}
}
@Test
- public void testPut() {
+ public void test() {
Assert.expectTrue(list.size() == 1000);
Assert.expectTrue(map.size() == 1000);
for (int i = 0; i < list.size(); i++) {
Integer k = list.get(i);
- Assert.expectTrue(map.get(k).equals(String.valueOf(k)));
+ Assert.expectTrue(map.get(k).equals(k));
}
- }
- @Test
- public void testScan() {
int i = 0;
for (map.scan(); map.hasNext(); ) {
i++;
- Integer k = map.nextKey();
- String v = map.value();
- Assert.expectTrue(v.equals(String.valueOf(k)));
+ Integer k = map.key();
+ Integer v = map.value();
+ Assert.expectTrue(k.equals(v));
Assert.expectTrue(list.contains(k));
}
Assert.expectTrue(i == list.size());
+
+ int size = list.size();
+ for (int j = 0; j < list.size(); j++) {
+ _test_remove(list.get(j));
+ }
+ Assert.expectTrue(map.size() == 0);
+ }
+
+ void _test_remove(Integer k) {
+ Object mv = map.remove(k);
+ Assert.expectTrue(mv != null);
}
@Test
- public void testRemove() {
- int i = 0;
- int size = list.size();
+ public void testBigMap() {
+ int count = 1024 * 1024;
+ IntMap map = new IntMap<>(count);
+ Map javaMap = new HashMap<>();
+ Random random = new Random();
+ for (int i = 0; i < count; i++) {
+ Integer v = random.nextInt(Integer.MAX_VALUE);
+ map.put(v, v);
+ javaMap.put(v, v);
+ }
+ int map_count = 0;
for (map.scan(); map.hasNext(); ) {
- i++;
- Integer k = map.nextKey();
- String v = map.value();
- Assert.expectTrue(v.equals(String.valueOf(k)));
- Assert.expectTrue(list.contains(k));
- if (k % 2 == 0) {
- map.remove(k);
- list.remove(k);
- }
+ map_count++;
}
- Assert.expectTrue(i == size);
- testScan();
+ logger.info("map_count: {}, javaMap_count: {}", map_count, javaMap.size());
+ Assert.expectTrue(map_count == javaMap.size());
}
+
}
diff --git a/firenio-test/src/main/java/test/others/TestIntMap1.java b/firenio-test/src/main/java/test/others/TestIntMap1.java
new file mode 100644
index 000000000..c01afcd09
--- /dev/null
+++ b/firenio-test/src/main/java/test/others/TestIntMap1.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.others;
+
+import io.netty.util.collection.IntObjectHashMap;
+
+import com.firenio.collection.IntMap;
+import com.firenio.log.LoggerFactory;
+
+/**
+ * @author: wangkai
+ **/
+public class TestIntMap1 {
+
+ public static void main(String[] args) {
+ LoggerFactory.setEnableSLF4JLogger(false);
+ // testNettyMap();
+ testMyMap();
+ }
+
+ static void testNettyMap() {
+
+ IntObjectHashMap map = new IntObjectHashMap(8);
+
+ map.put(7, "7");
+ map.put(15, "15");
+
+
+ System.out.println(map);
+
+ }
+
+ static void testMyMap() {
+ int test = 1005;
+ String debug = "remove 981";
+ IntMap map = new IntMap<>(256);
+ String string = "put 151\n" + "remove 152";
+ String[] actions = string.split("\n");
+ boolean mark = false;
+ for (int i = 0; i < actions.length; i++) {
+ String action = actions[i];
+ String[] ss = action.split(" ");
+ String sid = ss[1];
+ int id = Integer.parseInt(sid);
+ if (id == test) {
+ mark = true;
+ System.out.println(id);
+ }
+ if (action.equals(debug)) {
+ System.out.println(id);
+ }
+ if ("put".equals(ss[0])) {
+ map.put(id, sid);
+ } else {
+ map.remove(id);
+ }
+ System.out.println(action);
+ if (mark) {
+ if (map.get(test) == null) {
+ System.out.println(".........................");
+ return;
+ }
+ }
+ }
+ System.out.println(map.get(test));
+ }
+
+}
diff --git a/firenio-test/src/main/java/test/others/TestMask.java b/firenio-test/src/main/java/test/others/TestMask.java
index dce525c01..50ad4cdd4 100644
--- a/firenio-test/src/main/java/test/others/TestMask.java
+++ b/firenio-test/src/main/java/test/others/TestMask.java
@@ -26,16 +26,16 @@ public class TestMask {
public static void main(String[] args) {
ByteBuf buf = ByteBuf.wrap("hello word!".getBytes());
- byte mask = (byte) buf.remaining();
+ byte mask = (byte) buf.readableBytes();
mask(buf, mask);
- System.out.println(new String(buf.getBytes()));
- buf.position(0);
+ System.out.println(new String(buf.readBytes()));
+ buf.readIndex(0);
mask(buf, mask);
- System.out.println(new String(buf.getBytes()));
+ System.out.println(new String(buf.readBytes()));
}
public static void mask(ByteBuf src, byte m) {
- ByteBuffer buf = src.nioBuffer();
+ ByteBuffer buf = src.nioWriteBuffer();
int p = buf.position();
int l = buf.limit();
for (; p < l; p++) {
diff --git a/firenio-test/src/main/java/test/others/TestNettyByteBuf.java b/firenio-test/src/main/java/test/others/TestNettyByteBuf.java
new file mode 100644
index 000000000..bfbeb0bbc
--- /dev/null
+++ b/firenio-test/src/main/java/test/others/TestNettyByteBuf.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.others;
+
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufAllocator;
+
+import com.firenio.common.Util;
+
+/**
+ * @author: wangkai
+ **/
+public class TestNettyByteBuf {
+
+ static volatile ByteBuf buf;
+
+ public static void main(String[] args) {
+
+ ByteBufAllocator a = ByteBufAllocator.DEFAULT;
+
+ Util.exec(() ->{
+ buf = a.buffer(16);
+ });
+
+ Util.exec(() ->{
+ buf.release();
+ });
+
+ System.out.println(buf);
+
+
+ }
+
+
+}
diff --git a/firenio-test/src/main/java/test/others/TestShutdown.java b/firenio-test/src/main/java/test/others/TestShutdown.java
new file mode 100644
index 000000000..7ca71156d
--- /dev/null
+++ b/firenio-test/src/main/java/test/others/TestShutdown.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.others;
+
+import java.nio.ByteBuffer;
+
+import com.firenio.common.Unsafe;
+import com.firenio.log.Logger;
+import com.firenio.log.LoggerFactory;
+
+/**
+ * @author: wangkai
+ **/
+public class TestShutdown {
+
+
+ public static void main(String[] args) {
+ LoggerFactory.setEnableSLF4JLogger(false);
+
+ Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+ System.out.println("shutdown....");
+ }));
+ System.out.println("start..");
+ long address = Unsafe.allocate(1);
+ Unsafe.free(address);
+
+ Unsafe.putInt(address,100);
+ System.out.println("put address success..");
+
+ ByteBuffer buf = ByteBuffer.allocateDirect(100);
+ Unsafe.freeByteBuffer(buf);
+ buf.putLong(100);
+ System.out.println("put buffer success..");
+
+ Unsafe.putInt(-1,100);
+ System.out.println("put address -1 success..");
+
+ Unsafe.putInt(0,100);
+ System.out.println("put address 0 success..");
+
+ System.out.println("end....");
+
+ }
+
+
+
+
+}
diff --git a/firenio-test/src/main/java/test/others/TestScsp.java b/firenio-test/src/main/java/test/others/TestVolatile.java
similarity index 54%
rename from firenio-test/src/main/java/test/others/TestScsp.java
rename to firenio-test/src/main/java/test/others/TestVolatile.java
index 476309ac0..e73998862 100644
--- a/firenio-test/src/main/java/test/others/TestScsp.java
+++ b/firenio-test/src/main/java/test/others/TestVolatile.java
@@ -15,31 +15,23 @@
*/
package test.others;
-import com.firenio.common.Util;
-import com.firenio.concurrent.ScmpLinkedQueue;
-
/**
- * @author wangkai
- */
-public class TestScsp {
-
- public static void main(String[] args) throws Exception {
-
- ScmpLinkedQueue queue = new ScmpLinkedQueue<>();
+ * @author: wangkai
+ **/
+public class TestVolatile {
- for (int i = 0; i < 4; i++) {
- Util.exec(() -> {
- for (int j = 0; j < 32; j++) {
- queue.offer(String.valueOf(j));
- }
- });
- }
+ static boolean running = true;
- // Util.sleep(100);
- System.out.println("size:" + queue.size());
- for (; queue.size() > 0; ) {
- System.out.println(queue.poll());
- }
+ public static void main(String[] args) throws Exception {
+ new Thread(() -> {
+ for (; running; ) {
+ //Thread.yield();
+ }
+ System.out.println("worker stop");
+ }).start();
+ Thread.sleep(500);
+ running = false;
+ System.out.println("set running false");
}
}
diff --git a/firenio-test/src/main/java/test/others/TestVolatile2.java b/firenio-test/src/main/java/test/others/TestVolatile2.java
new file mode 100644
index 000000000..2d93c35f3
--- /dev/null
+++ b/firenio-test/src/main/java/test/others/TestVolatile2.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.others;
+
+/**
+ * @author: wangkai
+ **/
+public class TestVolatile2 {
+
+ static boolean running = true;
+ static volatile int mem_bar = 0;
+
+ public static void main(String[] args) throws Exception {
+ new Thread(() -> {
+ int temp = 0;
+ for (; running; ) {
+ temp = mem_bar;
+ }
+ System.out.println("worker stop");
+ }).start();
+ Thread.sleep(500);
+ running = false;
+ System.out.println("set running false");
+ }
+
+}
diff --git a/firenio-test/src/main/java/test/others/algorithm/BubbleSort.java b/firenio-test/src/main/java/test/others/algorithm/BubbleSort.java
index 9e0371a3f..f3e1b02b5 100644
--- a/firenio-test/src/main/java/test/others/algorithm/BubbleSort.java
+++ b/firenio-test/src/main/java/test/others/algorithm/BubbleSort.java
@@ -25,16 +25,10 @@
public class BubbleSort {
public static void main(String[] args) {
-
- int[] array = new int[30];
- for (int i = 0; i < array.length; i++) {
- array[i] = new Random().nextInt(30);
- }
-
- Util.printArray(array);
+ int[] array = TestSort.random_array();
+ System.out.println(Util.arrayToString(array));
sort(array);
- Util.printArray(array);
-
+ System.out.println(Util.arrayToString(array));
}
public static void sort(int[] array) {
diff --git a/firenio-test/src/main/java/test/others/algorithm/ByteArray.java b/firenio-test/src/main/java/test/others/algorithm/ByteArray.java
deleted file mode 100644
index a85ba9f55..000000000
--- a/firenio-test/src/main/java/test/others/algorithm/ByteArray.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright 2015 The FireNio Project
- *
- * 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 test.others.algorithm;
-
-/**
- * @author wangkai
- */
-public class ByteArray {
-
- private byte[] data;
-
- private int length;
-
- private int off;
-
- public ByteArray() {}
-
- public ByteArray(byte[] data, int off, int length) {
- this.data = data;
- this.off = off;
- this.length = length;
- }
-
- private static boolean greater(ByteArray b1, ByteArray b2) {
- int len = b1.getLength();
- for (int i = 0; i < len; i++) {
- byte b11 = b1.getByte(i);
- byte b22 = b2.getByte(i);
- if (b11 != b22) {
- return b11 > b22;
- }
- }
- return false;
- }
-
- private static boolean greaterOrEquals(ByteArray b1, ByteArray b2) {
- int len = b1.getLength();
- for (int i = 0; i < len; i++) {
- byte b11 = b1.getByte(i);
- byte b22 = b2.getByte(i);
- if (b11 != b22) {
- return b11 > b22;
- }
- }
- return true;
- }
-
- private static boolean lessOrEquals(ByteArray b1, ByteArray b2) {
- int len = b1.getLength();
- for (int i = 0; i < len; i++) {
- byte b11 = b1.getByte(i);
- byte b22 = b2.getByte(i);
- if (b11 != b22) {
- return b11 < b22;
- }
- }
- return true;
- }
-
- public byte getByte(int pos) {
- return data[ix(pos)];
- }
-
- public byte[] getData() {
- return data;
- }
-
- public int getLength() {
- return length;
- }
-
- public int getOff() {
- return off;
- }
-
- public boolean greater(ByteArray o) {
- if (getLength() > o.getLength()) {
- return true;
- }
- if (getLength() < o.getLength()) {
- return false;
- }
- return greater(this, o);
- }
-
- public boolean greaterOrEquals(ByteArray o) {
- if (getLength() > o.getLength()) {
- return true;
- }
- if (getLength() < o.getLength()) {
- return false;
- }
- return greaterOrEquals(this, o);
- }
-
- private int ix(int pos) {
- return off + pos;
- }
-
- public boolean lessOrEquals(ByteArray o) {
- if (getLength() > o.getLength()) {
- return false;
- }
- if (getLength() < o.getLength()) {
- return true;
- }
- return lessOrEquals(this, o);
- }
-
- public void setData(byte[] data) {
- this.data = data;
- }
-
- public void setLength(int length) {
- this.length = length;
- }
-
- public void setOff(int off) {
- this.off = off;
- }
-
- public String toString1() {
- return new String(data, off, length);
- }
-}
diff --git a/firenio-test/src/main/java/test/others/algorithm/InsertSort.java b/firenio-test/src/main/java/test/others/algorithm/InsertSort.java
new file mode 100644
index 000000000..159fc68c0
--- /dev/null
+++ b/firenio-test/src/main/java/test/others/algorithm/InsertSort.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.others.algorithm;
+
+/**
+ * @author: wangkai
+ **/
+public class InsertSort {
+
+ public static void main(String[] args) {
+ TestSort.test(InsertSort::sort, 10);
+ // TestSort.test_load(InsertSort::sort, 1024 * 32, 16);
+ TestSort.test_load(InsertSort::sort, 16, 1024 * 1024 * 8);
+ }
+
+ public static void sort(int[] array, int off, int end) {
+ if (end - off < 2) {
+ return;
+ }
+ int s0 = array[off + 0];
+ int s1 = array[off + 1];
+ if (s1 < s0) {
+ array[off + 0] = s1;
+ array[off + 1] = s0;
+ }
+ direct_sort(array, off, end);
+ }
+
+ public static void sort(int[] array) {
+ sort(array, 0, array.length);
+ }
+
+ static void move_des(int[] array, int j, int i) {
+ for (int k = i; k > j; k--) {
+ array[k] = array[k - 1];
+ }
+ }
+
+ static void direct_sort(int[] array, int off, int end) {
+ for (int i = off + 2; i < end; i++) {
+ int temp = array[i];
+ int mid_idx = (i + off) >>> 1;
+ int j = temp < array[mid_idx] ? off : mid_idx;
+ for (; j < i; j++) {
+ if (temp < array[j]) {
+ move_des(array, j, i);
+ array[j] = temp;
+ break;
+ }
+ }
+ }
+ }
+
+ static void half_sort(int[] array, int off, int end) {
+ for (int i = off + 2; i < end; i++) {
+ int temp = array[i];
+ int j = half_find(array, off, i, temp);
+ if (j < i) {
+ move_des(array, j, i);
+ array[j] = temp;
+ }
+ }
+ }
+
+ static int half_find(int[] array, int low, int high, int value) {
+ int mid = high >>> 1;
+ for (; ; ) {
+ int temp = array[mid];
+ if (value > temp) {
+ low = mid;
+ } else if (temp == value) {
+ return mid;
+ } else {
+ high = mid;
+ }
+ if (high - low == 1) {
+ if (value < array[low]) {
+ return low;
+ } else {
+ return high;
+ }
+ }
+ mid = (low + high) >>> 1;
+ }
+ }
+
+ static void move_aes(int[] array, int j, int i) {
+ int t1 = array[j];
+ int t2 = array[j + 1];
+ for (int k = j + 1; k < i; k++) {
+ t2 = array[k];
+ array[k] = t1;
+ t1 = t2;
+ }
+ array[i] = t1;
+ }
+
+}
diff --git a/firenio-test/src/main/java/test/others/algorithm/KMPUtil.java b/firenio-test/src/main/java/test/others/algorithm/KMPUtil.java
deleted file mode 100644
index 36cab87a3..000000000
--- a/firenio-test/src/main/java/test/others/algorithm/KMPUtil.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright 2015 The FireNio Project
- *
- * 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 test.others.algorithm;
-
-import com.firenio.collection.IntArray;
-import com.firenio.common.Util;
-
-//关键字:前缀,后缀,部分匹配表
-public class KMPUtil {
-
- private char[] match_array;
-
- private int[] match_table;
-
- private String match_value;
-
- public KMPUtil(String value) {
- this.initialize(value);
- }
-
- public static void main(String[] args) {
-
- String s1 = "1111111111111111111211111111112111121111211111111";
-
- String match = "1112";
-
- KMPUtil kmp = new KMPUtil(match);
-
- System.out.println(kmp.match_all(s1));
-
- }
-
- private void initialize(String value) {
- if (Util.isNullOrBlank(value)) {
- throw new IllegalArgumentException("null value");
- }
- this.match_value = value;
- this.match_array = match_value.toCharArray();
- this.match_table = new int[match_value.length()];
- this.initialize_part_match_table();
- }
-
- private void initialize_part_match_table() {
- int length = this.match_value.length();
- // 直接从两位开始比较
- for (int i = 2; i < length; i++) {
- match_table[i] = initialize_part_match_table0(match_array, i);
- }
- }
-
- private int initialize_part_match_table0(char[] array, int length) {
- int e = 0;
- WORD:
- for (int i = 1; i < length; i++) {
- int t = 0;
- int p = 0;
- int s = length - i;
- for (int j = 0; j < i; j++) {
- if (array[p++] != array[s++]) {
- continue WORD;
- }
- t++;
- }
- e = t;
- }
- return e;
- }
-
- public int match(String value) {
- return match(value, 0);
- }
-
- public int match(String value, int begin) {
- if (Util.isNullOrBlank(value) || begin < 0) {
- return -1;
- }
- if (value.length() - begin < this.match_array.length) {
- return -1;
- }
- int source_length = value.length();
- int index = begin;
- int match_length = this.match_array.length;
- char[] match_array = this.match_array;
- int[] match_table = this.match_table;
- LOOP:
- for (; index < source_length; ) {
- for (int i = 0; i < match_length; i++) {
- if (value.charAt(index + i) != match_array[i]) {
- if (i == 0) {
- index++;
- } else {
- index += (i - match_table[i]);
- }
- continue LOOP;
- }
- }
- return index;
- }
- return -1;
- }
-
- public IntArray match_all(String value) {
- if (Util.isNullOrBlank(value)) {
- return null;
- }
- if (value.length() < match_value.length()) {
- return null;
- }
- IntArray matchs = new IntArray();
- if (value.equals(match_value)) {
- matchs.add(0);
- return matchs;
- }
- int source_length = value.length();
- int index = 0;
- int match_length = this.match_array.length;
- char[] match_array = this.match_array;
- int[] match_table = this.match_table;
- LOOP:
- for (; index < source_length; ) {
- if (source_length - index < match_length) {
- break;
- }
- for (int i = 0; i < match_length; i++) {
- if (value.charAt(index + i) != match_array[i]) {
- if (i == 0) {
- index++;
- } else {
- index += (i - match_table[i]);
- }
- continue LOOP;
- }
- }
- matchs.add(index);
- index += match_length;
- }
- return matchs;
- }
-}
diff --git a/firenio-test/src/main/java/test/others/algorithm/Lz4CompressedInputStream.java b/firenio-test/src/main/java/test/others/algorithm/Lz4CompressedInputStream.java
index 083b3f04d..4ca5434f1 100644
--- a/firenio-test/src/main/java/test/others/algorithm/Lz4CompressedInputStream.java
+++ b/firenio-test/src/main/java/test/others/algorithm/Lz4CompressedInputStream.java
@@ -20,7 +20,7 @@ public class Lz4CompressedInputStream extends InputStream {
public Lz4CompressedInputStream(InputStream inputStream, int bufSize) {
this.inputStream = inputStream;
this.buf = ByteBuf.heap(bufSize);
- this.buf.limit(0);
+ this.buf.writeIndex(0);
}
public static int read(ByteBuf dst, InputStream src) throws IOException {
@@ -29,23 +29,23 @@ public static int read(ByteBuf dst, InputStream src) throws IOException {
public static int read(ByteBuf dst, InputStream src, long limit) throws IOException {
byte[] array = dst.array();
- if (!dst.hasRemaining()) {
+ if (!dst.hasReadableBytes()) {
int read = (int) Math.min(limit, dst.capacity());
int len = src.read(array, 0, read);
if (len > 0) {
- dst.position(0);
- dst.limit(len);
+ dst.readIndex(0);
+ dst.writeIndex(len);
}
return len;
}
- int remaining = dst.remaining();
- System.arraycopy(array, dst.position(), array, 0, remaining);
- dst.position(0);
- dst.limit(remaining);
+ int remaining = dst.readableBytes();
+ System.arraycopy(array, dst.readIndex(), array, 0, remaining);
+ dst.readIndex(0);
+ dst.writeIndex(remaining);
int read = (int) Math.min(limit, dst.capacity() - remaining);
int len = src.read(array, remaining, read);
if (len > 0) {
- dst.limit(remaining + len);
+ dst.writeIndex(remaining + len);
}
return len;
}
@@ -69,9 +69,9 @@ public int read(byte[] b) throws IOException {
public int read(byte[] b, int off, int len) throws IOException {
ByteBuf buf = this.buf;
byte[] readBuffer = buf.array();
- int limit = buf.limit();
- int offset = buf.position();
- if (buf.remaining() <= 4) {
+ int limit = buf.writeIndex();
+ int offset = buf.readIndex();
+ if (buf.readableBytes() <= 4) {
if (!hasRemaining) {
return -1;
}
@@ -87,7 +87,7 @@ public int read(byte[] b, int off, int len) throws IOException {
read(buf);
return read(b, off, len);
}
- buf.position(offset + _len);
+ buf.readIndex(offset + _len);
return Lz4RawDecompressor.decompress(readBuffer, offset, _len, b, off, len);
}
diff --git a/firenio-test/src/main/java/test/others/algorithm/Lz4RawCompressor.java b/firenio-test/src/main/java/test/others/algorithm/Lz4RawCompressor.java
index 0b49ed5c4..fba726511 100644
--- a/firenio-test/src/main/java/test/others/algorithm/Lz4RawCompressor.java
+++ b/firenio-test/src/main/java/test/others/algorithm/Lz4RawCompressor.java
@@ -77,7 +77,7 @@ public static int compress(final Object inputBase, final long inputAddress, fina
long anchor = input;
// First Byte
- // put position in hash
+ // put readIndex in hash
table[hash(Unsafe.getLong(inputBase, input), mask)] = (int) (input - inputAddress);
input++;
@@ -102,11 +102,11 @@ public static int compress(final Object inputBase, final long inputAddress, fina
return (int) (emitLastLiteral(outputBase, output, inputBase, anchor, inputLimit - anchor) - outputAddress);
}
- // get position on hash
+ // get readIndex on hash
matchIndex = inputAddress + table[hash];
nextHash = hash(Unsafe.getLong(inputBase, nextInputIndex), mask);
- // put position on hash
+ // put readIndex on hash
table[hash] = (int) (input - inputAddress);
} while (Unsafe.getInt(inputBase, matchIndex) != Unsafe.getInt(inputBase, input) || matchIndex + MAX_DISTANCE < input);
@@ -140,7 +140,7 @@ public static int compress(final Object inputBase, final long inputAddress, fina
long position = input - 2;
table[hash(Unsafe.getLong(inputBase, position), mask)] = (int) (position - inputAddress);
- // Test next position
+ // Test next readIndex
int hash = hash(Unsafe.getLong(inputBase, input), mask);
matchIndex = inputAddress + table[hash];
table[hash] = (int) (input - inputAddress);
diff --git a/firenio-test/src/main/java/test/others/algorithm/QuickSort.java b/firenio-test/src/main/java/test/others/algorithm/QuickSort.java
index 1bf8400d8..8e2cb928d 100644
--- a/firenio-test/src/main/java/test/others/algorithm/QuickSort.java
+++ b/firenio-test/src/main/java/test/others/algorithm/QuickSort.java
@@ -18,6 +18,7 @@
import java.util.Random;
import com.firenio.common.Util;
+import com.firenio.log.LoggerFactory;
/**
* @author wangkai
@@ -26,19 +27,13 @@ public class QuickSort {
public static void main(String[] args) {
- int[] array = new int[30];
- for (int i = 0; i < array.length; i++) {
- array[i] = new Random().nextInt(30);
- }
-
- Util.printArray(array);
- sort(array, 0, 29);
- Util.printArray(array);
+ TestSort.test(QuickSort::sort, 10);
+ TestSort.test_load(QuickSort::sort, 1024 * 32, 1024);
+// TestSort.test_load(QuickSort::sort, 16, 1024 * 1024 * 8);
}
private static int partition(int[] array, int low, int high) {
- //三数取中
int mid = low + (high - low) / 2;
if (array[mid] > array[high]) {
swap(array, mid, high);
@@ -49,6 +44,7 @@ private static int partition(int[] array, int low, int high) {
if (array[mid] > array[low]) {
swap(array, mid, low);
}
+
int key = array[low];
while (low < high) {
@@ -65,6 +61,10 @@ private static int partition(int[] array, int low, int high) {
return high;
}
+ public static void sort(int[] array) {
+ sort(array, 0, array.length - 1);
+ }
+
public static void sort(int[] array, int low, int high) {
if (low >= high) {
return;
diff --git a/firenio-test/src/main/java/test/others/algorithm/QuickSort1.java b/firenio-test/src/main/java/test/others/algorithm/QuickSort1.java
new file mode 100644
index 000000000..3044872b9
--- /dev/null
+++ b/firenio-test/src/main/java/test/others/algorithm/QuickSort1.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.others.algorithm;
+
+/**
+ * @author wangkai
+ */
+public class QuickSort1 {
+
+ public static void main(String[] args) {
+
+ TestSort.test(QuickSort1::sort, new int[]{9, 17, 19, 8, 3, 15, 17, 14, 14, 5});
+ // TestSort.test(QuickSort1::sort, new int[]{4, 3, 5});
+ TestSort.test_load(QuickSort1::sort, 1024 * 32, 1024);
+
+ }
+
+ private static int p_sort(int[] array, int low, int high) {
+ int mid = low + (high - low) / 2;
+ int key = (array[low] + array[mid] + array[high]) / 3;
+ for (; low < high; ) {
+ while (array[high] >= key && high > low) {
+ high--;
+ }
+ while (array[low] <= key && high > low) {
+ low++;
+ }
+ if (low < high) {
+ swap(array, low, high);
+ } else {
+ break;
+ }
+ }
+ return high;
+ }
+
+ public static void sort(int[] array) {
+ sort(array, 0, array.length);
+ }
+
+ public static void sort(int[] array, int low, int high) {
+ if (high - low < 8) {
+ InsertSort.sort(array, low, high);
+ } else {
+ int index = p_sort(array, low, high - 1) + 1;
+ sort(array, low, index);
+ sort(array, index, high);
+ }
+ }
+
+ private static void swap(int[] array, int a, int b) {
+ int temp = array[a];
+ array[a] = array[b];
+ array[b] = temp;
+ }
+
+}
diff --git a/firenio-test/src/main/java/test/others/algorithm/QuickSort2.java b/firenio-test/src/main/java/test/others/algorithm/QuickSort2.java
index 87c3713f7..2723b5742 100644
--- a/firenio-test/src/main/java/test/others/algorithm/QuickSort2.java
+++ b/firenio-test/src/main/java/test/others/algorithm/QuickSort2.java
@@ -20,50 +20,58 @@
*/
public class QuickSort2 {
- private static int partition(ByteArray[] array, int low, int high) {
- //三数取中
+ public static void main(String[] args) {
+
+ TestSort.test(QuickSort2::sort, 16);
+ TestSort.test_load(QuickSort2::sort, 1024 * 32, 1024);
+ }
+
+ private static int partition(int[] array, int low, int high) {
int mid = low + (high - low) / 2;
- if (array[mid].greater(array[high])) {
- swap(array[mid], array[high]);
+ if (array[mid] > array[high]) {
+ swap(array, mid, high);
}
- if (array[low].greater(array[high])) {
- swap(array[low], array[high]);
+ if (array[low] > array[high]) {
+ swap(array, low, high);
}
- if (array[mid].greater(array[low])) {
- swap(array[mid], array[low]);
+ if (array[mid] > array[low]) {
+ swap(array, mid, low);
}
- ByteArray key = array[low];
+
+ int key = array[low];
while (low < high) {
- while (array[high].greaterOrEquals(key) && high > low) {
+ while (array[high] >= key && high > low) {
high--;
}
array[low] = array[high];
- while (array[low].lessOrEquals(key) && high > low) {
+ while (array[low] <= key && high > low) {
low++;
}
array[high] = array[low];
}
- array[low] = key;//这里low
+ array[low] = key;
return high;
}
- public static void sort(ByteArray[] array, int low, int high) {
- if (low >= high) {
- return;
+ public static void sort(int[] array) {
+ sort(array, 0, array.length - 1);
+ }
+
+ public static void sort(int[] array, int low, int high) {
+ if (high - low < 8) {
+ InsertSort.sort(array, low, high + 1);
+ } else {
+ int index = partition(array, low, high);
+ sort(array, low, index - 1);
+ sort(array, index + 1, high);
}
- int index = partition(array, low, high);
- sort(array, low, index - 1);
- sort(array, index + 1, high);
}
- private static void swap(ByteArray a, ByteArray b) {
- int tmpOff = a.getOff();
- int tmpLen = a.getLength();
- a.setLength(b.getLength());
- a.setOff(b.getOff());
- b.setLength(tmpLen);
- b.setOff(tmpOff);
+ private static void swap(int[] array, int a, int b) {
+ int temp = array[a];
+ array[a] = array[b];
+ array[b] = temp;
}
}
diff --git a/firenio-test/src/main/java/test/others/algorithm/RSAUtil.java b/firenio-test/src/main/java/test/others/algorithm/RSAUtil.java
deleted file mode 100644
index 1809a73ea..000000000
--- a/firenio-test/src/main/java/test/others/algorithm/RSAUtil.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright 2015 The FireNio Project
- *
- * 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 test.others.algorithm;
-
-import java.io.File;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.RSAPrivateKeySpec;
-import java.security.spec.RSAPublicKeySpec;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.crypto.Cipher;
-
-import com.firenio.common.FileUtil;
-import com.firenio.common.Util;
-
-public class RSAUtil {
-
- private static KeyFactory keyFactory;
-
- static {
- try {
- keyFactory = KeyFactory.getInstance("RSA");
- } catch (NoSuchAlgorithmException e) {
- }
- }
-
- /**
- * 私钥解密
- *
- * @param bytes
- * @param privateKey
- * @return
- * @throws Exception
- */
- public static byte[] decryptByPrivateKey(byte[] bytes, RSAPrivateKey privateKey) throws Exception {
- Cipher cipher = Cipher.getInstance("RSA");
- cipher.init(Cipher.DECRYPT_MODE, privateKey);
- // 模长
- int key_len = privateKey.getModulus().bitLength() / 8;
- // 如果密文长度大于模长则要分组解密
- List arrays = splitArray(bytes, key_len);
- ByteBuffer buffer = ByteBuffer.allocate(arrays.size() * (key_len - 11));
- for (byte[] arr : arrays) {
- byte[] marr = cipher.doFinal(arr);
- buffer.put(marr);
- }
- byte[] r = new byte[buffer.position()];
- buffer.flip();
- buffer.get(r);
- return r;
- }
-
- /**
- * 公钥加密
- *
- * @param data
- * @param publicKey
- * @return
- * @throws Exception
- */
- public static byte[] encryptByPublicKey(byte[] data, RSAPublicKey publicKey) throws Exception {
- Cipher cipher = Cipher.getInstance("RSA");
- cipher.init(Cipher.ENCRYPT_MODE, publicKey);
- // 模长
- int key_len = publicKey.getModulus().bitLength() / 8;
- // 加密数据长度 <= 模长-11
- List datas = splitArray(data, key_len - 11);
- ByteBuffer buffer = ByteBuffer.allocate(key_len * datas.size());
- // 如果明文长度大于模长-11则要分组加密
- for (byte[] s : datas) {
- byte[] array = cipher.doFinal(s);
- buffer.put(array);
- }
- return buffer.array();
- }
-
- public static void generateKeys(String file, int length) throws NoSuchAlgorithmException, IOException {
- RSAKeys keys = RSAUtil.getKeys(length);
- // 生成公钥和私钥
- RSAPublicKey publicKey = keys.getPublicKey();
- RSAPrivateKey privateKey = keys.getPrivateKey();
- File publicKeyFile = new File(file + "/public.rsa");
- String publicKeyString = publicKey.toString();
- File privateKeyFile = new File(file + "/private.rsa");
- String privateKeyString = privateKey.toString();
- FileUtil.writeByFile(publicKeyFile, publicKeyString);
- FileUtil.writeByFile(privateKeyFile, privateKeyString);
- System.out.println("Public RSA File:" + publicKeyFile.getCanonicalPath());
- System.out.println(publicKeyString);
- System.out.println();
- System.out.println("Private RSA File:" + privateKeyFile.getCanonicalPath());
- System.out.println(privateKeyString);
- }
-
- /**
- * 生成公钥和私钥
- *
- * @param length 1024 ...
- * @throws NoSuchAlgorithmException
- */
- public static RSAKeys getKeys(int length) throws NoSuchAlgorithmException {
- KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
- keyPairGen.initialize(length);
- KeyPair keyPair = keyPairGen.generateKeyPair();
- RSAKeys keys = new RSAKeys();
- keys.publicKey = (RSAPublicKey) keyPair.getPublic();
- keys.privateKey = (RSAPrivateKey) keyPair.getPrivate();
- return keys;
- }
-
- /**
- * 使用模和指数生成RSA私钥
- * 注意:【此代码用了默认补位方式,为RSA/None/PKCS1Padding,不同JDK默认的补位方式可能不同,如Android默认是RSA
- * /None/NoPadding】
- *
- * @param modulus 模
- * @param exponent 指数
- * @return
- */
- public static RSAPrivateKey getPrivateKey(String modulus, String exponent) {
- try {
- BigInteger b1 = new BigInteger(modulus);
- BigInteger b2 = new BigInteger(exponent);
- RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(b1, b2);
- return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
- } catch (Exception e) {
- throw new RuntimeException(e.getMessage(), e);
- }
- }
-
- /**
- * 使用模和指数生成RSA公钥
- * 注意:【此代码用了默认补位方式,为RSA/None/PKCS1Padding,不同JDK默认的补位方式可能不同,如Android默认是RSA
- * /None/NoPadding】
- *
- * @param modulus 模
- * @param exponent 指数
- * @return
- */
- public static RSAPublicKey getPublicKey(String modulus, String exponent) {
- try {
- BigInteger b1 = new BigInteger(modulus);
- BigInteger b2 = new BigInteger(exponent);
- KeyFactory keyFactory = KeyFactory.getInstance("RSA");
- RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2);
- return (RSAPublicKey) keyFactory.generatePublic(keySpec);
- } catch (Exception e) {
- throw new RuntimeException(e.getMessage(), e);
- }
- }
-
- public static RSAPrivateKey getRsaPrivateKey(String content) {
- if (Util.isNullOrBlank(content)) {
- throw new IllegalArgumentException("null content");
- }
- Map map = parseRSAFromContent(content);
- String modulus = map.get("modulus");
- String exponent = map.get("private exponent");
- return getPrivateKey(modulus, exponent);
- }
-
- public static RSAPublicKey getRsaPublicKey(String content) {
- if (Util.isNullOrBlank(content)) {
- throw new IllegalArgumentException("null content");
- }
- Map map = parseRSAFromContent(content);
- String modulus = map.get("modulus");
- String exponent = map.get("public exponent");
- return getPublicKey(modulus, exponent);
- }
-
- public static void main(String[] args) throws Exception {
- RSAKeys keys = RSAUtil.getKeys(1024);
- // 生成公钥和私钥
- RSAPublicKey publicKey = keys.getPublicKey();
- RSAPrivateKey privateKey = keys.getPrivateKey();
- // 模
- String modulus = publicKey.getModulus().toString();
- // 公钥指数
- String public_exponent = publicKey.getPublicExponent().toString();
- // 私钥指数
- String private_exponent = privateKey.getPrivateExponent().toString();
- // 明文
- String ming = "你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好";
- // ming = "22ttt2aasdaaaaaasdasddw";
- // 使用模和指数生成公钥和私钥
- RSAPublicKey pubKey = RSAUtil.getPublicKey(modulus, public_exponent);
- RSAPrivateKey priKey = RSAUtil.getPrivateKey(modulus, private_exponent);
- // 加密后的密文
- byte[] mi = RSAUtil.encryptByPublicKey(ming.getBytes(Util.GBK), pubKey);
- System.out.println("mi.length:" + mi.length);
- // 解密后的明文
- ming = new String(RSAUtil.decryptByPrivateKey(mi, priKey), Util.GBK);
- System.err.println("明文:" + ming);
- }
-
- private static Map parseRSAFromContent(String content) {
- String[] lines = content.split("\n");
- Map map = new HashMap<>();
- for (int i = 1; i < lines.length; i++) {
- String[] array = lines[i].split(":");
- if (array.length != 2) {
- continue;
- }
- String name = array[0].trim().replace("\r", "");
- String value = array[1].trim().replace("\r", "");
- map.put(name, value);
- }
- return map;
- }
-
- /**
- * 拆分字符串
- */
- private static List splitArray(byte[] array, int len) {
- int length = array.length;
- List list = new ArrayList<>();
- if (length <= len) {
- list.add(array);
- return list;
- }
- int size = length / len;
- for (int i = 0; i < size; i++) {
- byte[] a = new byte[len];
- System.arraycopy(array, i * len, a, 0, len);
- list.add(a);
- }
- int yu = array.length % len;
- if (yu > 0) {
- byte[] a = new byte[yu];
- System.arraycopy(array, length - yu, a, 0, yu);
- list.add(a);
- }
- return list;
- }
-
- public static class RSAKeys {
- private RSAPrivateKey privateKey;
- private RSAPublicKey publicKey;
-
- public RSAPrivateKey getPrivateKey() {
- return privateKey;
- }
-
- public RSAPublicKey getPublicKey() {
- return publicKey;
- }
-
- public void setPrivateKey(RSAPrivateKey privateKey) {
- this.privateKey = privateKey;
- }
-
- public void setPublicKey(RSAPublicKey publicKey) {
- this.publicKey = publicKey;
- }
- }
-}
diff --git a/firenio-test/src/main/java/test/others/algorithm/TestSort.java b/firenio-test/src/main/java/test/others/algorithm/TestSort.java
new file mode 100644
index 000000000..3bf257bfc
--- /dev/null
+++ b/firenio-test/src/main/java/test/others/algorithm/TestSort.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.others.algorithm;
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+import java.util.Random;
+
+import com.firenio.common.Assert;
+import com.firenio.common.Util;
+import com.firenio.log.DebugUtil;
+import com.firenio.log.LoggerFactory;
+
+/**
+ * @author: wangkai
+ **/
+public class TestSort {
+
+ static {
+ LoggerFactory.setEnableSLF4JLogger(false);
+ }
+
+ public static int[] random_array() {
+ return random_array(10);
+ }
+
+ public static int[] random_array(int count) {
+ Random random = new Random();
+ int[] array = new int[count];
+ for (int i = 0; i < count; i++) {
+ array[i] = random.nextInt(count << 1);
+ }
+ return array;
+ }
+
+ interface TestISort {
+
+ void sort(int[] array);
+
+ }
+
+ public static void test(TestISort sort, int count) {
+ test(sort, TestSort.random_array(count));
+ }
+
+ public static void test(TestISort sort, int[] array) {
+ System.out.println(Util.arrayToString(array));
+ int[] copy = Arrays.copyOf(array, array.length);
+ sort.sort(array);
+ Arrays.sort(copy);
+ Assert.expectTrue(array_equals(array, copy));
+ System.out.println(Util.arrayToString(array));
+ }
+
+ public static void test_load(TestISort sort, int count, int time) {
+ int[] array = random_array(count);
+ int[][] sorts = new int[time][];
+ for (int i = 0; i < time; i++) {
+ sorts[i] = Arrays.copyOf(array, array.length);
+ }
+ long start = System.nanoTime();
+ for (int i = 0; i < time; i++) {
+ sort.sort(sorts[i]);
+ }
+ long past = System.nanoTime() - start;
+ DebugUtil.info("sort cost: " + (past / 1000_1000));
+ }
+
+ public static boolean array_equals(int[] array1, int[] array2) {
+ if (array1.length != array2.length) {
+ return false;
+ }
+ for (int i = 0; i < array1.length; i++) {
+ if (array1[i] != array2[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/firenio-test/src/main/java/test/others/algorithm/ZeroOnePackage.java b/firenio-test/src/main/java/test/others/algorithm/ZeroOnePackage.java
index 12b57175c..65756de2a 100644
--- a/firenio-test/src/main/java/test/others/algorithm/ZeroOnePackage.java
+++ b/firenio-test/src/main/java/test/others/algorithm/ZeroOnePackage.java
@@ -87,7 +87,7 @@ public static int knapsack(int[] val, int[] wt, int W, int[][] V, boolean print)
if (wt[item - 1] <= weight) {
// Given a weight, check if the value of the current
// item + value of the item that we could afford
- // with the remaining weight is greater than the value
+ // with the readableBytes weight is greater than the value
// without the current item itself
V[item][weight] = Math.max(val[item - 1] + V[item - 1][weight - wt[item - 1]], V[item - 1][weight]);
} else {
diff --git a/firenio-test/src/main/java/test/others/netty/EchoServer.java b/firenio-test/src/main/java/test/others/netty/EchoServer.java
index 423082c24..10ce94669 100644
--- a/firenio-test/src/main/java/test/others/netty/EchoServer.java
+++ b/firenio-test/src/main/java/test/others/netty/EchoServer.java
@@ -35,39 +35,27 @@
*/
public class EchoServer {
- static final int PORT = Integer.parseInt(System.getProperty("port", "443"));
- static final boolean SSL = System.getProperty("ssl") == null;
public static void main(String[] args) throws Exception {
- // Configure SSL.
- final SslContext sslCtx = null;
-// if (SSL) {
-// File key = FileUtil.readFileByCls("l.key");
-// File cert = FileUtil.readFileByCls("l.crt");
-// sslCtx = SslContextBuilder.forServer(cert, key).build();
-// } else {
-// sslCtx = null;
-// }
// Configure the server.
- EventLoopGroup bossGroup = new NioEventLoopGroup(1);
- EventLoopGroup workerGroup = new NioEventLoopGroup();
+ EventLoopGroup bossGroup = NettyUtil.newEventLoopGroup(1);
+ EventLoopGroup workerGroup = NettyUtil.newEventLoopGroup(1);
try {
ServerBootstrap b = new ServerBootstrap();
- b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 100).handler(new LoggingHandler(LogLevel.INFO)).childHandler(new ChannelInitializer() {
+ b.group(bossGroup, workerGroup);
+ b.channel(NettyUtil.newServerSocketChannel());
+ b.option(ChannelOption.SO_BACKLOG, 50);
+ b.childHandler(new ChannelInitializer() {
@Override
- public void initChannel(SocketChannel ch) throws Exception {
+ public void initChannel(SocketChannel ch) {
ChannelPipeline p = ch.pipeline();
- if (sslCtx != null) {
- p.addLast(sslCtx.newHandler(ch.alloc()));
- }
- //p.addLast(new LoggingHandler(LogLevel.INFO));
p.addLast(new TcpServerHandler());
}
});
// Start the server.
- ChannelFuture f = b.bind(PORT).sync();
+ ChannelFuture f = b.bind(8080).sync();
// Wait until the server socket is closed.
f.channel().closeFuture().sync();
diff --git a/firenio-test/src/main/java/test/others/netty/HelloClient.java b/firenio-test/src/main/java/test/others/netty/HelloClient.java
index c7ed52f21..79bfdad06 100644
--- a/firenio-test/src/main/java/test/others/netty/HelloClient.java
+++ b/firenio-test/src/main/java/test/others/netty/HelloClient.java
@@ -8,7 +8,6 @@
public class HelloClient extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
- // TODO Auto-generated method stub
System.out.println("channelActive>>>>>>>>");
}
diff --git a/firenio-test/src/main/java/test/others/netty/MyNettyServer.java b/firenio-test/src/main/java/test/others/netty/MyNettyServer.java
index e03d017e1..213a158da 100644
--- a/firenio-test/src/main/java/test/others/netty/MyNettyServer.java
+++ b/firenio-test/src/main/java/test/others/netty/MyNettyServer.java
@@ -16,10 +16,10 @@
import io.netty.util.CharsetUtil;
public class MyNettyServer {
- private static final EventLoopGroup bossGroup = new NioEventLoopGroup(1);
+ private static final EventLoopGroup bossGroup = NettyUtil.newEventLoopGroup(1);
private static final String IP = "127.0.0.1";
private static final int PORT = 8300;
- private static final EventLoopGroup workerGroup = new NioEventLoopGroup(8);
+ private static final EventLoopGroup workerGroup = NettyUtil.newEventLoopGroup(8);
public static void main(String[] args) throws Exception {
System.out.println("开始启动TCP服务器...");
@@ -30,7 +30,7 @@ public static void main(String[] args) throws Exception {
public static void service() throws Exception {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup);
- bootstrap.channel(NioServerSocketChannel.class);
+ bootstrap.channel(NettyUtil.newServerSocketChannel());
bootstrap.childHandler(new ChannelInitializer() {
@Override
diff --git a/firenio-test/src/main/java/test/others/netty/NettyClient.java b/firenio-test/src/main/java/test/others/netty/NettyClient.java
index 3e92737e7..189e1ce67 100644
--- a/firenio-test/src/main/java/test/others/netty/NettyClient.java
+++ b/firenio-test/src/main/java/test/others/netty/NettyClient.java
@@ -19,6 +19,7 @@
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.AttributeKey;
import io.netty.util.CharsetUtil;
+import io.netty.util.NetUtil;
import com.firenio.common.Util;
@@ -33,11 +34,11 @@ public class NettyClient {
}
public static void main(String[] args) throws Exception {
- EventLoopGroup group = new NioEventLoopGroup();
+ EventLoopGroup group = NettyUtil.newEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group);
- b.channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true);
+ b.channel(NettyUtil.newSocketChannel()).option(ChannelOption.TCP_NODELAY, true);
b.handler(new ChannelInitializer() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
diff --git a/firenio-test/src/main/java/test/others/netty/NettyClientThread.java b/firenio-test/src/main/java/test/others/netty/NettyClientThread.java
index 77c8e3819..e9952955b 100644
--- a/firenio-test/src/main/java/test/others/netty/NettyClientThread.java
+++ b/firenio-test/src/main/java/test/others/netty/NettyClientThread.java
@@ -21,11 +21,11 @@
public class NettyClientThread {
public static void main(String[] args) throws Exception {
- EventLoopGroup group = new NioEventLoopGroup();
+ EventLoopGroup group = NettyUtil.newEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group);
- b.channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true);
+ b.channel(NettyUtil.newSocketChannel()).option(ChannelOption.TCP_NODELAY, true);
b.handler(new ChannelInitializer() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
diff --git a/firenio-test/src/main/java/test/others/netty/NettyUtil.java b/firenio-test/src/main/java/test/others/netty/NettyUtil.java
new file mode 100644
index 000000000..100bdab98
--- /dev/null
+++ b/firenio-test/src/main/java/test/others/netty/NettyUtil.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.others.netty;
+
+import io.netty.channel.EventLoop;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.epoll.Epoll;
+import io.netty.channel.epoll.EpollEventLoopGroup;
+import io.netty.channel.epoll.EpollServerSocketChannel;
+import io.netty.channel.epoll.EpollSocketChannel;
+import io.netty.channel.epoll.Native;
+import io.netty.channel.kqueue.KQueue;
+import io.netty.channel.kqueue.KQueueEventLoopGroup;
+import io.netty.channel.kqueue.KQueueServerSocketChannel;
+import io.netty.channel.kqueue.KQueueSocketChannel;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.ServerSocketChannel;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+
+
+/**
+ * @author: wangkai
+ **/
+public class NettyUtil {
+
+ public static EventLoopGroup newEventLoopGroup() {
+ return newEventLoopGroup(0);
+ }
+
+ public static EventLoopGroup newEventLoopGroup(int ts) {
+ if (Epoll.isAvailable()) {
+ return new EpollEventLoopGroup(ts);
+ } else if (KQueue.isAvailable()) {
+ return new KQueueEventLoopGroup(ts);
+ } else {
+ return new NioEventLoopGroup(ts);
+ }
+ }
+
+ public static Class extends SocketChannel> newSocketChannel() {
+ if (Epoll.isAvailable()) {
+ return EpollSocketChannel.class;
+ } else if (KQueue.isAvailable()) {
+ return KQueueSocketChannel.class;
+ } else {
+ return NioSocketChannel.class;
+ }
+ }
+
+ public static Class extends ServerSocketChannel> newServerSocketChannel() {
+ if (Epoll.isAvailable()) {
+ return EpollServerSocketChannel.class;
+ } else if (KQueue.isAvailable()) {
+ return KQueueServerSocketChannel.class;
+ } else {
+ return NioServerSocketChannel.class;
+ }
+ }
+
+}
diff --git a/firenio-test/src/main/java/test/others/netty/TcpServerHandler.java b/firenio-test/src/main/java/test/others/netty/TcpServerHandler.java
index 98615a0b8..dba2b6b2b 100644
--- a/firenio-test/src/main/java/test/others/netty/TcpServerHandler.java
+++ b/firenio-test/src/main/java/test/others/netty/TcpServerHandler.java
@@ -7,31 +7,27 @@ public class TcpServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
- // TODO Auto-generated method stub
- System.out.println("channelActive>>>>>>>>");
+ System.out.println("active>>>>>>>>");
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
- ctx.channel().writeAndFlush(msg);
+
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
- System.out.println("hi 发生异常了:" + cause.getMessage());
- super.exceptionCaught(ctx, cause);
+ cause.printStackTrace();
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
- System.out.println("channelActive>>>>>>>>");
+ System.out.println("inactive>>>>>>>>");
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
- // IdleStateEvent e = (IdleStateEvent) evt;
- // System.out.println(DateUtil.formatYyyy_MM_dd_HH_mm_ss_SSS() + " " + e.state());
- super.userEventTriggered(ctx, evt);
+ System.out.println(evt);
}
}
diff --git a/firenio-test/src/main/java/test/others/netty/TestLoadEchoClient1.java b/firenio-test/src/main/java/test/others/netty/TestLoadEchoClient1.java
index dbc33be02..b0648c43a 100644
--- a/firenio-test/src/main/java/test/others/netty/TestLoadEchoClient1.java
+++ b/firenio-test/src/main/java/test/others/netty/TestLoadEchoClient1.java
@@ -39,7 +39,7 @@ public class TestLoadEchoClient1 extends ITestThread {
private ChannelInboundHandlerAdapter eventHandleAdaptor = null;
private ChannelFuture f;
- private EventLoopGroup group = new NioEventLoopGroup();
+ private EventLoopGroup group = NettyUtil.newEventLoopGroup();
public static void main(String[] args) throws IOException {
@@ -63,7 +63,7 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) {
Bootstrap b = new Bootstrap();
b.group(group);
- b.channel(NioSocketChannel.class);
+ b.channel(NettyUtil.newSocketChannel());
b.handler(new ChannelInitializer() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
diff --git a/firenio-test/src/main/java/test/others/smartsocket/TestSmartsocket.java b/firenio-test/src/main/java/test/others/smartsocket/TestSmartsocket.java
index b2fa86493..363f30595 100644
--- a/firenio-test/src/main/java/test/others/smartsocket/TestSmartsocket.java
+++ b/firenio-test/src/main/java/test/others/smartsocket/TestSmartsocket.java
@@ -34,7 +34,7 @@
// */
//public class TestSmartsocket {
//
-// static byte[] body = "Hello, World!".getBytes();
+// static byte[] body = "Hello, World!".readBytes();
//
// static class Message {
// private String message;
diff --git a/firenio-test/src/main/java/test/others/ssl/SSLSocketClient.java b/firenio-test/src/main/java/test/others/ssl/SSLSocketClient.java
index 3878bfa20..eb1491ce0 100644
--- a/firenio-test/src/main/java/test/others/ssl/SSLSocketClient.java
+++ b/firenio-test/src/main/java/test/others/ssl/SSLSocketClient.java
@@ -60,7 +60,7 @@ public X509Certificate[] getAcceptedIssuers() {
context.init(null, new TrustManager[]{x509m}, new SecureRandom());
SSLSocketFactory factory = context.getSocketFactory();
- SSLSocket s = (SSLSocket) factory.createSocket("192.168.133.134", 1443);
+ SSLSocket s = (SSLSocket) factory.createSocket("localhost", 443);
System.out.println("ok");
OutputStream output = s.getOutputStream();
diff --git a/firenio-test/src/main/java/test/others/undertow/TestUndertow.java b/firenio-test/src/main/java/test/others/undertow/TestUndertow.java
index 3ac49ebfd..421ecdbd0 100644
--- a/firenio-test/src/main/java/test/others/undertow/TestUndertow.java
+++ b/firenio-test/src/main/java/test/others/undertow/TestUndertow.java
@@ -55,7 +55,7 @@ public void handleRequest(final HttpServerExchange exchange) throws Exception {
private boolean hasBody(HttpServerExchange exchange) {
int length = (int) exchange.getRequestContentLength();
if (length == 0) {
- return false; // if body is empty, skip reading
+ return false; // if body is empty, skipRead reading
}
HttpString method = exchange.getRequestMethod();
diff --git a/firenio-test/src/main/java/test/test/TestUtil.java b/firenio-test/src/main/java/test/test/TestUtil.java
new file mode 100644
index 000000000..691c68375
--- /dev/null
+++ b/firenio-test/src/main/java/test/test/TestUtil.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2015 The FireNio Project
+ *
+ * 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 test.test;
+
+import com.firenio.common.ByteUtil;
+
+/**
+ * @author: wangkai
+ **/
+public class TestUtil {
+
+ public static String newString(int len) {
+ StringBuilder sb = new StringBuilder(len);
+ for (int i = 0; i < len; i++) {
+ sb.append(ByteUtil.getNumString((byte) (i % 10)));
+ }
+ return sb.toString();
+ }
+
+}
diff --git a/firenio/pom.xml b/firenio/pom.xml
index 5c9979d75..2f1eda953 100644
--- a/firenio/pom.xml
+++ b/firenio/pom.xml
@@ -4,7 +4,7 @@
4.0.0
com.firenio
firenio
- 1.2.2
+ 1.3.2
${project.artifactId}
An io framework project based on java nio
https://github.com/firenio/firenio