Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File URL Refactor #235

Merged
merged 2 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,35 @@ extension DiskPersistence.Datastore.Index {
case direct(index: DatastoreIndexIdentifier, manifest: DatastoreIndexManifestIdentifier)
case secondary(index: DatastoreIndexIdentifier, manifest: DatastoreIndexManifestIdentifier)

var indexID: DatastoreRootManifest.IndexID {
switch self {
case .primary(_): .primary
case .direct(let id, _): .direct(index: id)
case .secondary(let id, _): .secondary(index: id)
}
}

var manifestID: DatastoreIndexManifestIdentifier {
switch self {
case .primary(let id),
.direct(_, let id),
.secondary(_, let id):
return id
case .primary(let id): id
case .direct(_, let id): id
case .secondary(_, let id): id
}
}

func with(manifestID: DatastoreIndexManifestIdentifier) -> Self {
switch self {
case .primary: return .primary(manifest: manifestID)
case .direct(let indexID, _): return .direct(index: indexID, manifest: manifestID)
case .secondary(let indexID, _): return .secondary(index: indexID, manifest: manifestID)
case .primary: .primary(manifest: manifestID)
case .direct(let indexID, _): .direct(index: indexID, manifest: manifestID)
case .secondary(let indexID, _): .secondary(index: indexID, manifest: manifestID)
}
}

init(_ id: DatastoreRootManifest.IndexManifestID) {
switch id {
case .primary(let manifest): self = .primary(manifest: manifest)
case .direct(let index, let manifest): self = .direct(index: index, manifest: manifest)
case .secondary(let index, let manifest): self = .secondary(index: index, manifest: manifest)
}
}
}
Expand All @@ -91,9 +106,7 @@ extension DiskPersistence.Datastore.Index {
extension DiskPersistence.Datastore.Index {
/// The URL that points to the manifest.
nonisolated var manifestURL: URL {
datastore
.manifestsURL(for: id)
.appendingPathComponent("\(id.manifestID).indexmanifest", isDirectory: false)
datastore.manifestURL(for: id)
}
}

Expand Down Expand Up @@ -129,7 +142,7 @@ extension DiskPersistence.Datastore.Index {
}

/// Make sure the directories exists first.
try FileManager.default.createDirectory(at: datastore.manifestsURL(for: id), withIntermediateDirectories: true)
try FileManager.default.createDirectory(at: datastore.manifestsURL(for: id.indexID), withIntermediateDirectories: true)

/// Encode the provided manifest, and write it to disk.
let data = Data(manifest.bytes)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,7 @@ extension DiskPersistence.Datastore.Page {
extension DiskPersistence.Datastore.Page {
/// The URL that points to the page.
nonisolated var pageURL: URL {
let baseURL = datastore.pagesURL(for: id.index)

guard let components = try? id.page.components else { preconditionFailure("Components could not be determined for Page.") }

return baseURL
.appendingPathComponent(components.year, isDirectory: true)
.appendingPathComponent(components.monthDay, isDirectory: true)
.appendingPathComponent(components.hourMinute, isDirectory: true)
.appendingPathComponent("\(id.page).datastorepage", isDirectory: false)
datastore.pageURL(for: id)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ extension DiskPersistence.Datastore.RootObject: Hashable {
extension DiskPersistence.Datastore.RootObject {
/// The URL that points to the root object on disk.
nonisolated var rootObjectURL: URL {
datastore.rootURL.appendingPathComponent("\(id).json", isDirectory: false)
datastore.rootURL(for: id)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,21 @@ extension DatastoreRootManifest {
self = .secondary(index: index, manifest: manifest)
}
}

var indexID: DatastoreRootManifest.IndexID {
switch self {
case .primary(_): .primary
case .direct(let id, _): .direct(index: id)
case .secondary(let id, _): .secondary(index: id)
}
}

var manifestID: DatastoreIndexManifestIdentifier {
switch self {
case .primary(let id): id
case .direct(_, let id): id
case .secondary(_, let id): id
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ extension DiskPersistence {
extension DiskPersistence.Datastore {
/// The URL that points to the Datastore directory.
nonisolated var datastoreURL: URL {
snapshot
.datastoresURL
.appendingPathComponent("\(id).datastore", isDirectory: true)
snapshot.datastoreURL(for: id)
}

/// The URL that points to the Root directory.
Expand All @@ -68,40 +66,62 @@ extension DiskPersistence.Datastore {
.appendingPathComponent("Root", isDirectory: true)
}

/// The URL for the specified root.
nonisolated func rootURL(for id: DatastoreRootIdentifier) -> URL {
rootURL.appendingPathComponent("\(id).json", isDirectory: false)
}

/// The URL that points to the DirectIndexes directory.
nonisolated var directIndexesURL: URL {
datastoreURL
.appendingPathComponent("DirectIndexes", isDirectory: true)
datastoreURL.appendingPathComponent("DirectIndexes", isDirectory: true)
}

/// The URL that points to the SecondaryIndexes directory.
nonisolated var secondaryIndexesURL: URL {
datastoreURL
.appendingPathComponent("SecondaryIndexes", isDirectory: true)
datastoreURL.appendingPathComponent("SecondaryIndexes", isDirectory: true)
}

nonisolated func indexURL(for indexID: Index.ID) -> URL {
/// The root URL of a partifular index directory.
nonisolated func indexURL(for indexID: DatastoreRootManifest.IndexID) -> URL {
switch indexID {
case .primary:
return directIndexesURL
.appendingPathComponent("Primary.datastoreindex", isDirectory: true)
case .direct(let indexID, _):
return directIndexesURL
.appendingPathComponent("\(indexID).datastoreindex", isDirectory: true)
case .secondary(let indexID, _):
return secondaryIndexesURL
.appendingPathComponent("\(indexID).datastoreindex", isDirectory: true)
directIndexesURL.appendingPathComponent("Primary.datastoreindex", isDirectory: true)
case .direct(let indexID):
directIndexesURL.appendingPathComponent("\(indexID).datastoreindex", isDirectory: true)
case .secondary(let indexID):
secondaryIndexesURL.appendingPathComponent("\(indexID).datastoreindex", isDirectory: true)
}
}

nonisolated func manifestsURL(for indexID: Index.ID) -> URL {
indexURL(for: indexID)
.appendingPathComponent("Manifest", isDirectory: true)
/// The URL of an index's manifests directory.
nonisolated func manifestsURL(for id: DatastoreRootManifest.IndexID) -> URL {
indexURL(for: id).appendingPathComponent("Manifest", isDirectory: true)
}

/// The URL of an index's root manifest.
nonisolated func manifestURL(for id: Index.ID) -> URL {
manifestURL(for: DatastoreRootManifest.IndexManifestID(id))
}

nonisolated func pagesURL(for indexID: Index.ID) -> URL {
indexURL(for: indexID)
.appendingPathComponent("Pages", isDirectory: true)
/// The URL of an index's root manifest.
nonisolated func manifestURL(for id: DatastoreRootManifest.IndexManifestID) -> URL {
manifestsURL(for: id.indexID).appendingPathComponent("\(id.manifestID).indexmanifest", isDirectory: false)
}

/// The URL of an index's pages directory..
nonisolated func pagesURL(for id: Index.ID) -> URL {
indexURL(for: id.indexID).appendingPathComponent("Pages", isDirectory: true)
}

/// The URL of a particular page.
nonisolated func pageURL(for id: Page.ID) -> URL {
guard let components = try? id.page.components else { preconditionFailure("Components could not be determined for Page.") }

return pagesURL(for: id.index)
.appendingPathComponent(components.year, isDirectory: true)
.appendingPathComponent(components.monthDay, isDirectory: true)
.appendingPathComponent(components.hourMinute, isDirectory: true)
.appendingPathComponent("\(id.page).datastorepage", isDirectory: false)
}
}

Expand Down Expand Up @@ -198,7 +218,7 @@ extension DiskPersistence.Datastore {
extension DiskPersistence.Datastore {
/// Load the root object from disk for the given identifier.
func loadRootObject(for rootIdentifier: DatastoreRootIdentifier) throws -> DatastoreRootManifest {
let rootObjectURL = rootURL.appendingPathComponent("\(rootIdentifier).json", isDirectory: false)
let rootObjectURL = rootURL(for: rootIdentifier)

let data = try Data(contentsOf: rootObjectURL)

Expand All @@ -218,7 +238,7 @@ extension DiskPersistence.Datastore {
try FileManager.default.createDirectory(at: secondaryIndexesURL, withIntermediateDirectories: true)
}

let rootObjectURL = rootURL.appendingPathComponent("\(manifest.id).json", isDirectory: false)
let rootObjectURL = rootURL(for: manifest.id)

/// Encode the provided manifest, and write it to disk.
let data = try JSONEncoder.shared.encode(manifest)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ extension Snapshot {
snapshotURL.appendingPathComponent("Datastores", isDirectory: true)
}

/// The URL for a specific datastore within the snapshot.
nonisolated func datastoreURL(for id: DatastoreIdentifier) -> URL {
datastoresURL.appendingPathComponent("\(id).datastore", isDirectory: true)
}

/// The URL that points to the Inbox directory.
nonisolated var inboxURL: URL {
snapshotURL.appendingPathComponent("Inbox", isDirectory: true)
Expand Down Expand Up @@ -316,13 +321,11 @@ private enum SnapshotTaskLocals {
extension Snapshot {
/// Load the datastore for the given key.
func loadDatastore(for key: DatastoreKey, from iteration: SnapshotIteration) -> (DiskPersistence<AccessMode>.Datastore, DatastoreRootIdentifier?) {
let datastoreInfo: (id: DatastoreIdentifier, root: DatastoreRootIdentifier?) = {
if let info = iteration.dataStores[key] {
return (info.id, info.root)
} else {
return (DatastoreIdentifier(name: key.rawValue), nil)
}
}()
let datastoreInfo = if let info = iteration.dataStores[key] {
(id: info.id, root: info.root)
} else {
(id: DatastoreIdentifier(name: key.rawValue), root: DatastoreRootIdentifier?.none)
}

if let datastore = datastores[datastoreInfo.id] {
return (datastore, datastoreInfo.root)
Expand Down
Loading