Class StorageManager

java.lang.Object
com.hypixel.hytale.server.core.universe.StorageManager

public class StorageManager extends Object
Manages persistent storage operations for a universe, enforcing per-path read-write exclusion and supporting save deferral during backup operations.

Per-path concurrency contract:

  • Save (write) operations are exclusive: no other save or load for the same path runs concurrently with a save.
  • Load (read) operations run in parallel with other loads for the same path, but not concurrently with saves.

When saving is locked (e.g. during a backup), save operations are queued per path and only the latest save function for each path is retained. When saving is released, the queued saves execute.

  • Constructor Details

    • StorageManager

      public StorageManager(BooleanSupplier isSavingLocked)
      Creates a new StorageManager.
      Parameters:
      isSavingLocked - a supplier that returns true when saving is locked
  • Method Details

    • hasQueuedSave

      public boolean hasQueuedSave(@Nonnull Path path)
      Returns whether there is a pending or in-flight save operation for the given path.
      Parameters:
      path - the file path to check
      Returns:
      true if a save is queued or in-flight for this path
    • doSave

      public CompletableFuture<Void> doSave(@Nonnull Path path, @Nonnull Supplier<CompletableFuture<Void>> saveFunc)
      Submits a save operation for the given path.

      Behavior depends on the current state:

      • If saving is locked and a save is already queued for this path, the save function is replaced with the new one (only the latest data will be written).
      • If an operation is currently in-flight for this path (save or loads), the new save is chained to execute after the current operation completes.
      • If saving is locked and no operation exists for this path, the save function is queued until saving is released.
      • Otherwise, the save executes immediately.
      Parameters:
      path - the file path to save to
      saveFunc - a supplier that performs the actual save and returns a future
      Returns:
      a future that completes when the save operation finishes
    • doLoad

      public <T> CompletableFuture<T> doLoad(@Nonnull Path path, @Nonnull Supplier<CompletableFuture<T>> loadFunc)
      Submits a load operation for the given path.

      If a save is pending or in-flight for this path, the load waits for it to complete before executing. Multiple loads for the same path run in parallel.

      Type Parameters:
      T - the type of data being loaded
      Parameters:
      path - the file path to load from
      loadFunc - a supplier that performs the actual load
      Returns:
      a future that completes with the loaded value
    • pendingOperations

      public CompletableFuture<Void> pendingOperations()
      Returns a future that completes when all currently in-flight save operations finish.

      This does not include saves that are queued but not yet started (i.e. saves waiting for the saving lock to be released), nor in-flight load operations.

      Returns:
      a future that completes when all in-flight saves finish
    • onSavingRelease

      public void onSavingRelease()
      Called when the saving lock is released to flush all queued saves.

      For each path with a queued save function, the function is invoked and the entry transitions from queued to in-flight.