t2

发布时间 2023-11-17 22:24:44作者: 追风fc
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
* 本题答题框内的代码仅为待实现代码,执行或提交代码时,仅包含待实现部分(含所需的import)
* CodeCheck/Cmetrics工具也仅扫描待实现部分。
* 若需要完整框架用于本地调试,请点击答题框上面的“下载完整框架代码”进行下载。
* jdk基线版本为jdk 11, 平台支持jdk 17;使用完整框架代码需满足jdk基线要求。另将于24年引入fastjson 1.2.83
* VideoService([8, 1, 1], [10, 15, 30])
* allocateChannel(3, 107, 1)
* allocateChannel(3, 108, 1)
* allocateChannel(5, 110, 1)
* queryChannel(108)
* freeChannel(13, 108)
*
* @author 命题组
* @since 2023-1-1
*/
class VideoService {
public static void main(String[] args) {
VideoService vs = new VideoService(new int[]{8, 1, 1}, new int[]{10, 15, 30});
System.out.println(vs.allocateChannel(3, 107, 1));
System.out.println(vs.allocateChannel(3, 108, 1));
System.out.println(vs.allocateChannel(5, 110, 1));
System.out.println(vs.queryChannel(108));
System.out.println(vs.freeChannel(13, 108));
}

/**
* 使用记录
*/
private Map<Integer, UseVideoLog> userLogMap = new ConcurrentHashMap<>();

/**
* 资源池
*/
private Map<String, VideoResource> resPoolMap = new ConcurrentHashMap<>();
VideoService(int[] channels, int[] charge) {
// 注册资源通道池
for (int i = 0; i < channels.length; i++) {
int num = channels[i];
int price = charge[i];
for (int j = 0; j < num; j++) {
VideoResource res = new VideoResource();
res.setResId(UUID.randomUUID().toString());
res.setPrice(price);
res.setVideoType(i);
res.setStatus(true);
resPoolMap.put(res.getResId(), res);
}
}
}

boolean allocateChannel(int time, int userId, int videoType) {
// 筛选资源
List<VideoResource> fitterResList = resPoolMap.values().stream()
.filter(c -> c.videoType >= videoType && c.status).sorted(Comparator.comparingInt(o -> o.videoType))
.collect(Collectors.toList());
VideoResource res;
if (fitterResList == null || fitterResList.size() == 0) {
// 锁定资源失败
return false;
} else {
// 成功锁定
res = fitterResList.get(0);
}

List<VideoResource> fitterResList1 = resPoolMap.values().stream().filter(c -> c.videoType == videoType)
.sorted(Comparator.comparingInt(o -> o.price)).collect(Collectors.toList());
// 占用通道记录日志
UseVideoLog log = new UseVideoLog();
log.setUserId(userId);
log.setTime(time);
log.setActualVideoType(res.getVideoType());
log.setReqVideoType(videoType);
log.setPrice(fitterResList1.get(0).getPrice());
log.setResId(res.getResId());
userLogMap.put(userId, log);
// 资源锁定
res.setStatus(false);
resPoolMap.put(res.getResId(), res);
return true;
}

int freeChannel(int time, int userId) {
UseVideoLog log = userLogMap.get(userId);
if (log == null) {
return -1;
}
// 释放资源
VideoResource res = resPoolMap.get(log.getResId());
res.setStatus(true);
resPoolMap.put(log.getResId(), res);
// 移除使用记录
userLogMap.remove(userId);
// 分配给其他通道升级的用户 (按规则)
List<UseVideoLog> useVideoLogDownUserList = userLogMap.values().stream()
.filter(c -> c.getActualVideoType() > c.getReqVideoType() && c.getReqVideoType() <= res.videoType)
.sorted(Comparator.comparingInt(o -> o.userId)).collect(Collectors.toList());
// 降级匹配的用户
if (useVideoLogDownUserList != null && useVideoLogDownUserList.size() > 0) {
UseVideoLog downUser = useVideoLogDownUserList.get(0);
freeChannel(time, downUser.getUserId());
}
return (time - log.getTime()) * log.getPrice();
}

int queryChannel(int userId) {
UseVideoLog log = userLogMap.get(userId);
if (log == null) {
return -1;
}
return log.getActualVideoType();
}
}

class UseVideoLog {
String resId;
int userId;

int time;

int reqVideoType;

int actualVideoType;

int price;

public int getUserId() {
return userId;
}

public void setUserId(int userId) {
this.userId = userId;
}

public int getTime() {
return time;
}

public void setTime(int time) {
this.time = time;
}

public int getReqVideoType() {
return reqVideoType;
}

public void setReqVideoType(int reqVideoType) {
this.reqVideoType = reqVideoType;
}

public int getActualVideoType() {
return actualVideoType;
}

public void setActualVideoType(int actualVideoType) {
this.actualVideoType = actualVideoType;
}

public int getPrice() {
return price;
}

public void setPrice(int price) {
this.price = price;
}

public String getResId() {
return resId;
}

public void setResId(String resId) {
this.resId = resId;
}
}

class VideoResource {
String resId;
int videoType;

boolean status;

int price;

public int getVideoType() {
return videoType;
}

public void setVideoType(int videoType) {
this.videoType = videoType;
}

public boolean isStatus() {
return status;
}

public void setStatus(boolean status) {
this.status = status;
}

public int getPrice() {
return price;
}

public void setPrice(int price) {
this.price = price;
}

public String getResId() {
return resId;
}

public void setResId(String resId) {
this.resId = resId;
}
}