Pqax.Collector
0.2.2
Prefix Reserved
dotnet add package Pqax.Collector --version 0.2.2
NuGet\Install-Package Pqax.Collector -Version 0.2.2
<PackageReference Include="Pqax.Collector" Version="0.2.2" />
<PackageVersion Include="Pqax.Collector" Version="0.2.2" />
<PackageReference Include="Pqax.Collector" />
paket add Pqax.Collector --version 0.2.2
#r "nuget: Pqax.Collector, 0.2.2"
#:package Pqax.Collector@0.2.2
#addin nuget:?package=Pqax.Collector&version=0.2.2
#tool nuget:?package=Pqax.Collector&version=0.2.2
Pqax.Collector
Collects the footprint of Delta tables, and of folders of Parquet files with no table format, and writes it as a PQAX file. It reads the Delta log of each table and, at collection level 2, the footer of each Parquet file. It never reads row data, and it keeps no data value unless asked. The format is defined by the PQAX serialization and the PQAX object model; the file is written with the Pqax library.
| Targets | netstandard2.0 and net8.0 |
| Dependencies | Pqax. On netstandard2.0, the System.Text.Json package. No Parquet library: the collector parses footers itself. |
| Storage | A folder with the OneLake layout, OneLake through its DFS endpoint, or a container of Azure Data Lake Storage Gen2 through the same API, with GET requests only |
| Levels | 1, the Delta logs, and 2, also the Parquet footers |
| Checkpoints | Through an ICheckpointReader. Pqax.Collector.ParquetNet provides one with Parquet.Net. |
The package is not published yet. Reference the project src/dotnet/Pqax.Collector/Pqax.Collector.csproj.
Collect
using Pqax;
using Pqax.Collector;
using Pqax.Collector.ParquetNet;
var storage = new LocalStorage(@"conformance\fixtures\lakehouse"); // the folder plays the workspace
var tables = new List<TableLocation>();
foreach (string item in await TableDiscovery.ListItemsAsync(storage, CancellationToken.None))
{
tables.AddRange(await TableDiscovery.DiscoverAsync(storage, item, CancellationToken.None));
}
var collector = new PqaxCollector(storage, new CollectorOptions(), new ParquetNetCheckpointReader());
FootprintBuilder footprint = await collector.CollectAsync(tables, progress: null, CancellationToken.None);
footprint.Collection.CollectorApp = "MyTool";
footprint.Write("lakehouse.pqax");
For OneLake, the storage takes a delegate that returns an access token for the scope https://storage.azure.com/.default, so that the library does not depend on Azure.Identity. The application signs in with any TokenCredential of Azure.Identity, or gets the token another way:
// Azure.Identity, in the application: any TokenCredential.
TokenCredential credential = new ClientSecretCredential(tenantId, clientId, Environment.GetEnvironmentVariable("PQAX_CLIENT_SECRET"));
// or new ClientCertificateCredential(tenantId, clientId, "collector.pfx"), new ManagedIdentityCredential(ManagedIdentityId.SystemAssigned),
// new AzureCliCredential(), new DefaultAzureCredential(), new InteractiveBrowserCredential()
using var storage = new OneLakeStorage("My Workspace", async cancellation =>
(await credential.GetTokenAsync(new TokenRequestContext(new[] { OneLakeStorage.Scope }), cancellation)).Token);
IReadOnlyList<TableLocation> tables = await TableDiscovery.DiscoverAsync(storage, "Sales.Lakehouse", CancellationToken.None);
The delegate is called before every request. The credentials of Azure.Identity cache their tokens, but a delegate that calls another source should cache the token itself until shortly before it expires, as TokenCache of Pqax.Cli does. A token acquired elsewhere, such as the one of a notebook, is passed as it is: new OneLakeStorage("My Workspace", _ => Task.FromResult(token)).
A service principal or a managed identity needs the Fabric tenant setting that lets service principals use Fabric APIs, and a workspace role that reads OneLake: Contributor or higher works, and so does Viewer with the items shared with the principal; Viewer alone does not. The Pqax.Cli README has the details. A refused request is a StorageException with StatusCode 401 or 403 and IsAccessDenied true.
On a real workspace of 78 tables and 5,236 files, a collection at level 2 with every footer took 7,623 requests, one per footer, and wrote a 1.8 MB file. With a fixed 32 KB tail it read 177 MB in 2 minutes; with the adaptive tail it read 103 MB in 38 seconds, with the same output.
The workspace and the items are named both by name or both by id. OneLake answers 400 FriendlyNameSupportDisabled to a workspace id followed by item names.
A container of a storage account with hierarchical namespace, Azure Data Lake Storage Gen2, is read by the same class with the endpoint of the account: Azure Storage serves the DFS API that OneLake serves, with the container where OneLake has the workspace. The token is for the same scope, and the identity needs the role Storage Blob Data Reader on the container or the account. DiscoverFolderAsync finds the tables under a folder of the container, as Folders of a storage account says:
using var storage = new OneLakeStorage("lake", tokenProvider,
new OneLakeStorageOptions { Endpoint = new Uri("https://contoso.dfs.core.windows.net") }); // the container "lake"
IReadOnlyList<TableLocation> tables = await TableDiscovery.DiscoverFolderAsync(storage, "sales/curated", CancellationToken.None);
pqax collect in Pqax.Cli does both.
Public API
| Type | What it is |
|---|---|
PqaxCollector |
CollectAsync(tables, progress, cancellation) returns a FootprintBuilder with every table, its details, and the collection: library, times, level, requests, and bytes read |
CollectorOptions |
The options below. Validate() checks them; the constructor of the collector calls it. |
DetailDepth |
Summary, Files, RowGroups, ColumnChunks |
TableLocation |
A table to collect: format, source kind and name, namespace, name, folder in the storage, and the locations and identifiers to record. See Locations. |
TableFormats |
The formats of a table: Delta and Parquet |
TableDiscovery |
ListItemsAsync lists the lakehouses, warehouses, mirrored databases, and SQL databases at the root of a storage. DiscoverAsync finds the tables of one item: Tables/<table> or Tables/<schema>/<table>, by where _delta_log is. In a warehouse, every folder under Tables is a schema. DiscoverFolderAsync finds the Delta tables and the folders of Parquet files under a folder of any layout, such as a container of a storage account. |
SourceKinds |
The kinds of source: OneLake lakehouse, OneLake warehouse, Storage folder, and others |
CollectionProgress |
Reported each time a table is done |
IssueCodes |
The codes of the issues that the collector records |
IStorage, StorageEntry |
Read-only storage: ListAsync(path) and ReadRangeAsync(path, offset, length). A listing gives path, size, folder or file, and modification time. |
LocalStorage, OneLakeStorage, OneLakeStorageOptions |
The two storages. Both count their requests and bytes through IStorageStatistics. OneLakeStorage reads a container of a storage account with the endpoint of the account in OneLakeStorageOptions.Endpoint. |
StorageException |
A failed request, with its HTTP status when there is one: a timeout or a broken connection has none. The message never holds a path. |
StorageExtensions |
ReadAllAsync: a whole file in one request, with or without its size |
ICheckpointReader, DeltaAction and its kinds |
The contract of a checkpoint reader: AddAction, RemoveAction, MetadataAction, ProtocolAction, DomainMetadataAction, SidecarAction, CheckpointMetadataAction, and CommitInfoAction for commits |
FooterReader, ParquetFooter |
The footer parser, usable alone: FooterReader.ReadAsync(path, fileSize) reads the tail of a file, and ParquetFooter.Parse(bytes) decodes a FileMetaData |
ParquetSchemaElement, ParquetLeafColumn, ParquetRowGroup, ParquetColumnChunk, ParquetPageEncodingStats, ParquetKeyValue, ParquetSortingColumn |
What a footer holds |
ParquetFooterException |
A footer that cannot be read, with the issue code |
Options
| Option | Default | Meaning |
|---|---|---|
Level |
2 | 1 reads the Delta logs only. 2 also reads the Parquet footers. |
Depth |
ColumnChunks |
The detail kept for every table. A table keeps Summary when its files are unknown, and at most Files when no footer was read. |
MaxFootersPerTable |
0 | The footers read for each table, 0 for all. A limit picks files evenly over the files sorted by modification time, and the totals of level 2 cover the files read, as footerCount says. |
MaxCommitsPerTable |
30 | The commit files read for the history: operations and commits. The commits that the state needs are read anyway, so a table reads the greater of the limit and those. See Commits. |
Parallelism |
16 | The storage requests in flight, for the whole collection |
IncludeDataValues |
false | Keeps the bounds of the column chunks, the parameters of the operations, and the check constraints of the table properties |
IncludePartitionValues |
false | Keeps the values of the partitions and the file paths as the log has them. Without it, a value in a path becomes a number: Year=2024/part-1.parquet is written Year=#1/part-1.parquet. |
FooterTailBytes |
32768 | The bytes read from the end of the first file of a table, and the most read from any file in one request |
FooterTailMargin |
1.25 | The next files of a table are read with the largest footer seen so far times this factor. The footers of a table have about the same size, so one request per footer stays the rule while the bytes drop to what the footers take. |
FooterTailFloorBytes |
8192 | The fewest bytes read from the end of a file |
OneLakeStorageOptions sets how the storage connects:
| Option | Default | Meaning |
|---|---|---|
Endpoint |
https://onelake.dfs.fabric.microsoft.com |
The DFS endpoint: OneLake, a regional OneLake endpoint, or a storage account, https://<account>.dfs.core.windows.net. With a storage account, the first argument of the storage is the container, and the messages of a failed request name the storage account instead of OneLake. |
MaxRetries |
4 | The repeats of a request after 429, 500, 502, 503, 504, or a network failure |
HttpClient |
None | The client of the requests. Without one, the storage creates one and disposes it. |
Timeout |
5 minutes | The timeout of one request, when the storage creates its client |
Trace |
None | Receives one line for each answer: the URL and the status code |
What it reads
For each table:
| Request | When |
|---|---|
One listing of _delta_log |
Always. Its files give metadataFileCount and metadataSize, and _delta_log/_sidecars is listed too when it exists. |
_last_checkpoint |
When it exists. A hint only: the newest complete checkpoint of the listing is read. |
| The checkpoint | Through the checkpoint reader: a classic checkpoint, every part of a multi-part checkpoint, a v2 checkpoint in Parquet, or in JSON, which the collector reads itself, and its sidecar files |
| The commits that the state needs | One request each, replayed into the state: the commits after the checkpoint, or every commit when the state comes from the JSON commits alone |
| Older commits | One request each, for the history, the most recent first, until the commit files read reach MaxCommitsPerTable. See Commits. |
| One listing of the table folder, at any depth | When the files of the version are known, at every level. OneLakeStorage lists with recursive=true, in as many pages as the listing takes, and LocalStorage counts one request. Through another storage, each folder is a listing of its own, and _delta_log and _change_data are not listed. It gives unreferencedFileCount and unreferencedFileSize. See Unreferenced files. |
| The footer of each file | At level 2: the last FooterTailBytes bytes, and a second request only for a longer footer |
For a folder of Parquet files, the format Parquet, there is no log: one listing of the folder gives the files, the footer of the most recent file gives the columns at every level, and at level 2 every other footer is read too, the first one not again. See Folders of Parquet files.
Every request goes through the IStorage, so the collection states its requests and bytes. When the storage implements IStorageStatistics, those numbers come from it and include retries and the pages of a listing.
The log is replayed by the rules of the Delta protocol: a file is identified by its path and its deletion vector, and the latest action wins. A table whose checkpoint is not read keeps what the JSON commits say: when the log still has every commit from version 0, the collector replays them and the table is complete; otherwise its files are unknown, its file totals are null, it gets the issue DeltaCheckpointNotRead, and it has the Summary depth.
Commits
The collector chooses the commit files to read from the latest version back:
- Every commit that the state needs: those after the checkpoint, or all of them when the state comes from the JSON commits alone. The limit does not apply to them.
- Then older commits, the most recent first, until the commit files read reach
MaxCommitsPerTableor the log has no older one.
So a table reads the greater of the limit and the commits that the state needs, within the commits that the log keeps. A limit of 0 reads only the commits that the state needs. commitsRead is the number of commit files read. The commits of the table, kept from the Files depth, hold every one of them, and the operations and oldestCommitAt cover them all. A commit file whose read fails counts toward the limit, since it cost a request, and gets an issue instead of a place in commitsRead and in the commits.
| Limit | Checkpoint | Latest version | Commit files in the log | Commits read |
|---|---|---|---|---|
| 30 | 100 | 145 | 0 to 145 | 45: 101 to 145 |
| 0 | 100 | 145 | 0 to 145 | 45: 101 to 145 |
| 50 | 100 | 145 | 0 to 145 | 50: 96 to 145 |
| 60 | 100 | 145 | 90 to 145 | 56: 90 to 145 |
| 30 | None | 39 | 0 to 39 | 40: 0 to 39 |
What the footprint holds
The collector fills every field of the object model that a Delta table and its footers give, and follows the rule that unknown is not zero: a value that was not read is null, a total with an unknown term is null, and a known empty list is empty.
| Object | From |
|---|---|
| Source | The TableLocation of its tables: kind, name, location, and identifiers. See Locations. |
| Table | The TableLocation for the location, then metaData, protocol, the domains, the listings, the history, and totals over the files, the footers, and the row groups. fileSizes, rowGroupRowCounts, and partitionSizes are distributions with quartiles taken by position in the sorted values. nonLiveOldestRemovedAt and nonLiveNewestRemovedAt are the earliest and the latest remove.deletionTimestamp of the files that nonLiveFileCount counts. |
| Column | schemaString: name, type as Spark writes it in DDL, nullability, field id and physical name of column mapping, comment. Totals over the column chunks of the footers read, or at level 1 the null count of the statistics of the log, when every file has one. |
| Partition spec and partitions | partitionColumns and add.partitionValues, by physical name with column mapping. lastModifiedAt of a partition is the latest add.modificationTime of its files, and null when one of them has none, as for the table. |
| Physical schema and physical column | The schemas of the footers. A leaf maps to a column by the field id of its top-level field when the table has field ids, and otherwise by the physical name, or the name. |
| Writer | created_by, and V-Order from the VORDER tag of the file or the footer keys |
| Operation and commit | commitInfo of the commits read: time, operation, engine, blind append, metrics. Never a user name, a notebook, or a cluster. |
| File, row group, column chunk | The log and the footers, from the depth that keeps them. The encodings of a column chunk are sorted. |
| Issue | What went wrong, with a code. A table keeps 100 issues, and one more counts the rest. |
Partitions and commits are kept from the Files depth, as in the prototype.
Unreferenced files
| Rule | Detail |
|---|---|
| Data file | A file of the listing of the table folder, at any depth, whose name ends with .parquet, in any case, outside _delta_log and _change_data |
| Referenced | Its path relative to the table folder equals the decoded path of a live file of the version. An absolute path of the log that starts with the table location is compared without it. The comparison is case-sensitive. |
| Unreferenced | Every other data file: removed files that a VACUUM has not deleted yet, and files that no commit referenced, such as those of an aborted write |
| Size | The sum of the sizes that the listing gives. A file without a size counts in unreferencedFileCount only. |
| Unknown | Both fields are null when the files of the version are unknown, and when the listing fails, which is then an issue: AccessDenied or DataFilesNotListed |
Locations
TableDiscovery fills the location of each table, and the location and the identifiers of its source, from the storage and from the item as the caller names it.
| Storage | Source location |
Table location |
Source identifiers |
|---|---|---|---|
OneLakeStorage, by names |
abfss://<workspace>@<host>/<item>, such as abfss://My Workspace@onelake.dfs.fabric.microsoft.com/Sales.Lakehouse |
The source location, then /Tables/<table>, or /Tables/<schema>/<table> |
None |
OneLakeStorage, by ids |
abfss://<workspace id>@<host>/<item id> |
The same | workspaceId and itemId |
LocalStorage |
The full path of the item folder, with the separators of the platform, such as C:\data\Sales.Lakehouse |
The full path of the table folder | None |
OneLakeStorage on a storage account, through DiscoverFolderAsync |
abfss://<container>@<host>/<folder>, such as abfss://lake@contoso.dfs.core.windows.net/sales |
The source location, then the folders down to the table | None. See Folders of a storage account. |
| Another storage, or a storage that wraps one of these | None | None | None |
- The workspace and the item are written as the caller gave them, without escaping.
<host>is the host of the endpoint,onelake.dfs.fabric.microsoft.comby default. - An identifier is recorded only for a workspace or an item given as an id: a GUID with hyphens. A listing of the DFS endpoint has no item id, so with names the identifiers stay
null: the collector does not guess them. - The tables with the same source kind, name, and location share one source. A
TableLocationbuilt by hand records what its constructor is given. - A local location is a full path, so it can hold the name of the user of the machine. The object model marks the locations and the identifiers as names, for the obfuscation to replace.
Folders of a storage account
TableDiscovery.DiscoverFolderAsync(storage, folder, maxDepth) walks a folder of a storage that has no item layout, such as a container of Azure Data Lake Storage Gen2, with one listing for each folder walked:
| Rule | Detail |
|---|---|
| Delta table | A folder that holds _delta_log. The walk does not enter it. |
| Parquet table | A folder with at least one Parquet file and no subfolder. A Parquet file is a file whose name ends with .parquet, in any case. |
| Hidden | Files and folders whose name starts with _ or ., such as _SUCCESS and _temporary, as Spark writes them. A hidden folder does not count as a subfolder, and none is walked. |
| Partition | A folder whose name holds =, such as year=2024, is not walked: a partitioned folder of Parquet files is not read in this version, and gives no table |
| Depth | The folder itself is level 0 and may be a table. maxDepth, by default TableDiscovery.DefaultFolderDepth, 4, is the deepest level tested. A deeper table is found by starting from a deeper folder. |
| Other folders | Walked while they are above maxDepth. An empty folder, a folder of other files, and a folder that does not exist give no table. |
| Order | Depth first, by ordinal name, so the tables come sorted by path |
Every table it finds has one source:
| Field | Value |
|---|---|
Source kind |
Storage folder |
Source name |
The last segment of the folder, or the container for its root |
Source location |
abfss://<container>@<host>/<folder>, such as abfss://lake@contoso.dfs.core.windows.net/sales/curated; the full path on disk on a LocalStorage |
Source identifiers |
None: a storage account assigns no id to a folder |
Table namespace |
The folders between the folder and the table, empty for a table directly under it |
Table name |
The last segment of the table folder. When the folder is itself a table, its name, with no namespace. |
Table location |
The location of the table folder, in the same form as the source location |
Folders of Parquet files
A table of the format Parquet has no log, so the footprint holds what the files and their footers say:
| Field | Value |
|---|---|
| Files | The Parquet files directly in the folder, by name, with the size and the modification time of the listing. fileCount, fileSize, fileSizes, and lastModifiedAt come from them. |
| Columns | The top-level fields of the footer of the most recent file, by modification time and then by name, as the object model says. The type is written with the names of the Delta schema, such as long, string, decimal(18,2), timestamp, array<string>, so that it compares with a Delta table. A column is nullable when its field is optional. |
| Rows | From the footers, at level 2. At level 1 the row count is unknown. |
| Level 1 | Reads the footer of the most recent file for the columns only: footerCount is 0 and the depth is at most Files |
| Level 2 | Reads every footer, or MaxFootersPerTable of them: the sample of the limit, where the most recent file takes the place of the last file when the sample leaves it out |
unreferencedFileCount, unreferencedFileSize |
0: every Parquet file of the folder is a file of the table |
tableId, snapshotId, delta, the commits, the operations, the metadata files, the non-live files |
None: there is no table format to give them |
Issues
| Code | When |
|---|---|
AccessDenied |
The storage denied access, with status 401 or 403, to a folder, a commit, or the footer of a file. On the listing of the table folder, unreferencedFileCount and unreferencedFileSize are null. |
TableNotRead |
The table could not be read for another reason |
DeltaLogMissing |
The table folder has no Delta log |
DeltaLogIncomplete |
Commits that the state needs are missing |
DeltaCheckpointNotRead |
The checkpoint was not read. See above. |
DeltaCheckpointMissing |
_last_checkpoint names a checkpoint that the log does not have |
DeltaCommitNotRead |
A commit file could not be read or parsed |
DeltaSchemaNotParsed |
schemaString is not valid |
DeltaStatsNotParsed |
The statistics of some files are not valid JSON |
DataFilesNotListed |
The listing of the table folder for its data files failed for another reason than a denied access; unreferencedFileCount and unreferencedFileSize are null |
FileOutsideTable |
A file has an absolute path, so its footer was not read |
FooterNotRead |
The read of a footer failed for another reason than a denied access, or the log gives no size |
FooterEncrypted |
The footer is encrypted: the file ends with PARE |
FooterInvalid |
Not a valid Parquet footer, or the file is shorter than the log says |
FooterTooLarge |
The footer is larger than 64 MB |
FooterColumnsEncrypted |
Column chunks have no metadata because their columns are encrypted; the footer counts as not read |
IssuesTruncated |
The table had more than 100 issues |
Footer read failures
A footer that cannot be read becomes an issue with the path of its file, and the collection goes on. The code depends on the failure:
| Status or failure | Code | Effect on the totals |
|---|---|---|
| 401 or 403 | AccessDenied |
The footer counts as not read: footerCount and the totals of level 2 leave out the file and its row groups and column chunks, and the file keeps what the log says |
| 404, another status after the retries, a timeout, a broken connection, or an error of a local file | FooterNotRead |
The same |
| 416, or fewer bytes than the log says | FooterInvalid |
The same |
| Bytes that are not a valid footer | FooterInvalid, FooterEncrypted, or FooterTooLarge |
The same |
| Column chunks with no metadata | FooterColumnsEncrypted |
The same |
| No size in the log, or a file outside the table | FooterNotRead or FileOutsideTable |
The same, with no request |
| Any other exception | FooterNotRead |
The same |
A table with files and no footer read has the collection level 1 and at most the Files depth.
Footer parser
The parser reads the Thrift compact protocol: field headers with short and long deltas, booleans in the header, zigzag varints, doubles, binaries, lists, sets, maps, structures, and UUIDs. It skips a field that it does not know, of any type, and a known field with an unexpected type. It decodes FileMetaData, SchemaElement with its logical and converted types, RowGroup, ColumnChunk, ColumnMetaData, Statistics, PageEncodingStats, SizeStatistics, the bloom filter, column index, and offset index lengths, and the key-value metadata.
| Kept | Dropped without allocating |
|---|---|
| Null and distinct counts, and whether the statistics have bounds | The bounds, unless the footer is parsed with data values; then they are kept as text |
The keys of the key-value metadata, with the value for keys that contain vorder, the key org.apache.spark.version, and keys that end with string_prefix_length, up to 200 characters |
The values of other keys, which can hold data values: Fabric copies the statistics of the log into the footer |
| The schema, once | path_in_schema of every column chunk, column-level key-value metadata, the level histograms, geospatial statistics, column orders, and the encryption details |
It refuses an encrypted footer (PARE), a file that does not end with PAR1, a footer length that does not fit the file, a footer over 64 MB, a required field that is missing, a row group whose column chunks do not match the leaves of the schema, and any length or count that goes beyond the bytes left. It never throws anything but ParquetFooterException on bad bytes.
Limits
- Collection levels 3 and 4 and Iceberg tables are not supported in this version.
- A folder of Parquet files is read only when its files are directly in it: a partitioned folder, with
<column>=<value>subfolders, gives no table. Its partition values would come from the paths, which this version does not read. DiscoverFolderAsyncstops at 4 levels below its folder by default. A container with many folders above its tables costs one listing for each.- A storage account is read through its DFS endpoint, which needs hierarchical namespace. A flat Blob Storage account, Amazon S3, and Databricks volumes are not supported in this version.
- A checkpoint larger than 512 MB is not read.
- The log compaction files,
<x>.<y>.compacted.json, are counted with the log and not used. - All the files of a table are kept in memory until the footprint is built, as row objects in the builder.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Pqax (>= 0.2.2)
- System.Text.Json (>= 8.0.5)
-
net8.0
- Pqax (>= 0.2.2)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Pqax.Collector:
| Package | Downloads |
|---|---|
|
Pqax.Collector.ParquetNet
Reads Delta checkpoints, which are Parquet files with nested data, with Parquet.Net, for the PQAX collector. |
GitHub repositories
This package is not used by any popular GitHub repositories.