package redo.state

import org.apache.flink.api.common.functions.{IterationRuntimeContext, RichFlatMapFunction, RichFunction, RichMapFunction, RuntimeContext}
import org.apache.flink.api.common.state.{ListState, ListStateDescriptor, MapState, MapStateDescriptor, ValueState, ValueStateDescriptor}
import org.apache.flink.api.scala._
import org.apache.flink.configuration.Configuration
import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment}
import org.apache.flink.util.Collector


import java.util
case class user(id:String,item:String,group:String,bea:String,timestamp:Long)

object StateTest {
def main(args: Array[String]): Unit = {
val eal = StreamExecutionEnvironment.getExecutionEnvironment
val input_Stream:DataStream[String] = eal.socketTextStream("hadoop101",7777)
val info = input_Stream.map(x=>{
val gh = x.split(",").filter(_.nonEmpty)
user(gh(0),gh(1),gh(2),gh(3), gh(4).toLong)
})
val alterStream = info.keyBy(_.id)
// .flatMap(new TempChangeAlert(2))
.flatMapWithState[(String,String,String,String,Long), Long] {
//值为none返回当前的值
case (data: user, None) => ( List.empty, Some(data.timestamp) )
case (data: user, lastTemp: Some[Long]) => {
// 跟最新的温度值求差值作比较
val diff = (data.timestamp - lastTemp.get).abs
if( diff > 10.0 )
( List((data.id, data.item,data.group, data.bea,data.timestamp)), Some(data.timestamp) )
else
( List.empty, Some(data.timestamp))
}
}
alterStream.print()

eal.execute("state test")
}

}
// 实现自定义RichFlatmapFunction
class TempChangeAlert(threshold: Long) extends RichFlatMapFunction[user, (String, Long,Long)]{
// 定义状态保存上一次的温度值
lazy val lastTempState: ValueState[Long] = getRuntimeContext.getState(new ValueStateDescriptor[Long]("last-temp", classOf[Long]))
lazy val flagState: ValueState[Boolean] = getRuntimeContext.getState(new ValueStateDescriptor[Boolean]("flag", classOf[Boolean]))

override def flatMap(value: user, out: Collector[(String, Long,Long)]): Unit = {
// 获取上次的温度值
val lastTemp = lastTempState.value()

// 跟最新的温度值求差值作比较
val diff = (value.timestamp - lastTemp).abs

println("最后 "+lastTemp+ " 保 持 "+threshold+" "+flagState.value()+ " 绝对值 "+diff)
/*if( !flagState.value() && diff > threshold )
out.collect( (value.id, lastTemp, value.timestamp) )*/
if( diff > threshold )
out.collect( (value.id, lastTemp, value.timestamp) )

// 更新状态
lastTempState.update(value.timestamp)
flagState.update(true)
}
}
class RichMapper extends RichMapFunction[user,String] {
var valueState: ValueState[Double] = _
lazy val listState: ListState[Int] = getRuntimeContext.getListState( new ListStateDescriptor[Int]("liststate", classOf[Int]) )
//lazy val mapState: MapState[String, Double] = getRuntimeContext.getMapState( new MapStateDescriptor[String, Double]("mapstate", classOf[String], classOf[Double]))
override def map(in: user): String = {
// 状态的读写
val myV = valueState.value()
valueState.update(in.timestamp)
listState.add(1)
val list = new util.ArrayList[Int]()
list.add(2)
list.add(3)
listState.addAll(list)
listState.update(list)
listState.get()

in.id

}

override def open(parameters: Configuration): Unit = {
valueState = getRuntimeContext.getState( new ValueStateDescriptor[Double]("valuestate", classOf[Double]))
}
}