Class IdAllocator

  • All Implemented Interfaces:

    
    public class IdAllocator
    
                        

    通用 ID 分配器

    用于高效地分配和回收整数 ID。支持正向优先分配,正向耗尽后自动切换到负向。 使用区间合并算法来高效管理空闲 ID 区间,确保 O(log n) 的分配和释放操作。

    • 正向优先分配
    • 正向耗尽后自动使用负向
    • 支持 ID 释放和区间合并
    • 线程安全(所有公共方法使用 synchronized)
    • O(log n) 时间复杂度的分配和释放操作
    
    // 从已用 ID 集合初始化
    Set<Integer> usedIds = new HashSet<>(Arrays.asList(1, 2, 5, 6, 7));
    IdAllocator allocator = new IdAllocator(usedIds);
    
    // 分配 ID(返回 3,因为 1,2 已用,3 是第一个空洞)
    int id1 = allocator.acquire(); // 3
    int id2 = allocator.acquire(); // 4
    int id3 = allocator.acquire(); // 8
    
    // 释放 ID
    allocator.release(3);
    allocator.release(4);
    // 下次分配会优先使用刚释放的 ID
    int id4 = allocator.acquire(); // 3
    
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
    • Field Summary

      Fields 
      Modifier and Type Field Description
    • Constructor Summary

      Constructors 
      Constructor Description
      IdAllocator() 创建一个空的 ID 分配器
      IdAllocator(Set<Integer> usedIds) 根据已用 ID 集合创建 ID 分配器
    • Enum Constant Summary

      Enum Constants 
      Enum Constant Description
    • Method Summary

      Modifier and Type Method Description
      synchronized int acquire() 获取一个可用的 ID 分配策略:
      • 优先分配最小的正向空洞 ID
      • 如果正向耗尽,进行负向分配 ID
      synchronized boolean release(int id) 释放一个 ID,使其可被重新分配 释放策略:
      • 从已用集合中移除该 ID
      • 尝试与相邻空洞区间合并
      synchronized boolean isUsed(int id) 检查指定 ID 是否已被使用
      synchronized int getUsedCount() 获取当前已使用的 ID 数量
      synchronized int getHoleCount() 获取当前空洞区间的数量 可用于监控碎片化程度。区间数量越多,碎片化越严重。
      synchronized NavigableMap<Integer, Integer> getHolesView() 获取空洞区间的不可变包装 返回的 Map 是当前空洞区间的不可变包装,无法修改。
      synchronized NavigableMap<Integer, Integer> getHolesSnapshot() 获取空洞区间的快照 返回的 Map 是当前空洞区间的副本,修改不会影响分配器状态。
      synchronized Set<Integer> getUsedIdsView() 获取已用 ID 的不可变包装
      synchronized Set<Integer> getUsedIdsSnapshot() 获取已用 ID 的快照
      synchronized int peekNextId() 获取下一个将被分配的 ID(不实际分配) 如果没有可用的 ID(正负42亿个ID全部占用,你是个人物),直接报错。
      synchronized void reset() 重置分配器状态 清空所有已用 ID 和空洞区间,重新初始化。
      synchronized void reinitialize(@NonNull() Set<Integer> newUsedIds) 根据新的已用 ID 集合重新初始化分配器
      synchronized String toString()
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

      • IdAllocator

        IdAllocator()
        创建一个空的 ID 分配器
      • IdAllocator

        IdAllocator(Set<Integer> usedIds)
        根据已用 ID 集合创建 ID 分配器
        Parameters:
        usedIds - 已使用的 ID 集合,不能为 null
    • Method Detail

      • acquire

         synchronized int acquire()

        获取一个可用的 ID

        分配策略:

        • 优先分配最小的正向空洞 ID
        • 如果正向耗尽,进行负向分配 ID
        Returns:

        新分配的 ID

      • release

         synchronized boolean release(int id)

        释放一个 ID,使其可被重新分配

        释放策略:

        • 从已用集合中移除该 ID
        • 尝试与相邻空洞区间合并
        Parameters:
        id - 要释放的 ID
        Returns:

        true 如果释放成功,false 如果该 ID 未被使用

      • isUsed

         synchronized boolean isUsed(int id)

        检查指定 ID 是否已被使用

        Parameters:
        id - 要检查的 ID
        Returns:

        true 如果 ID 已被使用

      • getUsedCount

         synchronized int getUsedCount()

        获取当前已使用的 ID 数量

        Returns:

        已使用 ID 的数量

      • getHoleCount

         synchronized int getHoleCount()

        获取当前空洞区间的数量

        可用于监控碎片化程度。区间数量越多,碎片化越严重。

        Returns:

        空洞区间的数量

      • getHolesView

        @NonNull() synchronized NavigableMap<Integer, Integer> getHolesView()

        获取空洞区间的不可变包装

        返回的 Map 是当前空洞区间的不可变包装,无法修改。

        Returns:

        空洞区间的不可变包装

      • getHolesSnapshot

        @NonNull() synchronized NavigableMap<Integer, Integer> getHolesSnapshot()

        获取空洞区间的快照

        返回的 Map 是当前空洞区间的副本,修改不会影响分配器状态。

        Returns:

        空洞区间的不可修改副本

      • getUsedIdsView

        @NonNull() synchronized Set<Integer> getUsedIdsView()

        获取已用 ID 的不可变包装

        Returns:

        已用 ID 集合的不可变包装

      • getUsedIdsSnapshot

        @NonNull() synchronized Set<Integer> getUsedIdsSnapshot()

        获取已用 ID 的快照

        Returns:

        已用 ID 集合的不可修改副本

      • peekNextId

         synchronized int peekNextId()

        获取下一个将被分配的 ID(不实际分配)

        如果没有可用的 ID(正负42亿个ID全部占用,你是个人物),直接报错。

        Returns:

        下一个将被分配的 ID

      • reset

         synchronized void reset()

        重置分配器状态

        清空所有已用 ID 和空洞区间,重新初始化。

      • reinitialize

         synchronized void reinitialize(@NonNull() Set<Integer> newUsedIds)

        根据新的已用 ID 集合重新初始化分配器

        Parameters:
        newUsedIds - 新的已用 ID 集合