理论部分

一个long占8byte,大多数应用数值不超过int每次传输多4byte会很浪费

有没有什么办法可以压缩long或int呢?

答案是有的,原理好简单,如果数值不超过int.max_value的话就"自动变成"int类型

现在问题又出现了读取时如果知道原来的类型是什么?

可以先写一个byte是什么类型,再写入值,读时先读一个byte,根据类型做不同解释

源码解读

 public abstract class PacketUtil {

     public final static byte BIT_8 = Byte.MAX_VALUE;
public final static short BIT_16 = Short.MAX_VALUE;
public final static int BIT_32 = Integer.MAX_VALUE;
public final static long BIT_64 = Long.MAX_VALUE;
/***
读取自适应数字
*/
public static Number autoReadNum(int offset, byte[] bytes) {
byte bit = bytes[offset];
offset++;
Number ret = null;
switch (bit) {
case 9: //readLong
ret = readLong(offset, bytes);
break;
case 5: //readInt
ret = readInt(offset, bytes);
break;
case 3: //readShort
ret = readShort(offset, bytes);
break;
case 2: //readByte
ret = readByte(offset, bytes);
break;
case 1: //zero
ret = (byte) 0;
break;
default:
throw new QSocketException(QCode.SOCKET_UNKNOWN_OPCODE, "auto bytes unknown opcode :" + bit);
} return ret;
}
/***
写入自适应数字
*/
public static byte autoWriteNum(int offset, Number v, byte[] ret) {
byte bit = getAutoWriteLen(v);
writeByte(offset, bit, ret);
offset++;
switch (bit) {
case 9: //writeLong
writeLong(offset, v.longValue(), ret);
break;
case 5: //writeInt
writeInt(offset, v.intValue(), ret);
break;
case 3: //writeShort
writeShort(offset, v.shortValue(), ret);
break;
case 2: //writeByte
writeByte(offset, v.byteValue(), ret);
break;
case 1: //zero
break;
default:
throw new QSocketException(QCode.SOCKET_UNKNOWN_OPCODE, "auto bytes unknown opcode :" + bit);
}
return bit;
}
/***
获取自适合数字大小
*/
public static byte getAutoWriteLen(Number value) {
long v = value.longValue();
if (v < 0) {
v = -v;
}
byte bit = 0;
//如果为零返回类型为0
if (v == 0) {
bit = 1;
} else if (v > BIT_32) { //如果超过int max 认为是long类型
bit = 9;
} else if (v > BIT_16) {//如果超过short max 认为是int类型
bit = 5;
} else if (v > BIT_8) { //如果超过byte max 认为是short类型
bit = 3;
} else { //否则为byte类型
bit = 2;
}
return bit;
}
}

如果数值为0时,可以减小到1byte,少于short.max_value 占3byte,减少60%空间

[编织消息框架][设计协议]优化long,int转换的更多相关文章

  1. [编织消息框架][设计协议]bit基础

    理论部分 1字节等于8比特,也就是8个二进数,如下面公式 1Byte = 8bits = 0111 1111 1Short = 2Btye 1Int = 4Byte 那学这些有什么用呢? 可以用来做数 ...

  2. [编织消息框架][设计协议]opCode

    OpCode的全称 OpCode(Operation Code) 操作码的意思. OpCode 有几种域组成,不同领域格式组成不同 1.指令号 2.数据范围 3.数据内容 如 {code}{addr ...

  3. [编织消息框架][netty源码分析]2 eventLoop

    eventLoop从命名上看是专门处理事件 事件系统主要由线程池同队列技术组成,有以下几个优点 1.任务出队有序执行,不会出现错乱,当然前提执行线程池只有一个 2.解偶系统复杂度,这是个经典的生产者/ ...

  4. [编织消息框架][netty源码分析]4 eventLoop 实现类NioEventLoop职责与实现

    NioEventLoop 是jdk nio多路处理实现同修复jdk nio的bug 1.NioEventLoop继承SingleThreadEventLoop 重用单线程处理 2.NioEventLo ...

  5. [编织消息框架][网络IO模型]BIO

    既然跟网络内容有关就不得不学习网络IO模型,时代在进步,技术也在进步,采取使用那种网络IO模型就已经确定应用程序规模 阻塞IO(blocking IO) 在linux中,默认情况下所有的socket都 ...

  6. [编织消息框架][netty源码分析]14 PoolChunk 的 PoolSubpage

    final class PoolSubpage<T> implements PoolSubpageMetric { //该page分配的chunk final PoolChunk<T ...

  7. [编织消息框架][JAVA核心技术]数值与逻辑分离

    为什么要分离? 业务需求是不停地变,如果把条件写进代码里,当用户需求变时要改代码发版本更新才能生效,这过程无疑是漫长的 就算是在开发期,不停的变开发者精力耗光在沟通,小修改上,无法专注逻辑部分 分离的 ...

  8. [编织消息框架][netty源码分析]3 EventLoop 实现类SingleThreadEventLoop职责与实现

    eventLoop是基于事件系统机制,主要技术由线程池同队列组成,是由生产/消费者模型设计,那么先搞清楚谁是生产者,消费者内容 SingleThreadEventLoop 实现 public abst ...

  9. [编织消息框架][JAVA核心技术]jdk动态代理

    需要用到的工具  jdk : javac javap class 反编译 :JD-GUI http://jd.benow.ca/ import java.lang.reflect.Invocation ...

随机推荐

  1. iOS 之 系统机制

    iOS 沙盒 iOS 8 之 新特性 iOS 操作系统整体架构层次讲解

  2. 创建TabBar

    -(void)creatTabBarView { NSArray *imgArray=@[]; NSArray *selectImage=@[]; NSArray *names=@[]; for (i ...

  3. Angular - - ngInclude、ngTransclude

    这两个都是HTML DOM嵌入指令 ngInclude 读取,编译和插入外部的HTML片段. 格式:ng-include=“value”<ng-include src=”value” onloa ...

  4. js动态控制table的tr,td增加及删除

    html: <table id='wifi_clients_table'   class="table table-striped table-bordered table-hover ...

  5. HTML 5 服务器发送事件、Input 类型、表单元素、表单属性

    HTML5 服务器发送事件(server-sent event)允许网页获得来自服务器的更新. Server-Sent 事件 - 单向消息传递 Server-Sent 事件指的是网页自动获取来自服务器 ...

  6. JVM内存划分基础知识

    第一部分 JVM内存划分 目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbag ...

  7. C#多线程-volatile、lock关键字

    volatile是C#中最简单的一种同步关键字,其意义是针对程序中一些敏感数据,不允许多线程同时访问,保证数据在任何访问时刻,最多有一个线程访问,以保证数据的完整性,虽与java中的synchroni ...

  8. aJax请求结果中包含form的问题

    jsp页面a.jsp如下: <form action='login' id='formId' method='post'> <input name='user'> </f ...

  9. Yii2 独立操作

    看到最近有些人在问 yii2 独立操作相关的东西,在这做简单的说明吧, 平时核心业务逻辑一般用的还是比较少的.因为  独立操作 出现的原因 是 对重复被使用的操作进行简化,或 分配一个 额外处理逻辑的 ...

  10. 新手初学Redis之基础知识命令

    笔者最初接触Redis是因为了解了一些nosql方面的知识,觉得nosql是一个很有意思的方面.像其中的mongodb,redis等等.当初也没有深入的去了解Redis,直到自己前段时间在写一个web ...