几个月前,我实现了一个从 1 到 65535(16 位)范围内选择唯一值的解决方案。这个范围用于生成唯一的路由目标后缀,对于这个客户来说,庞大的网络(它是一个巨大的 ISP)是一个非常有争议的资源,所以任何释放的值(value)都需要立即提供给最终用户。
为了满足这个要求,我使用了 BitSet .使用 set
在 RT 索引上分配后缀,并使用 clear
取消分配后缀。方法nextClearBit()可以找到下一个可用值。我手动处理同步/并发问题。
这对于小范围来说效果很好……整个索引很小(大约 10k),速度非常快,可以很容易地序列化并存储在 blob 字段中。
问题是,一些新设备可以处理 32 位无符号的 RT 后缀(范围 1/4294967296)。这不能用 BitSet 来管理(它本身会消耗大约 600Mb,而且仅限于 int
- 32 位有符号 - 范围)。即使有这么大的可用范围,客户仍然希望释放最终用户可用的路由目标后缀,主要是因为与旧路由器兼容的最低后缀(最多 65535)存在很大争议。
在我告诉客户这是不可能的之前,他将不得不为较低的 RT(最高 65550)符合我的可重用索引并为其他的使用数据库序列(这意味着当用户释放一个 Route Target ,它不会再次可用),有人能解释一下吗?
也许某种灵魂已经为 Java 实现了一个高性能的数字池(如果重要的话是 6),或者我缺少 Oracle 数据库的 killer 级特性(如果重要的话是 11R2)...只是一些一厢情愿的想法:)。
非常感谢您。
最佳答案
我会结合以下内容:
1-65535 的当前 BitSet 解决方案
加上
基于 Oracle 的解决方案,其序列为 65536 - 4294967296,环绕定义为
CREATE SEQUENCE MyIDSequence
MINVALUE 65536
MAXVALUE 4294967296
START WITH 65536
INCREMENT BY 1
CYCLE
NOCACHE
ORDER;
此序列为您提供指定范围内的有序值,并允许重复使用任何值,但只有在达到最大值后 - 这应该为释放值留出足够的时间...如果需要,您可以跟踪值在表中使用,如果返回值已在使用中,则进一步递增 - 为了方便起见,所有这些都可以很好地包装到存储过程中......
关于Java "pool"of longs 或重用释放值的 Oracle 序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8272622/