flink int序列化

Flink中int的存储并不是直接通过int来存储,而是通过IntValue来存储,这样在内存中只需要存储4个字节大小的数据就可以保证单个int数据的存储。

private int value;

在IntValue中用value字段来保存所需要的int字段。

 

在IntValue中值得一提的是copyNormaliedKey()方法。

@Override
public void copyNormalizedKey(MemorySegment target, int offset, int len) {
   // take out value and add the integer min value. This gets an offset
   // representation when interpreted as an unsigned integer (as is the case
   // with normalized keys). write this value as big endian to ensure the
   // most significant byte comes first.
   if (len == 4) {
      target.putIntBigEndian(offset, value - Integer.MIN_VALUE);
   }
   else if (len <= 0) {
   }
   else if (len < 4) {
      int value = this.value - Integer.MIN_VALUE;
      for (int i = 0; len > 0; len--, i++) {
         target.put(offset + i, (byte) ((value >>> ((3-i)<<3)) & 0xff));
      }
   }
   else {
      target.putIntBigEndian(offset, value - Integer.MIN_VALUE);
      for (int i = 4; i < len; i++) {
         target.put(offset + i, (byte) 0);
      }
   }
}

这个方法会将int值按照接口NormalizableKey的规定生成制定长度的规范键来存储到内存中以便比较。其中,如果给定的长度大于int的大小4字节,将会填充0到字节大小对齐。如果给定的长度小于原本int所需要的四字节,那么只会存储前几个字节,失去低位比较的精度。

 

IntValue通过write()方法将int数据存储到内存中。

@Override
public void write(DataOutputView out) throws IOException {
   out.writeInt(this.value);
}

最终还是调用的是DataOutputView的writeInt()方法,DataOutputView是内存在MemorySegment基础之上的进一步抽象。

以AbstractpagedInputView为例子,AbstractpagedInputView是所有分页内存实现类需要继承的抽象类。

@Override
public void writeInt(int v) throws IOException {
   if (this.positionInSegment < this.segmentSize - 3) {
      this.currentSegment.putIntBigEndian(this.positionInSegment, v);
      this.positionInSegment += 4;
   }
   else if (this.positionInSegment == this.segmentSize) {
      advance();
      writeInt(v);
   }
   else {
      writeByte(v >> 24);
      writeByte(v >> 16);
      writeByte(v >>  8);
      writeByte(v);
   }
}

如果当前AbstractpagedInputView所对应的MemerySegment剩余大小大于4字节,那么将会直接保存到当前MemerySegment的byte数组当中,同时代表当前位置的偏移量移动4个字节大小的位置。如果当前大小正好耗完,那么将会通过advance()方法得到一个新的memorySegmet来进行存储。如果剩余大小不为0也小于4字节,那么将会逐字节进行存储。

 

结合上者,看到IntValueSerializer的serialize()方法,关于int值的序列化过程也清楚了。

@Override
public void serialize(IntValue record, DataOutputView target) throws IOException {
   record.write(target);
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值