Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 系列化番石榴';s MinMaxPriorityQueue_Scala_Guava_Apache Flink_Kryo - Fatal编程技术网

Scala 系列化番石榴';s MinMaxPriorityQueue

Scala 系列化番石榴';s MinMaxPriorityQueue,scala,guava,apache-flink,kryo,Scala,Guava,Apache Flink,Kryo,经过几天的研究,我得出结论,问题出在我使用的MinMaxPriorityQueue中 似乎此结构不可序列化。我尝试了几种序列化方法: env.getConfig.registerTypeWithKryoSerializer(classOf[MinMaxPriorityQueue[Double]], classOf[JavaSerializer]) env.getConfig.registerTypeWithKryoSerializer(classOf[MinMaxPriorityQueue[ja

经过几天的研究,我得出结论,问题出在我使用的
MinMaxPriorityQueue

似乎此结构不可序列化。我尝试了几种序列化方法:

env.getConfig.registerTypeWithKryoSerializer(classOf[MinMaxPriorityQueue[Double]], classOf[JavaSerializer])
env.getConfig.registerTypeWithKryoSerializer(classOf[MinMaxPriorityQueue[java.lang.Double]], classOf[ProtobufSerializer]);
env.getConfig().addDefaultKryoSerializer(MyCustomType.class, TBaseSerializer.class);
他们都不走运

但我发现:

是否有与MinMaxPriorityQueue等效的方法,或序列化它的方法

使现代化 我已将Tomasz翻译成scala:

class MinMaxPriorityQueueSerializer extends Serializer[MinMaxPriorityQueue[Object]] {
  private[this] val log = LoggerFactory.getLogger(this.getClass)
  setImmutable(false)
  setAcceptsNull(false)

  val OPTIMIZE_POSITIVE = true

  override def read(kryo: Kryo, input: Input, aClass: Class[MinMaxPriorityQueue[Object]]): MinMaxPriorityQueue[Object] = {
    log.error("Kryo READ")
    val comparator: Ordering[Object] = kryo.readClassAndObject(input).asInstanceOf[Ordering[Object]]
    val size = input.readInt(OPTIMIZE_POSITIVE)

    val queue: MinMaxPriorityQueue[Object] = MinMaxPriorityQueue.orderedBy(comparator)
      .expectedSize(size)
      .create()

    (0 to size).foreach(_ => queue.offer(kryo.readClassAndObject(input)))

    queue
  }

  override def write(kryo: Kryo, output: Output, queue: MinMaxPriorityQueue[Object]): Unit = {
    log.error("Kryo WRITE")
    kryo.writeClassAndObject(output, queue.comparator)

    val declaredSize = queue.size
    output.writeInt(declaredSize, OPTIMIZE_POSITIVE)

    val actualSize = queue.toArray.foldLeft(0) {
      case (z, q) =>
        kryo.writeClassAndObject(output, q)
        z + 1
    }

    Preconditions.checkState(
      declaredSize == actualSize,
      "Declared size (%s) different than actual size (%s)", declaredSize, actualSize)
  }
}
并在flink中设置kryo以使用该序列化程序:

env.getConfig.addDefaultKryoSerializer(classOf[MinMaxPriorityQueue[Double]], classOf[MinMaxPriorityQueueSerializer])       

env.getConfig.registerTypeWithKryoSerializer(classOf[MinMaxPriorityQueue[Double]], classOf[MinMaxPriorityQueueSerializer])
然而,它似乎从未被调用,因为我在日志中的任何地方都没有看到
log.error(“Kryo READ”)
log.error(“Kryo WRITE”)

转换仍然返回一个空的MinMaxPriorityQueue,即使我正在更新它

更新2 我已经实现了SerializerTester,但是我得到了一个缓冲区下溢:

object Main {

  def main(args: Array[String]) {

    val tester = new MinMaxPriorityQueueSerializerTester()

    val inQueue: MinMaxPriorityQueue[java.lang.Double] = MinMaxPriorityQueue.create()
    inQueue.add(1.0)

    val outputStream = new ByteArrayOutputStream()
    tester.serialize(outputStream, inQueue)

    val inputStream = new ByteArrayInputStream(outputStream.toByteArray())
    val outQueue: MinMaxPriorityQueue[java.lang.Double] = tester.deserialize(inputStream);

    System.out.println(inQueue);
    System.out.println(outQueue);

  }

  class MinMaxPriorityQueueSerializerTester {
    val kryo = new Kryo
    kryo.setInstantiatorStrategy(new StdInstantiatorStrategy)
    registerMinMaxSerializer();
    //  allowForClassesWithoutNoArgConstructor(); // needed to serialize Ordering

    def registerMinMaxSerializer() {
      kryo.addDefaultSerializer(classOf[MinMaxPriorityQueue[java.lang.Double]], new MinMaxPriorityQueueSerializer());
    }

    def serialize(out: OutputStream, queue: MinMaxPriorityQueue[java.lang.Double]) {
      // try (Output output = new Output(out)) {
      val output = new Output(out)
      kryo.writeClassAndObject(output, queue)
      //      kryo.writeObject(output, queue)
      //}
      output.flush
    }

    def deserialize(in: InputStream): MinMaxPriorityQueue[java.lang.Double] = {
      //try (Input input = new Input(in)) {
      val input = new Input(in)
      //kryo.readObject(input, classOf[MinMaxPriorityQueue[java.lang.Double]])
      kryo.readClassAndObject(input).asInstanceOf[MinMaxPriorityQueue[java.lang.Double]]
      //p}
    }
  }

您可以使用自定义Kryo
序列化程序

下面是一个示例(Java):

类MinMaxPriorityQueueSerializer扩展了序列化程序{
私有静态最终布尔优化_正=真;
受保护的MinMaxPriorityQueueSerializer(){
SetAcceptsAll(假);
设置不可变(false);
}
@凌驾
公共无效写入(Kryo Kryo、输出、MinMaxPriorityQueue队列){
writeClassAndObject(输出,queue.comparator());
int declaredSize=queue.size();
output.writeInt(declaredSize,优化_正数);
int-actualSize=0;
for(对象元素:队列){
writeClassAndObject(输出,元素);
actualSize++;
}
先决条件(
declaredSize==实际大小,
“声明的大小(%s)与实际大小(%s)不同”,declaredSize,actualSize
);
}
@凌驾
公共MinMaxPriorityQueue读取(Kryo Kryo,输入,类类型){
@抑制警告(“未选中”)
比较器比较器=(比较器)kryo.readClassAndObject(输入);
int size=input.readInt(正优化);
MinMaxPriorityQueue=MinMaxPriorityQueue.orderedBy(比较器)
.预期尺寸(尺寸)
.create();
对于(int i=0;i
以下是您可以如何使用它:

class MinMaxPriorityQueueSerializerTester {

    public static void main(String[] args) {
        MinMaxPriorityQueueSerializerTester tester = new MinMaxPriorityQueueSerializerTester();

        MinMaxPriorityQueue<Integer> inQueue = MinMaxPriorityQueue.<Integer>orderedBy(Comparator.reverseOrder())
                .create(Arrays.asList(5, 2, 7, 2, 4));

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        tester.serialize(outputStream, inQueue);

        ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
        @SuppressWarnings("unchecked")
        MinMaxPriorityQueue<Integer> outQueue = (MinMaxPriorityQueue<Integer>) tester.deserialize(inputStream);

        System.out.println(inQueue);
        System.out.println(outQueue);
    }

    private final Kryo kryo;

    public MinMaxPriorityQueueSerializerTester() {
        this.kryo = new Kryo();
        registerMinMaxSerializer();
        allowForClassesWithoutNoArgConstructor(); // needed to serialize Ordering
    }

    private void registerMinMaxSerializer() {
        kryo.addDefaultSerializer(MinMaxPriorityQueue.class, new MinMaxPriorityQueueSerializer());
    }

    private void allowForClassesWithoutNoArgConstructor() {
        ((Kryo.DefaultInstantiatorStrategy) kryo.getInstantiatorStrategy())
                .setFallbackInstantiatorStrategy(new StdInstantiatorStrategy());
    }


    public void serialize(OutputStream out, MinMaxPriorityQueue<?> queue) {
        try (Output output = new Output(out)) {
            kryo.writeObject(output, queue);
        }
    }

    public MinMaxPriorityQueue<?> deserialize(InputStream in) {
        try (Input input = new Input(in)) {
            return kryo.readObject(input, MinMaxPriorityQueue.class);
        }
    }
}
class MinMaxPriorityQueueSerializerTester{
公共静态void main(字符串[]args){
MinMaxPriorityQueueSerializerTester=新的MinMaxPriorityQueueSerializerTester();
MinMaxPriorityQueue inQueue=MinMaxPriorityQueue.orderedBy(Comparator.reverseOrder())
.create(Arrays.asList(5,2,7,2,4));
ByteArrayOutputStream outputStream=新建ByteArrayOutputStream();
序列化(outputStream,inQueue);
ByteArrayInputStream inputStream=新建ByteArrayInputStream(outputStream.toByteArray());
@抑制警告(“未选中”)
MinMaxPriorityQueue outQueue=(MinMaxPriorityQueue)测试器。反序列化(inputStream);
System.out.println(inQueue);
System.out.println(输出队列);
}
私人决赛高雄高雄;
public MinMaxPriorityQueueSerializerTester(){
this.kryo=新的kryo();
registerMinMaxSerializer();
allowForClassesWithoutNoArgConstructor();//序列化排序需要
}
专用无效注册表项MaxSerializer(){
addDefaultSerializer(MinMaxPriorityQueue.class,新的MinMaxPriorityQueueSerializer());
}
私有void allowforclassswithoutnoargconstructor(){
((Kryo.defaultInstanceorStrategy)Kryo.getInstanceorStrategy())
.SetFallbackInstanceorStrategy(新StdInstantiatorStrategy());
}
public void序列化(OutputStream out,MinMaxPriorityQueue){
尝试(输出=新输出(输出)){
writeObject(输出,队列);
}
}
public MinMaxPriorityQueue反序列化(InputStream in){
尝试(输入=新输入(输入)){
返回kryo.readObject(输入,MinMaxPriorityQueue.class);
}
}
}

我最终放弃了,尝试使用不同的数据结构,并使用
java.io.Serializable
将其序列化

这个数据结构是一个,我刚刚在中使它可以序列化


现在一切正常。

您可以在Guava的Github repo中创建一个问题并请求该功能。有,其中提到了
MinMaxPriorityQueue
,但最后它没有包含在票据的范围内。@Xaerxess,谢谢,我已经打开了它:@elbaulp你能发布bufferUnderflow的堆栈跟踪吗?没关系,我改为使用intervalHeap的这个实现:因为它是开箱即用的。谢谢你的帮助,我接受你的回答。@elbaulp谢谢,尽管我的回答并没有真正解决你的问题。你可能会考虑单独回答一个问题,如果其他人有类似的问题,你会如何解决它。谢谢,我已经尝试过了,运气不好:-(@ El Baulp我用java测试了这个代码代码,它工作了。你测试过斯卡拉(Flink以外)的序列化吗?如果没有,请做。(正如我在
MinMaxPriorityQueueSerializerTester
中所做的),然后我们将了解更多。
class MinMaxPriorityQueueSerializerTester {

    public static void main(String[] args) {
        MinMaxPriorityQueueSerializerTester tester = new MinMaxPriorityQueueSerializerTester();

        MinMaxPriorityQueue<Integer> inQueue = MinMaxPriorityQueue.<Integer>orderedBy(Comparator.reverseOrder())
                .create(Arrays.asList(5, 2, 7, 2, 4));

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        tester.serialize(outputStream, inQueue);

        ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
        @SuppressWarnings("unchecked")
        MinMaxPriorityQueue<Integer> outQueue = (MinMaxPriorityQueue<Integer>) tester.deserialize(inputStream);

        System.out.println(inQueue);
        System.out.println(outQueue);
    }

    private final Kryo kryo;

    public MinMaxPriorityQueueSerializerTester() {
        this.kryo = new Kryo();
        registerMinMaxSerializer();
        allowForClassesWithoutNoArgConstructor(); // needed to serialize Ordering
    }

    private void registerMinMaxSerializer() {
        kryo.addDefaultSerializer(MinMaxPriorityQueue.class, new MinMaxPriorityQueueSerializer());
    }

    private void allowForClassesWithoutNoArgConstructor() {
        ((Kryo.DefaultInstantiatorStrategy) kryo.getInstantiatorStrategy())
                .setFallbackInstantiatorStrategy(new StdInstantiatorStrategy());
    }


    public void serialize(OutputStream out, MinMaxPriorityQueue<?> queue) {
        try (Output output = new Output(out)) {
            kryo.writeObject(output, queue);
        }
    }

    public MinMaxPriorityQueue<?> deserialize(InputStream in) {
        try (Input input = new Input(in)) {
            return kryo.readObject(input, MinMaxPriorityQueue.class);
        }
    }
}