///
///
import { RemoteConfig, RemoteConfigBase, SourceConfig, ArchiveFileInfo, ChangesAfterConfig } from "../IArchives";
export declare const ROUTING_FILE = "storage/storagerouting.json";
/** The variable-shard route override embedded in the key ("_", see VARIABLE_SHARD), or undefined when the key has no sentinel or the sentinel has no value yet. */
export declare function parseVariableRoute(key: string): number | undefined;
/** Where a key routes in [0, 1). A materialized variable-shard suffix completely overrides the hash. */
export declare function getRoute(key: string): number;
/** The in-memory getChangesAfter2 emulation, for backends without a native change feed: a full listing filtered down to files written after config.time whose keys route into config.routes. */
export declare function filterChanges(files: ArchiveFileInfo[], config: ChangesAfterConfig): ArchiveFileInfo[];
export declare function routeContains(route: [number, number] | undefined, value: number): boolean;
export declare function routesOverlap(a: [number, number] | undefined, b: [number, number] | undefined): boolean;
/** The overlap of two route ranges, or undefined when they don't overlap. */
export declare function routeIntersection(a: [number, number] | undefined, b: [number, number] | undefined): [number, number] | undefined;
export declare function getConfigVersion(config: RemoteConfig): number;
/** Strips the routing-file suffix, leaving the bucket's public base URL (file paths append to it). */
export declare function getBucketBaseUrl(url: string): string;
export declare function buildFileUrl(baseUrl: string, filePath: string): string;
export declare function parseHostedUrl(url: string): {
address: string;
port: number;
account: string;
bucketName: string;
};
export declare function parseBackblazeUrl(url: string): {
bucketName: string;
};
export declare function replaceHostedUrlPort(url: string, port: number): string;
/**
* Puts a source into the shape the code expects. It does NOT judge it: this runs every time a config
* is READ, and a config that is already on disk has to keep working - a server that cannot parse its
* own routing file is a server that cannot serve, and it would stay that way forever. Anything
* missing or unusable is filled in with the safest equivalent instead, loudly where it matters.
*
* Judging happens on the way IN, in assertValidRemoteConfig.
*/
export declare function normalizeSource(source: RemoteConfigBase): SourceConfig;
/** Puts a whole config into the shape the code expects, without judging it - see normalizeSource, and see assertValidRemoteConfig for the judging. */
export declare function normalizeRemoteConfig(config: RemoteConfig | RemoteConfigBase): RemoteConfig;
/**
* Whether a config may be WRITTEN. Everything here is a rule about the config as a whole, which is
* exactly why it cannot run on read: a config that is already stored somewhere has to keep being
* readable, or a server that once accepted a bad one could never start again. Rejecting it at the
* point it is introduced is what keeps a bad one from ever being stored in the first place.
*/
export declare function assertValidRemoteConfig(config: RemoteConfig): void;
/**
* The identity of one of a store's SOURCE SLOTS - which is the endpoint it talks to, and not the same
* question as which store this is (that is CommonConfig.name). A switchover's alternate port is a
* distinct slot even though it names the same storage, because a slot holds a connection to a port.
*
* ONLY the type, the url, and the intermediate's alternate port are part of it: everything else is
* policy about how we USE the endpoint, and changing policy must never make a store believe it is
* looking at a NEW source - that would drop every index entry the old one held and rescan it from
* scratch, so the files it holds go missing from listings until the rescan finishes, for a flag flip.
*
* Built by hand rather than by serializing the config, so it cannot change just because the routing
* file was written with its keys in a different order.
*/
export declare function sourceIdentity(sourceConfig: SourceConfig | undefined): string;
/** What an index entry records as the holder of its bytes (see ArchivesSource.url), so it must name the endpoint FOREVER. An intermediate is a switchover's temporary alternate port onto another source, and that port is gone for good once its window passes - so it is recorded as the source it was split out of, which holds the same bucket and outlives it. */
export declare function sourcePersistentUrl(sourceConfig: SourceConfig | undefined, folder: string): string;
/** Reads a stored routing config. NEVER throws: this runs on every READ of a stored config, and a torn/corrupt file must not brick the paths that would fix it - above all writeRoutingConfig, where throwing while reading the OLD config blocks the write of the NEW one forever. Unreadable data is logged and read as undefined - the same as the file not existing. Judging a config on its way IN is the writer's job (see assertValidRemoteConfig at the write entry points), where rejecting bad data with a throw is correct. */
export declare function parseRoutingData(data: Buffer): RemoteConfig | undefined;
export declare function serializeRemoteConfig(config: RemoteConfig): Buffer;