Documentation
¶
Overview ¶
Package ccrawl is a Go library for working with Common Crawl data: the collection list, the CDX URL index, WARC/WAT/WET archive files, the columnar Parquet index, CC-NEWS, and the host/domain ranks. It is the engine behind the ccrawl command line tool but is usable on its own.
Index ¶
- Constants
- Variables
- func AggregateCDXRaw(ctx context.Context, workDir string, prefixes []string, parallel int, ...) error
- func BM25IDF(N, df int) float64
- func BM25TF(tf, dl int, avgDL float64, p BM25Params) float64
- func BuildDatasetShard(ctx context.Context, prefix, workDir, crawlID, graphID, outPath string, ...) (int64, error)
- func BuildDatasetShardFromChunk(ctx context.Context, prefix, workDir, crawlID, graphID, outPath string, ...) (int64, error)
- func CDXBatchPath(workDir, prefix string, chunk int) string
- func CDXNumPages(ctx context.Context, h *HTTPClient, crawlID string, q CDXQuery) (int, error)
- func CDXSeqLocalSQL(localPath, prefix string) string
- func CDXStream(ctx context.Context, h *HTTPClient, crawlID string, q CDXQuery, ...) error
- func CanonicalURL(raw string) string
- func ColumnarParquetURLs(ctx context.Context, h *HTTPClient, cache *Cache, crawlID, subset string, ...) ([]string, error)
- func ColumnarSource(crawlID, subset string, src Source) string
- func ComputeEdgeDegrees(ctx context.Context, h *HTTPClient, manifestURL string, nodeCount int64) (inDeg, outDeg []int32, err error)
- func ConfigDir() string
- func ContentSHA1(content []byte) string
- func CrawlScore(harmonicVal, changeRate float64) float64
- func CrawlTier(harmonicPos int64, changeRate float64) int
- func DatasetPrefixReady(workDir, prefix string) bool
- func DatasetWorkFiles(workDir, prefix string) (cdxFile, rankFile string)
- func DecodeVarInt(b []byte) (uint64, int)
- func DiffCDX(ctx context.Context, urlsA, urlsB []string, crawlA, crawlB string, ...) error
- func DiffCDXSQL(urlsA, urlsB []string, crawlA, crawlB string) string
- func DocumentID(canonicalURL string) uint64
- func DownloadFiles(ctx context.Context, h *HTTPClient, src Source, paths []string, ...) error
- func DownloadRankTable(ctx context.Context, rankURL, localPath string) error
- func DownloadToFile(ctx context.Context, h *HTTPClient, url, localPath string) error
- func DuckDBAvailable() bool
- func EncodeVarInt(v uint64) []byte
- func ExtractCDXBatch(ctx context.Context, h *HTTPClient, batchURLs []string, workDir string, ...) error
- func ExtractCDXRaw(ctx context.Context, h *HTTPClient, parquetURLs []string, workDir string, ...) error
- func ExtractMarkdown(body []byte) (string, error)
- func ExtractOutLinks(htmlBytes []byte, baseURL string) []string
- func ExtractText(body []byte) string
- func ExtractTitle(body []byte) string
- func FetchPaths(ctx context.Context, h *HTTPClient, cache *Cache, crawlID, kind string) ([]string, error)
- func FetchWARCRecordRaw(ctx context.Context, h *HTTPClient, filename string, offset, length int64) ([]byte, error)
- func FileLimit() uint64
- func FileURL(path string, src Source) string
- func GenerateDatasetREADME(s DatasetStats) string
- func GenerateMarkdownREADME(s MarkdownDatasetStats) string
- func HFMarkdownPath(crawlID string, shardIdx int) string
- func HFRefetchPath(crawlID string, shardIdx int) string
- func HFShardPath(crawlID, subset, prefix string) string
- func HFShardPathChunk(crawlID, subset, prefix string, chunk int) string
- func HTMLCanonicalURL(htmlBytes []byte) string
- func HTTPBody(block []byte) []byte
- func HTTPHeaders(block []byte) []byte
- func HTTPSURL(path string) string
- func HarmonicTier(harmonicPos int64, totalHosts int64) int
- func HostCDXAgg(ctx context.Context, parquetURLs []string, crawlID, host string, ...) error
- func HostCDXAggSQL(parquetURLs []string, crawlID, host string) string
- func HostCDXBatchSQL(parquetURLs []string, crawlID string, prefixes []string, ...) string
- func HostCDXPrefixSQL(parquetURLs []string, crawlID, prefix, tempDir string) string
- func HostCDXSingleSQL(parquetURLs []string, crawlID, host string) string
- func HostOf(raw string) string
- func InferMatchType(pattern string) (cleanURL, matchType string)
- func IterateWARC(r io.Reader, fn func(WARCRecord) error) error
- func IterateWAT(r io.Reader, crawlID string, fn func(WATRecord) error) error
- func IterateWET(r io.Reader, crawlID string, fn func(WETRecord) error) error
- func LibraryDir() string
- func LinkBoost(bm25Score, harmonicVal, alpha float64) float64
- func LoadCDXRawChunk(workDir, prefix string, chunk int, fn func(CDXRawOutputRow) error) error
- func LoadCDXRawPrefix(workDir, prefix string, fn func(CDXRawOutputRow) error) error
- func MarkdownDocID(rawURL string) string
- func NormalizeURL(raw string) string
- func ParquetListLiteral(urls []string) string
- func RaiseFileLimit() (uint64, error)
- func RankStream(ctx context.Context, h *HTTPClient, url, tld string, fn func(Rank) error) error
- func ResolveCrawl(ctx context.Context, h *HTTPClient, cache *Cache, ref string) (string, error)
- func ResolveCrawls(ctx context.Context, h *HTTPClient, cache *Cache, ref string) ([]string, error)
- func RunColumnarDuckDB(ctx context.Context, sql string, emit func(map[string]any) error) error
- func RunDuckDBJSON(ctx context.Context, dbPath, sql string, emit func(map[string]any) error) error
- func SURT(raw string) string
- func SaveCDXBatchByPrefix(ctx context.Context, parquetURLs []string, crawlID, workDir string, ...) (map[string]int64, error)
- func SaveCDXSeqByPrefix(ctx context.Context, h *HTTPClient, parquetURLs []string, ...) error
- func SaveCDXSplitByPrefix(ctx context.Context, parquetURLs []string, crawlID, workDir string, ...) (map[string]int64, error)
- func SplitRankByPrefix(ctx context.Context, h *HTTPClient, rankURL, workDir string, ...) (map[string]int64, error)
- func SplitRankFromFile(ctx context.Context, localPath, workDir string, progress func(total int64)) (map[string]int64, error)
- func StreamPaths(ctx context.Context, h *HTTPClient, crawlID, kind string, ...) error
- func StripTrackingParams(rawQuery string) string
- func TierBoost(tier int) float64
- func TierInterval(tier int) int
- func Tokenize(text string) []string
- func VertexStream(ctx context.Context, h *HTTPClient, manifestURL string, ...) error
- func WriteWARCResponse(w io.Writer, rec NewWARCRecord) error
- type APIServer
- type BM25Params
- type CDXBatchOptions
- type CDXQuery
- type CDXRawOutputRow
- type CDXRawRow
- type CDXRecord
- type Cache
- type ColumnarQuery
- type Config
- type Crawl
- type CrawlConfig
- type CrawlResult
- type DatasetStats
- type DownloadResult
- type EdgeDegrees
- type ForwardDoc
- type ForwardIndexWriter
- type Frontier
- type FrontierEntry
- type HFClient
- func (c *HFClient) CommitWithRetry(ctx context.Context, repoID, message string, ops []HFOperation, ...) (string, error)
- func (c *HFClient) CreateCommit(ctx context.Context, repoID, message string, ops []HFOperation) (string, error)
- func (c *HFClient) CreateDatasetRepo(ctx context.Context, repoID string, private bool) error
- func (c *HFClient) PathsExist(ctx context.Context, repoID string, paths []string) (map[string]bool, error)
- func (c *HFClient) Valid() bool
- type HFOperation
- type HTTPClient
- func (h *HTTPClient) FetchBytes(ctx context.Context, url string) ([]byte, error)
- func (h *HTTPClient) Get(ctx context.Context, url string) (*http.Response, error)
- func (h *HTTPClient) GetDownload(ctx context.Context, url string) (*http.Response, error)
- func (h *HTTPClient) GetRange(ctx context.Context, url string, offset, length int64) (*http.Response, error)
- type HostCDXStats
- type HostDatasetRow
- type HostDiffEntry
- type HostRecord
- type HostSchedule
- type HostStore
- type IndexReader
- type IndexSearchStore
- type InvertedIndexBuilder
- type Ledger
- type Library
- type Location
- type MarkdownDatasetStats
- type MarkdownExportConfig
- type MarkdownPackConfig
- type MarkdownRow
- type MarkdownRunStats
- type MarkdownStats
- type MemHostStore
- type NewWARCRecord
- type NewsFile
- type ParquetWriter
- type PostingEntry
- type QualityResult
- type Rank
- type RateLimitError
- type RefetchDatasetStats
- type RefetchExportConfig
- type RefetchPackConfig
- type RefetchRow
- type RefetchRunStats
- type RefetchStats
- type RobotsCache
- type RobotsEntry
- type RobotsRule
- type ScoredDoc
- type SearchResult
- type SearchStore
- type SeedExportOptions
- type SeedExportStats
- type SeedRow
- type ServeConfig
- type Source
- type StreamingParquetWriter
- type TextResult
- type URLDatasetRow
- type VertexRecord
- type WARCExporter
- type WARCHeader
- type WARCInfo
- type WARCParquetRow
- type WARCRecord
- type WARCURLRecord
- type WATLink
- type WATMeta
- type WATParquetRow
- type WATRecord
- type WETParquetRow
- type WETRecord
- type WebGraph
Constants ¶
const ( CollInfoURL = "https://index.commoncrawl.org/collinfo.json" DataBaseURL = "https://data.commoncrawl.org/" CDXBaseURL = "https://index.commoncrawl.org/" S3BaseURL = "s3://commoncrawl/" // ColumnarPrefix is the root of the columnar (Parquet) index. ColumnarPrefix = "cc-index/table/cc-main/warc/" // UserAgent identifies the client politely to Common Crawl's CDN. UserAgent = "ccrawl/1.0 (+https://github.com/tamnd/ccrawl-cli)" )
Common Crawl endpoints.
const ( DefaultTimeout = 120 * time.Second DefaultRetries = 5 DefaultDelay = 200 * time.Millisecond )
Defaults for the client and downloader.
const DefaultWARCSize int64 = 1 << 30
DefaultWARCSize is the target size a single exported WARC file grows to before the exporter rotates to the next one. It matches cdx_toolkit's 1 GB default.
const DuckDBPrelude = "INSTALL httpfs; LOAD httpfs; SET enable_progress_bar=false;"
DuckDBPrelude is prepended to every statement ccrawl sends to the duckdb binary. httpfs reads remote Parquet over HTTPS; the progress bar is noise on a pipe.
Variables ¶
var DatasetPrefixes = func() []string { out := make([]string, 0, 28) for c := 'a'; c <= 'z'; c++ { out = append(out, string(c)) } out = append(out, "0", "misc") return out }()
DatasetPrefixes is the ordered set of shard prefix keys. Letters a-z, "0" for digit-initial hosts, "misc" for everything else.
var DefaultBM25Params = BM25Params{K1: 1.2, B: 0.75}
DefaultBM25Params are the standard Okapi BM25 defaults.
var DefaultColumnarColumns = []string{
"url", "url_host_registered_domain", "fetch_status",
"content_mime_detected", "content_languages",
"warc_filename", "warc_record_offset", "warc_record_length",
}
DefaultColumnarColumns are the columns selected when none are given.
var DefaultCrawlConfig = CrawlConfig{ UserAgent: "CCrawl/2.0 (+https://ccrawl.tamnd.com/bot)", MaxRedirect: 5, Timeout: 120 * time.Second, }
DefaultCrawlConfig returns sensible defaults for the crawler.
var LocationColumns = []string{"url", "warc_filename", "warc_record_offset", "warc_record_length"}
LocationColumns return just the fields needed to range-fetch a record.
var PathKinds = []string{"warc", "wat", "wet", "robotstxt", "non200responses", "cc-index", "cc-index-table", "segment"}
PathKinds are the file manifests published per crawl.
Functions ¶
func AggregateCDXRaw ¶ added in v0.2.2
func AggregateCDXRaw(ctx context.Context, workDir string, prefixes []string, parallel int, progress func(prefix string, hosts int64)) error
AggregateCDXRaw reads cdx-raw-{prefix}.jsonl.gz for each prefix and writes cdx-agg-{prefix}.jsonl.gz with one row per unique host. parallel controls how many prefixes are aggregated concurrently. Skips prefixes whose cdx-agg-{prefix}.done marker already exists.
func BM25IDF ¶ added in v0.2.0
BM25IDF computes the IDF component for a term given N total docs and df doc frequency.
func BM25TF ¶ added in v0.2.0
func BM25TF(tf, dl int, avgDL float64, p BM25Params) float64
BM25TF computes the BM25 TF component.
func BuildDatasetShard ¶ added in v0.2.2
func BuildDatasetShard(ctx context.Context, prefix, workDir, crawlID, graphID, outPath string, progress func(n int64)) (int64, error)
BuildDatasetShard reads cdx-raw-{prefix}.jsonl.gz (per-URL rows) and the rank prefix file, joins rank signals by host, and writes a zstd-compressed Parquet file with one URLDatasetRow per URL capture. Returns the number of rows written.
func BuildDatasetShardFromChunk ¶ added in v0.3.0
func BuildDatasetShardFromChunk(ctx context.Context, prefix, workDir, crawlID, graphID, outPath string, chunk int, progress func(n int64)) (int64, error)
BuildDatasetShardFromChunk builds a Parquet shard for one prefix from one CDX batch chunk. It loads the prefix's rank file internally, the same way BuildDatasetShard does for the monolithic flow.
func CDXBatchPath ¶ added in v0.3.0
CDXBatchPath returns the work-dir path for a per-prefix per-batch CDX file. chunk is 1-based. Used by the batched pipeline to write per-chunk JSONL.
func CDXNumPages ¶
CDXNumPages returns the number of result pages for a query.
func CDXSeqLocalSQL ¶ added in v0.2.2
CDXSeqLocalSQL returns DuckDB SQL for a LOCAL parquet file. It groups by (url_host_name, content_mime_detected, content_languages) so that the Go accumulator can track per-MIME counts for accurate top-MIME selection without any file-level merge step.
func CDXStream ¶
func CDXStream(ctx context.Context, h *HTTPClient, crawlID string, q CDXQuery, fn func(CDXRecord) error) error
CDXStream runs a query and calls fn for each matching record, paginating through the server's pages and stopping at q.Limit.
func CanonicalURL ¶
CanonicalURL applies light canonicalization: ensure a scheme, lower-case the host, and drop a fragment. It does not reorder query parameters.
func ColumnarParquetURLs ¶
func ColumnarParquetURLs(ctx context.Context, h *HTTPClient, cache *Cache, crawlID, subset string, src Source) ([]string, error)
ColumnarParquetURLs resolves the columnar index glob into the explicit list of parquet file URLs for one crawl and subset. Common Crawl's bucket does not allow anonymous listing, so a duckdb run cannot expand the `*.parquet` glob over HTTPS (or anonymous S3) on its own. The crawl publishes the full file list in cc-index-table.paths.gz, so we read that manifest (cached) and turn each entry into a fetchable URL for the chosen source.
func ColumnarSource ¶
ColumnarSource returns the parquet glob for one crawl's columnar index subset (subset is warc, crawldiagnostics, or robotstxt).
func ComputeEdgeDegrees ¶ added in v0.2.0
func ComputeEdgeDegrees(ctx context.Context, h *HTTPClient, manifestURL string, nodeCount int64) (inDeg, outDeg []int32, err error)
ComputeEdgeDegrees streams all edge part files and computes in-degree and out-degree for every node. It requires knowing nodeCount (the total number of vertices) to allocate the degree arrays. Degrees are returned as two arrays indexed by node ID; the caller should join with vertex IDs.
func ContentSHA1 ¶ added in v0.2.0
ContentSHA1 returns the hex SHA-1 of raw content bytes (matches CC's digest field in CDX records).
func CrawlScore ¶ added in v0.2.0
CrawlScore computes a composite score combining link-graph importance and empirical change rate. Higher = higher crawl priority.
func CrawlTier ¶ added in v0.2.0
CrawlTier assigns a 1–5 crawl tier to a host based on its harmonic rank position and estimated change rate. Lower tier = more frequent crawling.
Tier 1: > 0.8 change rate + top 100 K rank → 24 h interval Tier 2: 0.5–0.8 + top 1 M → 3 days Tier 3: 0.2–0.5 + top 5 M → 7 days Tier 4: < 0.2 + top 10 M → 30 days Tier 5: everything else → on-demand
func DatasetPrefixReady ¶ added in v0.2.2
DatasetPrefixDone reports whether a prefix has been split (both cdx and rank files present for workDir).
func DatasetWorkFiles ¶ added in v0.2.2
DatasetWorkFiles returns the paths of all intermediate files for a prefix.
func DecodeVarInt ¶ added in v0.2.0
DecodeVarInt decodes a VByte-encoded integer from b, returning the value and the number of bytes consumed.
func DiffCDX ¶ added in v0.2.0
func DiffCDX(ctx context.Context, urlsA, urlsB []string, crawlA, crawlB string, fn func(HostDiffEntry) error) error
DiffCDX runs the differential CDX analysis via DuckDB and calls fn for each HostDiffEntry. Requires DuckDB on PATH.
func DiffCDXSQL ¶ added in v0.2.0
DiffCDXSQL returns the DuckDB SQL that computes per-host change rates between two crawl snapshots by joining on url and comparing content digests.
func DocumentID ¶ added in v0.2.0
DocumentID returns a stable 64-bit document ID for a canonical URL.
func DownloadFiles ¶
func DownloadFiles(ctx context.Context, h *HTTPClient, src Source, paths []string, localDir string, workers int, flat bool, progress func(DownloadResult)) error
DownloadFiles fetches a list of Common Crawl relative paths into localDir, concurrently and resumably. progress is called once per file when non-nil.
func DownloadRankTable ¶ added in v0.2.2
DownloadRankTable downloads the full rank table (gzipped TSV, 3-8 GB) to rankCachePath in workDir using curl with HTTP range resume (--continue-at -). If the file is already complete (i.e. curl exits 0 without needing to download anything), this is a no-op beyond the curl HEAD check. Uses curl so that interrupted downloads can be resumed without re-reading from the beginning — essential for multi-GB files over unstable connections.
func DownloadToFile ¶ added in v0.2.2
func DownloadToFile(ctx context.Context, h *HTTPClient, url, localPath string) error
DownloadToFile downloads url into localPath using the download HTTP client. The caller is responsible for deleting the file after use.
func DuckDBAvailable ¶
func DuckDBAvailable() bool
DuckDBAvailable reports whether a duckdb binary is on PATH.
func EncodeVarInt ¶ added in v0.2.0
EncodeVarInt encodes v as a VByte-encoded byte slice.
func ExtractCDXBatch ¶ added in v0.3.0
func ExtractCDXBatch(ctx context.Context, h *HTTPClient, batchURLs []string, workDir string, chunk, workers int, progress func(fileN, totalInBatch int, rows int64)) error
ExtractCDXBatch is the batched variant of ExtractCDXRaw: it processes only batchURLs (a contiguous slice of the full CDX URL list) and writes per-prefix cdx-raw-{p}-chunk{NNN}.jsonl.gz files. No done-marker checks or writes. chunk is 1-based. progress reports (fileN within batch, total rows so far).
func ExtractCDXRaw ¶ added in v0.2.2
func ExtractCDXRaw(ctx context.Context, h *HTTPClient, parquetURLs []string, workDir string, workers, limit int, progress func(fileN int, totalRows int64)) error
ExtractCDXRaw downloads each of parquetURLs with up to workers goroutines, reads each file with parquet-go (column-projected to CDXRawRow), and fans every row to the appropriate per-prefix cdx-raw-{prefix}.jsonl.gz file.
No aggregation is performed. Each URL capture becomes one output row. Prefixes whose cdx-raw-{prefix}.done marker already exists are skipped. limit, if > 0, stops after that many files (useful for benchmarking).
progress is called after each source file is fully processed.
func ExtractMarkdown ¶
ExtractMarkdown converts an HTML document to a compact Markdown approximation. It is intentionally light: headings, paragraphs, list items, links, and emphasis, which covers the bulk of crawled article content.
func ExtractOutLinks ¶ added in v0.2.0
ExtractOutLinks extracts absolute URLs from HTML anchor hrefs, resolving relative URLs against baseURL.
func ExtractText ¶
ExtractText returns readable plain text from an HTML document, dropping the contents of script and style elements and collapsing whitespace.
func ExtractTitle ¶
ExtractTitle returns the <title> text of an HTML document.
func FetchPaths ¶
func FetchPaths(ctx context.Context, h *HTTPClient, cache *Cache, crawlID, kind string) ([]string, error)
FetchPaths downloads and decompresses a crawl's path manifest.
func FetchWARCRecordRaw ¶ added in v0.4.0
func FetchWARCRecordRaw(ctx context.Context, h *HTTPClient, filename string, offset, length int64) ([]byte, error)
FetchWARCRecordRaw fetches the raw bytes of a single WARC record by byte range. The bytes are the original gzip member as stored in the WARC file, so they can be written straight into an exported WARC without re-encoding.
func FileLimit ¶ added in v0.4.0
func FileLimit() uint64
FileLimit reports the current open-file soft limit without changing it.
func FileURL ¶
FileURL turns a Common Crawl relative path into a fetchable URL for the given source. HTTPS uses the CloudFront mirror; S3 uses the bucket URI.
func GenerateDatasetREADME ¶ added in v0.2.4
func GenerateDatasetREADME(s DatasetStats) string
GenerateDatasetREADME produces a HuggingFace dataset card for cc-host-dataset. It is committed to the repo as README.md and updated on each shard commit.
func GenerateMarkdownREADME ¶ added in v0.3.0
func GenerateMarkdownREADME(s MarkdownDatasetStats) string
GenerateMarkdownREADME produces the HuggingFace dataset card for open-markdown-v2. It mirrors the original open-index/open-markdown card section for section: the intro, the released-files description, the download snippets, the full dataset card, the schema, the compression-ratio table, and the processing-time chart. The only deltas are this dataset's Hive partition layout (data/crawl=.../NNNNNN.parquet) and its actual column set, which drops warc_refers_to and uses a SHA-256 doc_id.
func HFMarkdownPath ¶ added in v0.3.0
HFMarkdownPath returns the HuggingFace repo path for one parquet shard. All shards for a crawl land under data/crawl=CC-MAIN-YYYY-WW/ so HF's partition-aware tooling can filter by crawl without a full scan.
func HFRefetchPath ¶ added in v0.3.0
HFRefetchPath returns the HF repo path for one refetch parquet shard.
func HFShardPath ¶ added in v0.2.4
HFShardPath returns the canonical HF repo path for a prefix shard (flat layout).
data/crawl=CC-MAIN-2026-21/subset=urls/hosts-a.parquet
func HFShardPathChunk ¶ added in v0.3.0
HFShardPathChunk returns the HF path for one prefix shard within a CDX batch. chunk is 1-based. DuckDB reads all chunks with:
read_parquet('.../subset=urls/**/*.parquet')
func HTMLCanonicalURL ¶ added in v0.2.0
HTMLCanonicalURL returns the best canonical URL from HTML headers (in priority order): link[rel=canonical], og:url. Returns "" if none found.
func HTTPBody ¶
HTTPBody splits a response block at the header/body boundary and returns the body. It returns the whole block when no boundary is found.
func HTTPHeaders ¶
HTTPHeaders returns the header section (status line + headers) of a response block, without the body.
func HTTPSURL ¶
HTTPSURL always returns the HTTPS mirror URL (used for control-plane fetches like manifests and collinfo regardless of the bulk source).
func HarmonicTier ¶ added in v0.2.0
HarmonicTier returns a 1–10 tier for a host's harmonic rank position (1 = most important, 10 = long tail). Used for multiplicative ranking boosts.
func HostCDXAgg ¶ added in v0.2.0
func HostCDXAgg(ctx context.Context, parquetURLs []string, crawlID, host string, fn func(HostCDXStats) error) error
HostCDXAgg runs the CDX aggregation for one or all hosts via DuckDB and calls fn for each result row. If host is non-empty, only that host is aggregated.
func HostCDXAggSQL ¶ added in v0.2.0
HostCDXAggSQL returns the DuckDB SQL to aggregate per-host CDX statistics from the columnar Parquet index for a given crawl. If host is non-empty the query filters to that host only; otherwise it aggregates all hosts (full table scan).
func HostCDXBatchSQL ¶ added in v0.2.2
func HostCDXBatchSQL(parquetURLs []string, crawlID string, prefixes []string, tempDir, memLimit string, threads int) string
HostCDXBatchSQL returns CDX aggregation SQL for a batch of prefix keys. Each result row has an extra `prefix_key` column for routing to per-prefix files. Scanning N prefixes in one query reads 184 GB once instead of N times.
func HostCDXPrefixSQL ¶ added in v0.2.2
HostCDXPrefixSQL returns the CDX aggregation SQL filtered to a single prefix. Superseded by HostCDXBatchSQL; kept for external callers and --seq mode.
func HostCDXSingleSQL ¶ added in v0.2.0
HostCDXSingleSQL returns the DuckDB SQL to aggregate CDX stats for one host. This is faster than the full aggregation when only one host is needed.
func InferMatchType ¶
InferMatchType guesses the CDX matchType from a user-supplied URL pattern. "*.example.com" -> domain, "example.com/*" -> prefix, otherwise exact unless the caller already chose host/domain/prefix.
func IterateWARC ¶
func IterateWARC(r io.Reader, fn func(WARCRecord) error) error
IterateWARC reads a WARC file (a multi-member gzip stream where each member is one record) and calls fn for every record. The parser lives in pkg/warc.
func IterateWAT ¶
IterateWAT reads a WAT file and calls fn for each parsed record. The parser lives in pkg/wat.
func IterateWET ¶
IterateWET reads a WET file (WARC conversion records holding plain text) and calls fn for each record. The parser lives in pkg/wet.
func LibraryDir ¶
func LibraryDir() string
LibraryDir is the root of the structured dataset library that the --library flag downloads into and processes from. It is deliberately separate from the data dir: the data dir (see Config) holds ad-hoc downloads, the cache, and the local DuckDB file, while the library is a curated, browsable corpus you build up over time. CCRAWL_LIBRARY overrides the default of ~/notes/ccrawl.
func LinkBoost ¶ added in v0.2.0
LinkBoost blends a BM25 score with a host's harmonic centrality value. alpha controls the weight of the link signal (spec recommends 0.3).
func LoadCDXRawChunk ¶ added in v0.3.0
func LoadCDXRawChunk(workDir, prefix string, chunk int, fn func(CDXRawOutputRow) error) error
LoadCDXRawChunk streams per-URL rows from cdx-raw-{prefix}-chunk{NNN}.jsonl.gz.
func LoadCDXRawPrefix ¶ added in v0.2.3
func LoadCDXRawPrefix(workDir, prefix string, fn func(CDXRawOutputRow) error) error
LoadCDXRawPrefix streams per-URL rows from cdx-raw-{prefix}.jsonl.gz. Falls back to cdx-{prefix}.jsonl.gz for backward compatibility with old DuckDB output.
func MarkdownDocID ¶ added in v0.3.0
MarkdownDocID returns a stable 16-byte hex document ID derived from the URL. The same URL always produces the same ID regardless of crawl date or shard, so duplicate-URL deduplication across crawls is a simple equi-join on doc_id.
func NormalizeURL ¶ added in v0.2.0
NormalizeURL applies light URL normalization: lowercase scheme+host, remove default port, strip fragment, strip known tracking parameters.
func ParquetListLiteral ¶
ParquetListLiteral renders parquet URLs as a duckdb list literal, e.g. ['https://a', 'https://b'], suitable as the argument to read_parquet.
func RaiseFileLimit ¶ added in v0.4.0
RaiseFileLimit lifts the process open-file soft limit to the hard limit so a high-concurrency refetch can hold thousands of sockets at once. The default soft limit on most Linux hosts is 1024, which caps in-flight connections well below what the fetch engine can drive: every live socket, every DNS UDP socket, and every open Parquet/WARC file counts against it, so a few hundred workers already brush the ceiling and further workers fail with "too many open files". Raising the soft limit to the hard limit (commonly 1048576) removes that wall without needing root or an ulimit change in the launching shell.
It returns the soft limit now in effect (the value after the raise, or the original value if the raise was not possible), so callers can size their worker pool to what the OS will actually allow. The uint64 conversions on the returns matter for portability: Rlimit.Cur is uint64 on Linux and Darwin but int64 on the BSDs, so returning it bare fails to cross-compile for FreeBSD. Converting is a no-op where it is already uint64 and a safe widening elsewhere.
func RankStream ¶ added in v0.2.0
RankStream streams every row of a gzipped rank table, calling fn for each entry. If tld is non-empty only hosts under that TLD are emitted. The caller controls early-exit by returning an error from fn.
func ResolveCrawl ¶
ResolveCrawl turns a loose reference into a canonical crawl ID.
"latest" -> newest crawl "CC-MAIN-2024-51" -> itself "2024-51" -> "CC-MAIN-2024-51" "2024" -> newest crawl whose ID starts with CC-MAIN-2024
func ResolveCrawls ¶ added in v0.4.0
ResolveCrawls expands a crawl reference into the ordered list of crawl IDs a multi-crawl command (search, get --all) should operate over, newest first.
"latest" / "" -> the newest crawl "all" -> every crawl "6" -> the newest 6 crawls "2023" -> every crawl in 2023 "CC-MAIN-2024-51" -> itself "2024-51" -> "CC-MAIN-2024-51" "a,b,2023" -> each element expanded in turn, duplicates dropped
A bare four-digit year expands to every crawl of that year here, unlike the single-crawl ResolveCrawl which picks the newest crawl of the year. Commands that operate on exactly one crawl use ResolveCrawl; commands that iterate use this.
func RunColumnarDuckDB ¶
RunColumnarDuckDB executes sql with the local duckdb binary, installing the httpfs extension for S3/HTTPS parquet access, and streams JSON rows to emit.
func RunDuckDBJSON ¶
RunDuckDBJSON runs sql with the local duckdb binary and streams JSON rows to emit. An empty dbPath runs against an in-memory database; a path opens (and creates) a persistent database file. httpfs is loaded so remote parquet over HTTPS or S3 works either way.
func SURT ¶
SURT converts a URL into a Sort-friendly URI Reordering Transform key, the canonical form Common Crawl uses to sort and group its index. For example "https://www.example.com/a/b?q=1" becomes "com,example,www)/a/b?q=1".
The transform lower-cases the scheme and host, reverses the host labels, drops a leading "www.", strips the default port, and keeps the path and query.
func SaveCDXBatchByPrefix ¶ added in v0.2.2
func SaveCDXBatchByPrefix(ctx context.Context, parquetURLs []string, crawlID, workDir string, prefixes []string, opts CDXBatchOptions, progress func(prefix string, n int64)) (map[string]int64, error)
SaveCDXBatchByPrefix runs CDX aggregation in batches of opts.BatchSize prefixes, with up to opts.Parallel batches in flight at once. Compared to SaveCDXSplitByPrefix with BatchSize=1, Parallel=1, a batch of N prefixes reads the same 184 GB Parquet corpus once instead of N times — at the cost of a proportionally larger DuckDB GROUP BY hash table.
Already-written cdx-{prefix}.jsonl.gz files are skipped, so re-running is safe. Each batch writes atomically via .tmp rename.
func SaveCDXSeqByPrefix ¶ added in v0.2.2
func SaveCDXSeqByPrefix(ctx context.Context, h *HTTPClient, parquetURLs []string, prefix, workDir string, progress func(fileN int, hosts int64)) error
SaveCDXSeqByPrefix processes all parquetURLs for a single prefix by downloading each file sequentially, running DuckDB locally, and accumulating per-host stats in memory — no intermediate files, no merge.
For each URL: download to tmpFile, run CDXSeqLocalSQL, accumulate into hostMap, delete tmpFile. After all URLs, write cdx-{prefix}.jsonl.gz.
progress is called after each file with (fileIndex, uniqueHostsSoFar).
func SaveCDXSplitByPrefix ¶ added in v0.2.2
func SaveCDXSplitByPrefix(ctx context.Context, parquetURLs []string, crawlID, workDir string, prefixes []string, progress func(prefix string, n int64)) (map[string]int64, error)
SaveCDXSplitByPrefix is the original one-prefix-at-a-time implementation. Prefer SaveCDXBatchByPrefix for new code.
func SplitRankByPrefix ¶ added in v0.2.2
func SplitRankByPrefix(ctx context.Context, h *HTTPClient, rankURL, workDir string, progress func(total int64)) (map[string]int64, error)
SplitRankByPrefix downloads the rank table once via HTTP and writes one gzipped TSV file per prefix into workDir (rank-a.tsv.gz ... rank-misc.tsv.gz). Each line: harmonic_pos\tharmonic_val\tpagerank_pos\tpagerank_val\thost For large rank tables that may fail mid-stream, prefer DownloadRankTable + SplitRankFromFile which supports HTTP range resume via curl.
func SplitRankFromFile ¶ added in v0.2.2
func SplitRankFromFile(ctx context.Context, localPath, workDir string, progress func(total int64)) (map[string]int64, error)
SplitRankFromFile reads the rank table from a local gzipped TSV file and writes one per-prefix gzipped TSV into workDir. Suitable for use after DownloadRankTable completes. Call signature identical to SplitRankByURL.
func StreamPaths ¶
func StreamPaths(ctx context.Context, h *HTTPClient, crawlID, kind string, fn func(string) error) error
StreamPaths streams a crawl's path manifest one path at a time.
func StripTrackingParams ¶ added in v0.2.0
StripTrackingParams removes known tracking query parameters from a raw URL query string. Returns the cleaned query string (without leading "?").
func TierBoost ¶ added in v0.2.0
TierBoost returns the multiplicative ranking boost for a harmonic tier. Tier 1 = 2.0×, tier 10 = 1.0×.
func TierInterval ¶ added in v0.2.0
TierInterval returns the recommended re-crawl interval in hours for a tier.
func Tokenize ¶ added in v0.2.0
Tokenize splits text into lowercase, stopword-filtered, min-2-char tokens.
func VertexStream ¶ added in v0.2.0
func VertexStream(ctx context.Context, h *HTTPClient, manifestURL string, fn func(VertexRecord) error) error
VertexStream downloads and streams all vertex part files listed in the manifest at manifestURL, calling fn for each record. Parts are fetched sequentially; use multiple goroutines externally for parallelism.
func WriteWARCResponse ¶ added in v0.2.0
func WriteWARCResponse(w io.Writer, rec NewWARCRecord) error
WriteWARCResponse writes a WARC/1.0 response record to w.
Types ¶
type APIServer ¶ added in v0.2.0
type APIServer struct {
// contains filtered or unexported fields
}
APIServer is the ccrawl v2 HTTP API server.
func NewAPIServer ¶ added in v0.2.0
func NewAPIServer(cfg ServeConfig, hosts HostStore, search SearchStore) *APIServer
NewAPIServer creates an API server with the given stores. Either store may be nil; endpoints that require the missing store return 503.
type BM25Params ¶ added in v0.2.0
type BM25Params struct {
K1 float64 // term frequency saturation (default 1.2)
B float64 // length normalization (default 0.75)
}
BM25Params holds the BM25 hyper-parameters.
type CDXBatchOptions ¶ added in v0.2.2
type CDXBatchOptions struct {
// BatchSize is the number of prefix letters per DuckDB query (default 1).
// Higher values reduce total S3 reads at the cost of a larger hash table.
// Rule of thumb: each extra prefix adds ~600 MB to the DuckDB hash table.
BatchSize int
// Parallel is how many DuckDB queries run concurrently (default 1).
// Memory budget: Parallel × (BatchSize × 600 MB + 1.5 GB DuckDB overhead).
Parallel int
// DuckDBThreads is passed as SET threads=N inside each query (default 2).
// Higher values speed up CPU-bound aggregation; each thread also opens one
// extra S3 connection, so keep ≤4 to avoid CC rate limiting.
DuckDBThreads int
// MemoryLimit is passed as SET memory_limit= per DuckDB instance (default "2GB").
// When BatchSize > 1 increase this to BatchSize × 600 MB + 1 GB headroom.
MemoryLimit string
}
CDXBatchOptions controls how SaveCDXBatchByPrefix scans and fans CDX data.
type CDXQuery ¶
type CDXQuery struct {
URL string // URL or pattern
Match string // exact|prefix|host|domain (empty -> inferred from URL)
From string // 14-digit (or loose) lower time bound
To string // 14-digit (or loose) upper time bound
Status string // HTTP status filter (e.g. "200")
MIME string // mime-detected filter
Lang string // languages filter (ISO-639-3)
Filter []string
Limit int
}
CDXQuery describes a query against the CDX URL index.
type CDXRawOutputRow ¶ added in v0.2.2
type CDXRawOutputRow struct {
Host string `json:"host"`
RD string `json:"rd,omitempty"`
TLD string `json:"tld,omitempty"`
Proto string `json:"proto,omitempty"`
URL string `json:"url,omitempty"`
Surt string `json:"surt,omitempty"`
ST int32 `json:"st"`
Redir string `json:"redir,omitempty"`
Digest string `json:"digest,omitempty"`
MIME string `json:"mime,omitempty"`
MIMEDecl string `json:"mime_d,omitempty"`
Charset string `json:"charset,omitempty"`
Lang string `json:"lang,omitempty"`
Trunc string `json:"trunc,omitempty"`
TS string `json:"ts,omitempty"`
Bytes int64 `json:"bytes,omitempty"`
WARCFile string `json:"warc_f,omitempty"`
WARCOff int64 `json:"warc_o,omitempty"`
RobotsOK bool `json:"robots_ok,omitempty"`
Crawl string `json:"crawl,omitempty"`
}
CDXRawOutputRow is written to cdx-raw-{prefix}.jsonl.gz. Short field names reduce storage size. All fields map 1:1 to CDX Parquet columns — no aggregation.
type CDXRawRow ¶ added in v0.2.2
type CDXRawRow struct {
URL string `parquet:"url"`
URLSurtKey string `parquet:"url_surtkey"`
URLHostName string `parquet:"url_host_name"`
URLHostRegisteredDomain string `parquet:"url_host_registered_domain"`
URLHostTLD string `parquet:"url_host_tld"`
URLProtocol string `parquet:"url_protocol"`
FetchStatus int32 `parquet:"fetch_status"`
FetchRedirect string `parquet:"fetch_redirect"`
FetchTime string `parquet:"fetch_time"`
Digest string `parquet:"digest"`
ContentMIMEType string `parquet:"content_mime_type"`
ContentMIMEDetected string `parquet:"content_mime_detected"`
ContentCharset string `parquet:"content_charset"`
ContentLanguages string `parquet:"content_languages"`
ContentTruncated string `parquet:"content_truncated"`
WARCFilename string `parquet:"warc_filename"`
WARCRecordOffset int64 `parquet:"warc_record_offset"`
WARCRecordLength int64 `parquet:"warc_record_length"`
RobotsTXTForceGet bool `parquet:"robotstxt_forceget"`
Crawl string `parquet:"crawl"`
}
CDXRawRow is the projected schema for CC CDX Parquet files. parquet-go reads only the declared columns, skipping the remaining ~9 in the file. All timestamp fields are read as strings to avoid conversion overhead.
type CDXRecord ¶
type CDXRecord struct {
CrawlID string `json:"crawl,omitempty" table:"crawl"`
URLKey string `json:"urlkey" table:"-"`
Timestamp string `json:"timestamp" table:"timestamp"` // 14-digit YYYYMMDDHHmmss
URL string `json:"url" table:"url,url"`
MIME string `json:"mime" table:"-"`
MIMEDetected string `json:"mime-detected" table:"mime"`
Status string `json:"status" table:"status"`
Digest string `json:"digest" table:"digest"`
Length string `json:"length" table:"length"`
Offset string `json:"offset" table:"offset"`
Filename string `json:"filename" table:"filename"`
Charset string `json:"charset,omitempty" table:"-"`
Languages string `json:"languages,omitempty" table:"languages"`
Truncated string `json:"truncated,omitempty" table:"-"`
Redirect string `json:"redirect,omitempty" table:"-"`
}
CDXRecord is one capture from the URL index. Numeric fields stay as strings because that is how the CDX server returns them; helpers convert on demand.
type Cache ¶
type Cache struct {
// contains filtered or unexported fields
}
Cache is a tiny on-disk blob cache keyed by an arbitrary string, with a TTL per entry. It is safe for the simple single-process use the CLI makes of it.
func NewCache ¶
NewCache returns a cache rooted under dir. If dir is empty or enabled is false, all operations are no-ops (cache miss on every Get).
type ColumnarQuery ¶
type ColumnarQuery struct {
Crawl string
Subset string // warc (default) | crawldiagnostics | robotstxt
Domain string // url_host_registered_domain
Host string // url_host_name
TLD string // url_host_tld
MIME string // content_mime_detected
Lang string // content_languages (substring match)
PathPrefix string // url_path prefix
Status int // fetch_status (0 = any)
Select []string
Limit int
}
ColumnarQuery builds SQL against the columnar (Parquet) index. The zero value selects everything; set fields to add WHERE clauses.
func (ColumnarQuery) SQL ¶
func (q ColumnarQuery) SQL(src Source) string
SQL renders the query as a runnable DuckDB statement reading parquet over the given source. The same text runs in Athena or Spark after swapping read_parquet for the engine's table reference.
type Config ¶
type Config struct {
DataDir string
CacheDir string
DBPath string
Source Source
Workers int
Timeout time.Duration
Delay time.Duration
Retries int
UserAgent string
CrawlID string
}
Config controls library behaviour. The zero value is not usable; call DefaultConfig and adjust.
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns a Config rooted at the XDG data/cache directories, with the most recent crawl resolved lazily (CrawlID == "latest").
func (Config) ParquetDir ¶
ParquetDir is where converted Parquet files land.
type Crawl ¶
type Crawl struct {
ID string `json:"id" kit:"id" table:"id"`
Name string `json:"name" table:"name"`
CDXAPI string `json:"cdx-api" table:"-"`
From string `json:"from,omitempty" table:"from"`
To string `json:"to,omitempty" table:"to"`
}
Crawl is one Common Crawl collection as published in collinfo.json.
func ListCrawls ¶
ListCrawls fetches and parses collinfo.json. Results are cached when a cache is supplied (pass nil to skip).
type CrawlConfig ¶ added in v0.2.0
CrawlConfig holds configuration for the crawler.
type CrawlResult ¶ added in v0.2.0
type CrawlResult struct {
URL string
FinalURL string // after redirects
Status int
ContentType string
Body []byte
Digest string // SHA-1 of body
FetchedAt time.Time
// Links extracted from HTML (relative links resolved to FinalURL)
Links []string
}
CrawlResult is the output of fetching a single URL.
func CrawlURL ¶ added in v0.2.0
func CrawlURL(ctx context.Context, rawURL string, cfg CrawlConfig) (*CrawlResult, error)
CrawlURL fetches a single URL and returns a CrawlResult. It does not consult the robots.txt cache; the caller must do that before calling CrawlURL.
type DatasetStats ¶ added in v0.2.4
type DatasetStats struct {
CrawlID string
CommittedShards int
TotalShards int
TotalURLs int64
TotalBytes int64 // sum of WARC record bytes across all URL rows
// Batched-pipeline fields (non-zero activates batch-aware progress line).
TotalBatches int
CommittedBatches int
}
DatasetStats accumulates per-shard statistics for the README.
type DownloadResult ¶
DownloadResult is the outcome of fetching one file.
type EdgeDegrees ¶ added in v0.2.0
type EdgeDegrees struct {
NodeID int64 `json:"node_id"`
InDegree int32 `json:"in_degree"`
OutDegree int32 `json:"out_degree"`
}
EdgeDegrees holds the in-degree and out-degree for one node.
type ForwardDoc ¶ added in v0.2.0
type ForwardDoc struct {
DocID uint64 `json:"doc_id" table:"doc_id"`
URL string `json:"url" table:"url"`
CanonURL string `json:"canon_url" table:"canon_url"`
Host string `json:"host" table:"host"`
Title string `json:"title" table:"title"`
Description string `json:"description" table:"description"`
Language string `json:"language" table:"language"`
WordCount int `json:"word_count" table:"word_count"`
LinkScore float32 `json:"link_score" table:"link_score"`
Snippet string `json:"snippet" table:"snippet"`
}
ForwardDoc is one row in the forward index.
type ForwardIndexWriter ¶ added in v0.2.0
type ForwardIndexWriter struct {
// contains filtered or unexported fields
}
ForwardIndexWriter appends ForwardDoc rows to a JSONL file.
func NewForwardIndexWriter ¶ added in v0.2.0
func NewForwardIndexWriter(path string) (*ForwardIndexWriter, error)
NewForwardIndexWriter opens (or creates) a JSONL forward index file.
func (*ForwardIndexWriter) Close ¶ added in v0.2.0
func (fw *ForwardIndexWriter) Close() error
Close flushes and closes the writer.
func (*ForwardIndexWriter) Write ¶ added in v0.2.0
func (fw *ForwardIndexWriter) Write(d ForwardDoc) error
Write appends one ForwardDoc to the index.
type Frontier ¶ added in v0.2.0
type Frontier struct {
// contains filtered or unexported fields
}
Frontier is an in-memory URL frontier with a priority heap and per-host politeness (minimum delay between requests to the same host).
func NewFrontier ¶ added in v0.2.0
NewFrontier creates a Frontier with the given per-host politeness delay.
func (*Frontier) Add ¶ added in v0.2.0
func (f *Frontier) Add(e FrontierEntry) bool
Add enqueues a URL if it has not been seen before. Returns true if added.
func (*Frontier) Pop ¶ added in v0.2.0
func (f *Frontier) Pop(now int64) (FrontierEntry, bool)
Pop removes and returns the highest-priority URL that is eligible to crawl now (host delay has elapsed). Returns false if no eligible URL exists.
To avoid starvation when the top-priority host is in its politeness window, Pop scans up to scanLimit candidates before giving up. Skipped (ineligible) entries are temporarily held and re-pushed so the heap remains consistent.
type FrontierEntry ¶ added in v0.2.0
type FrontierEntry struct {
URL string // normalized URL
Host string // hostname for politeness grouping
Priority float32 // harmonic centrality (higher = crawl sooner)
NextAt int64 // earliest Unix timestamp to fetch
Depth uint8 // BFS depth from seed
Retries uint8
}
FrontierEntry is one URL in the crawl frontier.
type HFClient ¶ added in v0.2.4
type HFClient struct {
// contains filtered or unexported fields
}
HFClient is a HuggingFace Hub client. Large-file commits are delegated to an embedded Python helper (hf_commit.py) run via uv, which uses huggingface_hub + hf-xet for xet-aware uploads.
func NewHFClient ¶ added in v0.2.4
NewHFClient creates an HFClient. If token is empty, HF_TOKEN is used (falling back to HUGGINGFACE_TOKEN for compatibility).
func (*HFClient) CommitWithRetry ¶ added in v0.2.4
func (c *HFClient) CommitWithRetry(ctx context.Context, repoID, message string, ops []HFOperation, maxAttempts int) (string, error)
CommitWithRetry calls CreateCommit up to maxAttempts times with exponential backoff. Rate-limit errors respect the server's Retry-After duration.
func (*HFClient) CreateCommit ¶ added in v0.2.4
func (c *HFClient) CreateCommit(ctx context.Context, repoID, message string, ops []HFOperation) (string, error)
CreateCommit uploads files to HuggingFace via uv+Python and returns the commit URL. The Python helper (hf_commit.py) is extracted to ~/.cache/ccrawl/ on first use.
func (*HFClient) CreateDatasetRepo ¶ added in v0.2.4
CreateDatasetRepo creates a dataset repo if it does not exist. Returns nil for both 200/201 (created) and 409 (already exists).
type HFOperation ¶ added in v0.2.4
HFOperation describes a file to add to a HuggingFace commit.
type HTTPClient ¶
type HTTPClient struct {
// contains filtered or unexported fields
}
HTTPClient is a polite, retrying HTTP client for Common Crawl. It rate-limits requests, retries on 403/429/5xx with linear backoff, and supports byte-range requests for single-record retrieval.
func NewHTTPClient ¶
func NewHTTPClient(cfg Config) *HTTPClient
NewHTTPClient builds an HTTPClient from cfg.
func (*HTTPClient) FetchBytes ¶
FetchBytes fetches url and returns the whole body.
func (*HTTPClient) GetDownload ¶
GetDownload fetches url with no client timeout (relies on ctx cancellation), for large archive bodies.
type HostCDXStats ¶ added in v0.2.0
type HostCDXStats struct {
Host string `json:"url_host_name"`
RegisteredDomain string `json:"registered_domain"`
URLCount int64 `json:"url_count"`
Status2xx int64 `json:"status_2xx"`
Status3xx int64 `json:"status_3xx"`
Status4xx int64 `json:"status_4xx"`
Status5xx int64 `json:"status_5xx"`
TopMIME string `json:"top_mime"`
Language string `json:"language"`
FirstSeen string `json:"first_seen"`
LastSeen string `json:"last_seen"`
TotalBytes int64 `json:"total_bytes"`
}
HostCDXStats is the CDX aggregation result for one host, produced by a DuckDB GROUP BY query over the columnar Parquet index.
type HostDatasetRow ¶ added in v0.2.2
type HostDatasetRow struct {
Host string `parquet:"host"`
HostRev string `parquet:"host_rev,dict"`
TLD string `parquet:"tld,dict"`
RegisteredDomain string `parquet:"registered_domain,dict"`
CrawlID string `parquet:"crawl_id,dict"`
GraphID string `parquet:"graph_id,dict"`
HarmonicPos int64 `parquet:"harmonic_pos"`
HarmonicVal float64 `parquet:"harmonic_val"`
PageRankPos int64 `parquet:"pagerank_pos"`
PageRankVal float64 `parquet:"pagerank_val"`
InDegree int32 `parquet:"in_degree"`
OutDegree int32 `parquet:"out_degree"`
URLCount int64 `parquet:"url_count"`
Status2xx int64 `parquet:"status_2xx"`
Status3xx int64 `parquet:"status_3xx"`
Status4xx int64 `parquet:"status_4xx"`
Status5xx int64 `parquet:"status_5xx"`
TopMIME string `parquet:"top_mime,dict"`
Language string `parquet:"language,dict"`
FirstSeen string `parquet:"first_seen,dict"`
LastSeen string `parquet:"last_seen,dict"`
TotalBytes int64 `parquet:"total_bytes"`
}
HostDatasetRow is the legacy per-host aggregated schema kept for reference. The active pipeline now uses URLDatasetRow (per-URL rows, no aggregation).
type HostDiffEntry ¶ added in v0.2.0
type HostDiffEntry struct {
Host string `json:"host" table:"host"`
TotalURLs int64 `json:"total_urls" table:"total_urls"`
ChangedURLs int64 `json:"changed_urls" table:"changed_urls"`
ChangeRate float64 `json:"change_rate" table:"change_rate"`
Tier int `json:"tier" table:"tier"`
}
HostDiffEntry is one row of the per-host change report between two CDX snapshots. It shows how many URLs were seen in both crawls, how many had their content digest change, and the derived change rate.
type HostRecord ¶ added in v0.2.0
type HostRecord struct {
// Identity
Host string `json:"host" kit:"id" table:"host"`
HostRev string `json:"host_rev,omitempty" table:"-"`
TLD string `json:"tld" table:"tld"`
RegisteredDomain string `json:"registered_domain,omitempty" table:"registered_domain"`
// Rank signals (from rank table)
HarmonicPos int64 `json:"harmonic_pos" table:"harmonic_pos"`
HarmonicVal float64 `json:"harmonic_val" table:"harmonic_val"`
PageRankPos int64 `json:"pagerank_pos" table:"pagerank_pos"`
PageRankVal float64 `json:"pagerank_val" table:"pagerank_val"`
// Graph topology (from edge files)
InDegree int64 `json:"in_degree" table:"in_degree"`
OutDegree int64 `json:"out_degree" table:"out_degree"`
// CDX statistics (from columnar Parquet index)
URLCount int64 `json:"url_count" table:"url_count"`
Status2xx int64 `json:"status_2xx" table:"status_2xx"`
Status3xx int64 `json:"status_3xx" table:"status_3xx"`
Status4xx int64 `json:"status_4xx" table:"status_4xx"`
Status5xx int64 `json:"status_5xx" table:"status_5xx"`
TopMIME string `json:"top_mime,omitempty" table:"top_mime"`
Language string `json:"language,omitempty" table:"language"`
FirstSeen string `json:"first_seen,omitempty" table:"first_seen"`
LastSeen string `json:"last_seen,omitempty" table:"last_seen"`
TotalBytes int64 `json:"total_bytes" table:"total_bytes"`
}
HostRecord is the fully enriched profile for one host, combining signals from the web-graph rank table, graph topology (in/out-degree), and the CDX URL index.
func HostFromRank ¶ added in v0.2.0
func HostFromRank(r Rank) HostRecord
HostFromRank builds a minimal HostRecord from a Rank entry.
func HostLookupRank ¶ added in v0.2.0
func HostLookupRank(ctx context.Context, h *HTTPClient, rankURL, host string) (HostRecord, error)
HostLookupRank returns the rank-only HostRecord for a host by streaming the rank table. This is O(rank_table_size) — for a single-host lookup it is best to use HostLookupCDX for CDX stats and join separately.
type HostSchedule ¶ added in v0.2.0
type HostSchedule struct {
Host string `json:"host" table:"host"`
HarmonicPos int64 `json:"harmonic_pos" table:"harmonic_pos"`
HarmonicVal float64 `json:"harmonic_val" table:"harmonic_val"`
ChangeRate float64 `json:"change_rate" table:"change_rate"`
Tier int `json:"tier" table:"tier"`
IntervalH int `json:"interval_h" table:"interval_h"`
Score float64 `json:"score" table:"score"`
}
HostSchedule holds the crawl schedule for one host: its tier and derived priority score.
func HostScheduleFrom ¶ added in v0.2.0
func HostScheduleFrom(r Rank, changeRate float64) HostSchedule
HostScheduleFrom builds a HostSchedule from a Rank entry and a change rate.
type HostStore ¶ added in v0.2.0
type HostStore interface {
GetHost(ctx context.Context, host string) (*HostRecord, error)
TopHosts(ctx context.Context, n int, tld string) ([]HostRecord, error)
}
HostStore is the interface for host metadata lookups used by the API.
type IndexReader ¶ added in v0.2.0
IndexReader reads a flushed inverted index from disk.
func OpenIndex ¶ added in v0.2.0
func OpenIndex(dir string) (*IndexReader, error)
OpenIndex opens a flushed inverted index directory.
func (*IndexReader) Close ¶ added in v0.2.0
func (r *IndexReader) Close() error
Close releases the index file handles.
func (*IndexReader) Lookup ¶ added in v0.2.0
func (r *IndexReader) Lookup(term string) ([]PostingEntry, float64, bool)
Lookup returns the posting list for a term.
type IndexSearchStore ¶ added in v0.2.0
type IndexSearchStore struct {
// contains filtered or unexported fields
}
IndexSearchStore wraps an IndexReader to implement the SearchStore interface. The forward index is looked up from a map of docID → ForwardDoc.
func NewIndexSearchStore ¶ added in v0.2.0
func NewIndexSearchStore(idx *IndexReader, forward map[uint64]ForwardDoc) *IndexSearchStore
NewIndexSearchStore wraps an IndexReader.
func (*IndexSearchStore) Search ¶ added in v0.2.0
func (s *IndexSearchStore) Search(_ context.Context, query string, k int) ([]SearchResult, error)
Search tokenizes the query and returns top-k search results with snippets.
type InvertedIndexBuilder ¶ added in v0.2.0
type InvertedIndexBuilder struct {
N int // total docs indexed
TermCount int // unique term count (set by Flush)
// contains filtered or unexported fields
}
InvertedIndexBuilder accumulates (term → postings) in memory and writes the index to disk when Flush() is called.
func NewInvertedIndexBuilder ¶ added in v0.2.0
func NewInvertedIndexBuilder(dir string) (*InvertedIndexBuilder, error)
NewInvertedIndexBuilder creates a builder that writes to dir.
func (*InvertedIndexBuilder) Add ¶ added in v0.2.0
func (b *InvertedIndexBuilder) Add(docID uint64, tokens []string)
Add indexes a single document. DL (the document token length) is stored in each PostingEntry so BM25 scoring can use per-document length normalization.
func (*InvertedIndexBuilder) Flush ¶ added in v0.2.0
func (b *InvertedIndexBuilder) Flush() error
Flush writes the inverted index to disk in shard_NNN/ directories.
type Ledger ¶ added in v0.3.0
type Ledger struct {
// contains filtered or unexported fields
}
Ledger is an append-only record of which shard indices have been committed. It lets a killed run resume without re-doing finished shards and without a database: the file is one shard index per line. It is safe for concurrent use; the committer is the only writer in practice.
func OpenLedger ¶ added in v0.3.0
OpenLedger loads any existing ledger at path and opens it for appending.
type Library ¶
Library is a structured corpus of Common Crawl archive files for one crawl, rooted at Root. The layout is predictable so a directory listing tells you exactly what you have:
<root>/<crawl>/<kind>/<file>.gz raw downloaded archives <root>/<crawl>/<format>/<kind>/<file>.<ext> processed output (parquet|jsonl)
Files are stored flat under each kind by their base name. A Common Crawl file name already encodes its segment and timestamp and is unique within a crawl, so the base name alone is a safe, stable key with no risk of collision.
func NewLibrary ¶
NewLibrary returns a Library rooted at root (or LibraryDir() when root is empty) for the given crawl ID.
func (Library) CrawlDir ¶
CrawlDir is the per-crawl root, the parent of every kind and format directory.
func (Library) ProcessedDir ¶
ProcessedDir is where processed output of a kind lives, grouped by format (parquet or jsonl) so the same archives can be materialised more than one way side by side.
type Location ¶
type Location struct {
Filename string `json:"filename" table:"filename"`
Offset int64 `json:"offset" table:"offset"`
Length int64 `json:"length" table:"length"`
URL string `json:"url,omitempty" table:"url,url"`
}
Location is the WARC file plus byte span needed to range-fetch this capture.
type MarkdownDatasetStats ¶ added in v0.3.0
type MarkdownDatasetStats struct {
CrawlID string
CommittedShards int
TotalShards int
Rows int64
WARCBytes int64 // compressed .warc.gz bytes downloaded
HTMLBytes int64
MDBytes int64
ParquetBytes int64
// Cumulative pipeline timings across committed shards, in seconds. Zero
// values drop the Processing Times chart from the card.
DownloadS int64
ConvertS int64
ExportS int64
PublishS int64
}
MarkdownDatasetStats holds cumulative stats for the open-markdown README. The byte and row totals cover the shards committed so far; when fewer shards are committed than the crawl holds, GenerateMarkdownREADME scales them to a full-crawl estimate the same way the original open-markdown card did.
type MarkdownExportConfig ¶ added in v0.3.0
type MarkdownExportConfig struct {
CrawlID string
Indices []int // shard indices to process, in order
WARCPaths []string // full manifest, indexed by shard index
OutDir string
Repo string
Push bool
// ShardParallel is the number of shards processed at once (P). More than a
// couple only helps when downloads are slow relative to conversion. 0 picks
// a small default.
ShardParallel int
// ConvertWorkers caps total concurrent conversions across all shards (C).
// 0 selects runtime.NumCPU().
ConvertWorkers int
// CommitBatch is how many finished parquets go into one HF commit (K). The
// committer runs off the critical path, so batching keeps commit round
// trips from dominating wall-clock on long runs. 0 means 1.
CommitBatch int
// KeepParquet leaves local parquet files in place after they are committed.
// The default deletes them, which is required on small disks.
KeepParquet bool
// MinFreeBytes pauses new downloads while free disk is below this. 0 selects
// 2 GiB.
MinFreeBytes int64
// Ledger, when set, skips already-committed shards and records new ones.
Ledger *Ledger
// Progress is called once per committed batch with a snapshot of the run.
// It may be nil.
Progress func(MarkdownRunStats)
}
MarkdownExportConfig configures a parallel multi-shard markdown export.
type MarkdownPackConfig ¶ added in v0.3.0
type MarkdownPackConfig struct {
// CrawlID is the CC crawl identifier (e.g. CC-MAIN-2026-25).
CrawlID string
// ShardIdx is the 0-based index of this WARC file in the crawl manifest.
ShardIdx int
// WARCPath is the Common Crawl relative path (crawl-data/.../warc.gz).
WARCPath string
// OutPath is the local parquet file to write.
OutPath string
// Workers is the number of goroutines for HTML→Markdown conversion.
// 0 selects runtime.NumCPU().
Workers int
// MaxRecords, when > 0, stops the shard after this many HTML response
// records have been queued for conversion. 0 means convert the whole shard.
// It exists for the throughput benchmark, which needs a fixed, fast slice of
// a shard; production export leaves it at 0.
MaxRecords int
// ConvertSem, when non-nil, caps the number of conversions running at once
// across every shard that shares it. The orchestrator passes one semaphore
// sized to the CPU count so several shards can be in flight (hiding download
// latency) without oversubscribing the cores. nil means no global cap.
ConvertSem chan struct{}
// Progress is called after each row is written. It may be nil.
Progress func(MarkdownStats)
}
MarkdownPackConfig controls one shard conversion run.
type MarkdownRow ¶ added in v0.3.0
type MarkdownRow struct {
DocID string `parquet:"doc_id"`
URL string `parquet:"url"`
Host string `parquet:"host"`
CrawlDate string `parquet:"crawl_date"`
WARCRecordID string `parquet:"warc_record_id"`
HTMLLength int64 `parquet:"html_length"`
MarkdownLength int64 `parquet:"markdown_length"`
Markdown string `parquet:"markdown"`
}
MarkdownRow is the parquet schema for one converted HTML document. It matches the open-index/open-markdown dataset layout so the output can be appended to existing crawls without a schema migration.
type MarkdownRunStats ¶ added in v0.3.0
type MarkdownRunStats struct {
Total int // shards requested this run
Skipped int // shards skipped via the ledger
Committed int // shards committed so far
Failed int // shards that errored
Rows int64 // cumulative rows across committed shards
WARCBytes int64
HTMLBytes int64
MDBytes int64
ParquetBytes int64
ConvertS int64 // cumulative per-shard conversion wall-clock, seconds
PublishS int64 // cumulative HF commit wall-clock, seconds
Elapsed time.Duration
ShardsPerHour float64
ETA time.Duration // estimated time to finish the remaining shards
FreeDiskBytes int64
}
MarkdownRunStats is a live snapshot of a parallel export run.
func RunMarkdownExport ¶ added in v0.3.0
func RunMarkdownExport(ctx context.Context, h *HTTPClient, hf *HFClient, cfg MarkdownExportConfig) (MarkdownRunStats, error)
RunMarkdownExport streams the requested shards through the conversion pipeline in parallel and commits the parquet files to HuggingFace in batches.
Layout:
[P shard workers] download+convert each shard (sharing one C-sized convert
semaphore) → finished channel → [1 committer] batches K parquets per HF
commit, deletes the local files, records the ledger, logs an ETA.
Moving commits onto their own goroutine keeps the ~30 s HF round trip off the per-shard critical path, which is what makes a full-crawl run practical.
type MarkdownStats ¶ added in v0.3.0
type MarkdownStats struct {
ShardIdx int
Rows int64
WARCBytes int64 // compressed .warc.gz bytes downloaded (Content-Length)
HTMLBytes int64
MDBytes int64
ParquetBytes int64
DurDownload time.Duration
DurConvert time.Duration
DurExport time.Duration
DurPublish time.Duration
}
MarkdownStats summarises one WARC shard's conversion run.
func PackMarkdownShard ¶ added in v0.3.0
func PackMarkdownShard(ctx context.Context, h *HTTPClient, cfg MarkdownPackConfig) (MarkdownStats, error)
PackMarkdownShard streams one WARC shard through the conversion pipeline and writes a parquet file at cfg.OutPath. The WARC is never written to disk — the HTTP response body streams directly to the WARC iterator.
Pipeline:
HTTP stream → WARC iterator → filter (response + HTML) → records chan → [N conversion workers] → rows chan → parquet writer
N workers parallelise the h2m extraction and markdown rendering. The single writer keeps the parquet output sequential.
type MemHostStore ¶ added in v0.2.0
type MemHostStore struct {
// contains filtered or unexported fields
}
MemHostStore is a simple in-memory HostStore backed by a slice of HostRecord.
func NewMemHostStore ¶ added in v0.2.0
func NewMemHostStore(recs []HostRecord) *MemHostStore
NewMemHostStore builds a MemHostStore from a slice of HostRecord.
func (*MemHostStore) GetHost ¶ added in v0.2.0
func (s *MemHostStore) GetHost(_ context.Context, host string) (*HostRecord, error)
GetHost returns the HostRecord for a given hostname.
func (*MemHostStore) TopHosts ¶ added in v0.2.0
func (s *MemHostStore) TopHosts(_ context.Context, n int, tld string) ([]HostRecord, error)
TopHosts returns up to n hosts filtered optionally by TLD.
type NewWARCRecord ¶ added in v0.2.0
type NewWARCRecord struct {
TargetURI string
Date string
RecordID string
Block []byte // raw HTTP response bytes
}
NewWARCRecord holds the fields to write a fresh WARC response record.
type NewsFile ¶
type NewsFile struct {
Path string `json:"path" table:"path"`
Year int `json:"year" table:"year"`
Mon int `json:"month" table:"month"`
}
NewsFile describes one CC-NEWS WARC file.
func ListNewsFiles ¶
ListNewsFiles returns the CC-NEWS WARC files for a year and month. Pass month 0 to list every month of a year; pass year 0 to list everything found via the index page.
type ParquetWriter ¶
type ParquetWriter[T any] struct { // contains filtered or unexported fields }
ParquetWriter writes rows of type T to a zstd-compressed Parquet file.
func NewParquetWriter ¶
func NewParquetWriter[T any](path string) (*ParquetWriter[T], error)
NewParquetWriter creates a Parquet writer for path.
func (*ParquetWriter[T]) Close ¶
func (p *ParquetWriter[T]) Close() error
Close flushes and closes the file.
func (*ParquetWriter[T]) Rows ¶
func (p *ParquetWriter[T]) Rows() int64
Rows returns the number of rows written.
func (*ParquetWriter[T]) Write ¶
func (p *ParquetWriter[T]) Write(row T) error
Write appends one row.
type PostingEntry ¶ added in v0.2.0
type PostingEntry struct {
DocID uint64
TF uint32
DL uint32 // document token length at index time
}
PostingEntry is one (doc_id, term_freq, doc_len) triple in a posting list. DL is the document token length, stored per-posting so BM25 length normalization uses the actual document length rather than the corpus average.
type QualityResult ¶ added in v0.2.0
type QualityResult struct {
WordCount int
TitleLength int
HasMainContent bool
SpamScore float64 // 0–1
IsParked bool
IsShortContent bool // word_count < 50
}
QualityResult holds per-document quality signals computed from a TextResult.
func QualitySignals ¶ added in v0.2.0
func QualitySignals(tr TextResult) QualityResult
QualitySignals computes per-document quality signals from a TextResult.
type Rank ¶
type Rank struct {
Key string `json:"key" kit:"id" table:"key"` // host or domain (forward form)
HarmonicPos int64 `json:"harmonic_pos" table:"harmonic_pos"`
HarmonicVal float64 `json:"harmonic_val" table:"harmonic_val"`
PageRankPos int64 `json:"pagerank_pos" table:"pagerank_pos"`
PageRankVal float64 `json:"pagerank_val" table:"pagerank_val"`
}
Rank is a host/domain entry from the web-graph rank tables.
func RankLookup ¶
RankLookup streams a gzipped rank table from url and returns the entry whose reversed key matches the given host or domain, or a not-found error.
type RateLimitError ¶ added in v0.2.4
RateLimitError is returned when HuggingFace responds 429 Too Many Requests.
func (*RateLimitError) Error ¶ added in v0.2.4
func (e *RateLimitError) Error() string
type RefetchDatasetStats ¶ added in v0.3.0
type RefetchDatasetStats struct {
CrawlID string
CommittedShards int
TotalShards int
Rows int64
URLsFound int64
WARCBytes int64
FetchBytes int64
HTMLBytes int64
MDBytes int64
ParquetBytes int64
ConvertS int64
PublishS int64
}
RefetchDatasetStats holds cumulative stats for the refetch README card.
type RefetchExportConfig ¶ added in v0.3.0
type RefetchExportConfig struct {
CrawlID string
Indices []int // shard indices to process, in order
WARCPaths []string // full manifest, indexed by shard index
OutDir string
Repo string
Push bool
// FetchCfg is the ami config passed to each shard's FetchBatch call.
// Workers, MaxRedirects, and PerHostDelay are the knobs most callers set.
FetchCfg config.Config
// ShardParallel is the number of shards processed concurrently. 0 picks 2.
ShardParallel int
// ConvertWorkers caps total concurrent HTML-to-Markdown conversions. 0 picks NumCPU.
ConvertWorkers int
// CommitBatch is how many finished parquets go into one HF commit. 0 means 1.
CommitBatch int
// KeepParquet leaves local parquet files in place after they are committed.
KeepParquet bool
// MinFreeBytes pauses new downloads while free disk is below this. 0 selects 2 GiB.
MinFreeBytes int64
// CacheDir caches downloaded WARC shards so a re-run skips the download.
// Empty disables caching.
CacheDir string
// FetchOnly stores raw HTML and skips the HTML-to-Markdown convert, so the
// fetch step runs at its true ceiling and Markdown is produced by a separate
// offline pass over the stored html column.
FetchOnly bool
// Ledger, when set, skips already-committed shards and records new ones.
Ledger *Ledger
// Progress is called once per committed batch with a snapshot of the run.
Progress func(RefetchRunStats)
}
RefetchExportConfig configures a parallel multi-shard refetch export.
type RefetchPackConfig ¶ added in v0.3.0
type RefetchPackConfig struct {
CrawlID string
ShardIdx int
WARCPath string
OutPath string
FetchCfg config.Config
ConvertSem chan struct{}
Progress func(RefetchStats)
// FetchOnly stores the raw HTML body in the html column and skips the
// HTML-to-Markdown convert entirely. Convert is the CPU-bound phase and the
// end-to-end wall on a multi-core box, so skipping it lets the fetch step run
// at its true ceiling; the Markdown is produced later by an offline convert
// pass over the stored html column, which can run on a bigger box or a
// cluster without holding back the crawl.
FetchOnly bool
// CacheDir, when set, is where the downloaded WARC is cached so a re-run of
// the same shard skips the multi-second download. The download streams to a
// .part file beside the final name and is renamed into place only once it is
// complete, so an interrupted run never leaves a truncated file that a later
// run would mistake for a good cache. Empty disables caching.
CacheDir string
}
RefetchPackConfig controls one shard refetch run.
type RefetchRow ¶ added in v0.3.0
type RefetchRow struct {
DocID string `parquet:"doc_id"`
URL string `parquet:"url"`
FinalURL string `parquet:"final_url"`
Host string `parquet:"host"`
IPAddress string `parquet:"ip_address"`
CrawlID string `parquet:"crawl_id"`
CrawlDate string `parquet:"crawl_date"`
WARCRecordID string `parquet:"warc_record_id"`
FetchedAt int64 `parquet:"fetched_at"`
Status int32 `parquet:"status"`
ContentType string `parquet:"content_type"`
FetchDurMS int64 `parquet:"fetch_duration_ms"`
TTFBMS int64 `parquet:"ttfb_ms"`
ETag string `parquet:"etag"`
LastModified string `parquet:"last_modified"`
RespHeaders string `parquet:"resp_headers"`
BodyLength int64 `parquet:"body_length"`
Digest string `parquet:"digest"`
HTMLLength int64 `parquet:"html_length"`
HTML string `parquet:"html"`
MarkdownLength int64 `parquet:"markdown_length"`
Markdown string `parquet:"markdown"`
Error string `parquet:"error"`
}
RefetchRow is the parquet schema for a re-fetched page. It combines CC provenance (crawl_id, crawl_date, warc_record_id) with live fetch metadata (status, TTFB, timing, headers) and the converted markdown body.
type RefetchRunStats ¶ added in v0.3.0
type RefetchRunStats struct {
Total int
Skipped int
Committed int
Failed int
Rows int64
URLsFound int64
WARCBytes int64
FetchBytes int64
HTMLBytes int64
MDBytes int64
ParquetBytes int64
// Per-phase wall-time sums (in seconds, across all completed shards).
ExtractS int64 // phase 1: WARC download + URL extraction
FetchS int64 // phase 2: ami live refetch
ConvertS int64 // phase 3: HTML to Markdown
ExportS int64 // phase 4: Parquet write
PublishS int64 // HF commit (off critical path)
// Failure breakdown summed across shards, for throughput diagnosis.
Failures int64
ErrDNS int64
ErrTimeout int64
ErrRefused int64
ErrSkip int64
ErrOther int64
Elapsed time.Duration
ShardsPerHour float64
ETA time.Duration
FreeDiskBytes int64
}
RefetchRunStats is a live snapshot of a parallel refetch export run.
func RunRefetchExport ¶ added in v0.3.0
func RunRefetchExport(ctx context.Context, h *HTTPClient, hf *HFClient, cfg RefetchExportConfig) (RefetchRunStats, error)
RunRefetchExport streams the requested shards through the refetch pipeline in parallel and commits the parquet files to HuggingFace in batches.
Layout mirrors RunMarkdownExport:
[P shard workers] extract URLs + re-fetch + convert → finished channel → [1 committer] batches K parquets per HF commit, deletes local files, records the ledger, logs an ETA.
type RefetchStats ¶ added in v0.3.0
type RefetchStats struct {
ShardIdx int
// Phase 1: WARC URL extraction.
URLsFound int64
DurExtract time.Duration
WARCBytes int64
// Phase 2: ami refetch.
Fetched int64
Failed int64
Redirected int64
FetchBytes int64
DurFetch time.Duration
// Failure breakdown, so a low-yield shard can be diagnosed without a second
// run. These count Result.Err by class and sum to Failed.
ErrDNS int64 // name does not resolve (no such host / NXDOMAIN)
ErrTimeout int64 // deadline exceeded before a response
ErrRefused int64 // connection refused / reset by peer
ErrSkip int64 // engine skipped the URL (dead-domain breaker, non-HTTP)
ErrOther int64 // TLS, protocol, and everything else
// Phase 3: HTML to Markdown convert.
Rows int64
HTMLBytes int64
MDBytes int64
DurConvert time.Duration
// Phase 4: parquet write.
ParquetBytes int64
DurExport time.Duration
MemRSSBytes int64
}
RefetchStats summarises one shard's refetch run with per-phase breakdown.
func PackRefetchShard ¶ added in v0.3.0
func PackRefetchShard(ctx context.Context, h *HTTPClient, cfg RefetchPackConfig) (RefetchStats, error)
PackRefetchShard runs the four-phase refetch pipeline for one WARC shard:
- Extract URLs from WARC headers (stream the WARC, keep only response+HTML records)
- Re-fetch all URLs live with ami's FetchBatch
- Convert HTML bodies to Markdown
- Write a parquet file at cfg.OutPath
type RobotsCache ¶ added in v0.2.0
type RobotsCache struct {
// contains filtered or unexported fields
}
RobotsCache caches parsed robots.txt per host with a TTL.
func NewRobotsCache ¶ added in v0.2.0
func NewRobotsCache(ttl time.Duration, userAgent string) *RobotsCache
NewRobotsCache creates a cache with the given TTL and user-agent string.
func (*RobotsCache) Get ¶ added in v0.2.0
func (rc *RobotsCache) Get(host string) *RobotsEntry
Get returns the cached robots entry for host, or nil if not cached or expired.
func (*RobotsCache) Put ¶ added in v0.2.0
func (rc *RobotsCache) Put(host string, e *RobotsEntry)
Put stores a robots entry for host.
type RobotsEntry ¶ added in v0.2.0
type RobotsEntry struct {
Rules []RobotsRule
CrawlDelay time.Duration
ExpiresAt int64 // Unix timestamp
}
RobotsEntry is a cached robots.txt for one host.
func FetchRobots ¶ added in v0.2.0
func FetchRobots(ctx context.Context, h *HTTPClient, host, scheme string) *RobotsEntry
FetchRobots fetches and parses robots.txt for the given host. On timeout or 5xx, returns a permissive entry (allow all). On 404, returns allow all permanently. The caller should Put the result into the cache.
func (*RobotsEntry) IsAllowed ¶ added in v0.2.0
func (e *RobotsEntry) IsAllowed(path string) bool
IsAllowed reports whether the given path is allowed. The most specific (longest) matching rule wins, following the standard robots.txt precedence.
type RobotsRule ¶ added in v0.2.0
RobotsRule is one allow/disallow rule from robots.txt.
type SearchResult ¶ added in v0.2.0
type SearchResult struct {
DocID uint64 `json:"doc_id"`
URL string `json:"url"`
Host string `json:"host"`
Title string `json:"title"`
Snippet string `json:"snippet"`
Score float64 `json:"score"`
Language string `json:"language,omitempty"`
}
SearchResult is one search hit returned by the API.
type SearchStore ¶ added in v0.2.0
type SearchStore interface {
Search(ctx context.Context, query string, k int) ([]SearchResult, error)
}
SearchStore is the interface for full-text search used by the API.
type SeedExportOptions ¶ added in v0.3.0
type SeedExportOptions struct {
// Status keeps only captures with this fetch_status. Zero means any status.
Status int32
// MIME, when set, keeps only captures whose detected MIME contains it.
MIME string
// Lang, when set, keeps only captures whose content languages contain it.
Lang string
// Limit stops after this many written rows. Zero means no limit.
Limit int64
}
SeedExportOptions filters which captures become seed rows.
func DefaultSeedExportOptions ¶ added in v0.3.0
func DefaultSeedExportOptions() SeedExportOptions
DefaultSeedExportOptions keeps successful captures only, which is almost always what a recrawl wants as a starting list.
type SeedExportStats ¶ added in v0.3.0
SeedExportStats reports how a shard projected into seed rows.
func ExportSeedFromCDX ¶ added in v0.3.0
func ExportSeedFromCDX(ctx context.Context, shardPath string, opt SeedExportOptions, write func(SeedRow) error) (SeedExportStats, error)
ExportSeedFromCDX streams a CDX URL-index shard at shardPath, projects each matching capture to a SeedRow, and hands it to write. It performs no network and no aggregation: one capture becomes at most one seed row, in file order, so the output streams in constant memory regardless of shard size.
type SeedRow ¶ added in v0.3.0
type SeedRow struct {
URL string `parquet:"url" json:"url"`
Digest string `parquet:"digest" json:"digest,omitempty"`
Host string `parquet:"host" json:"host,omitempty"`
MIME string `parquet:"mime" json:"mime,omitempty"`
Lang string `parquet:"lang" json:"lang,omitempty"`
Status int32 `parquet:"status" json:"status,omitempty"`
Time string `parquet:"time" json:"time,omitempty"`
}
SeedRow is the generic seed projection of one CDX capture: a URL plus the few hints a downstream recrawler can use. The column names are deliberately plain (url, digest, host, ...) so the file is a generic seed and carries nothing specific to its origin. A recrawler reads "url" and "digest" and treats every other string column as opaque metadata.
type ServeConfig ¶ added in v0.2.0
type ServeConfig struct {
Addr string // e.g. ":8080"
DBPath string // path to DuckDB/SQLite host database (optional)
IndexDir string // path to the inverted index directory (optional)
}
ServeConfig holds configuration for the HTTP API server.
type StreamingParquetWriter ¶ added in v0.4.0
type StreamingParquetWriter struct {
// contains filtered or unexported fields
}
StreamingParquetWriter writes dynamically-shaped rows to a zstd-compressed Parquet stream. Unlike ParquetWriter, the schema is not known at compile time: it is derived from the first row's column names, so any command's projected output can be emitted as Parquet without a hand-written struct. Every column is an optional UTF-8 string, matching the string projection the render layer hands us. This is the encoder behind "-o parquet".
func NewStreamingParquetWriter ¶ added in v0.4.0
func NewStreamingParquetWriter(dest io.Writer) *StreamingParquetWriter
NewStreamingParquetWriter returns a writer that emits Parquet to dest. The schema is built lazily from the first EmitRow call.
func (*StreamingParquetWriter) Close ¶ added in v0.4.0
func (s *StreamingParquetWriter) Close() error
Close flushes and finalizes the Parquet stream. It is safe to call when no row was ever emitted.
func (*StreamingParquetWriter) EmitRow ¶ added in v0.4.0
func (s *StreamingParquetWriter) EmitRow(cols, vals []string) error
EmitRow writes one projected row. The first call defines the schema from cols.
type TextResult ¶ added in v0.2.0
type TextResult struct {
Title string
Description string // <meta name="description">
CanonURL string // canonical URL from meta or link[rel=canonical]
Body string // extracted clean body text
WordCount int
Language string // BCP-47 code inferred from lang attribute
}
TextResult holds the output of HTML-to-text extraction.
func ExtractContent ¶ added in v0.2.0
func ExtractContent(htmlBytes []byte) TextResult
ExtractContent parses HTML bytes and returns a TextResult with clean text, title, description, canonical URL, and inferred language.
type URLDatasetRow ¶ added in v0.2.3
type URLDatasetRow struct {
// CDX identity
Host string `parquet:"host,dict"`
RD string `parquet:"rd,dict"`
TLD string `parquet:"tld,dict"`
Proto string `parquet:"proto,dict"`
URL string `parquet:"url"`
Surt string `parquet:"surt"`
// CDX fetch result
ST int32 `parquet:"st"`
Redir string `parquet:"redir"`
Digest string `parquet:"digest,dict"`
// CDX content
MIME string `parquet:"mime,dict"`
MIMEDecl string `parquet:"mime_d,dict"`
Charset string `parquet:"charset,dict"`
Lang string `parquet:"lang,dict"`
Trunc string `parquet:"trunc,dict"`
// CDX timing and size
TS string `parquet:"ts,dict"`
Bytes int64 `parquet:"bytes"`
// CDX WARC location (for byte-range content fetch)
WARCFile string `parquet:"warc_f,dict"`
WARCOff int64 `parquet:"warc_o"`
RobotsOK bool `parquet:"robots_ok"`
Crawl string `parquet:"crawl,dict"`
// Rank signals (joined from rank table by host)
GraphID string `parquet:"graph_id,dict"`
HarmonicPos int64 `parquet:"harmonic_pos"`
HarmonicVal float64 `parquet:"harmonic_val"`
PageRankPos int64 `parquet:"pagerank_pos"`
PageRankVal float64 `parquet:"pagerank_val"`
}
URLDatasetRow is the Parquet schema for one row of the public cc-host-dataset. Each row is one URL capture from the CC CDX index, enriched with host rank signals. No aggregation — callers GROUP BY host to compute per-host statistics.
type VertexRecord ¶ added in v0.2.0
type VertexRecord struct {
ID int64 `json:"id" kit:"id" table:"id"`
HostRev string `json:"host_rev" table:"host_rev"`
Host string `json:"host" table:"host"`
}
VertexRecord is one row from the host vertices files: a numeric graph ID and the host name in reversed form (com.example.www).
type WARCExporter ¶ added in v0.4.0
type WARCExporter struct {
Files []string // paths written, in order
// contains filtered or unexported fields
}
WARCExporter writes captured WARC records into one or more standards compliant .warc.gz files. Each file opens with a warcinfo record carrying the provenance, and the exporter rotates to a new file once the current one passes maxSize bytes. Records are written as their original gzip members, so the output round-trips through ccrawl parse unchanged.
func NewWARCExporter ¶ added in v0.4.0
func NewWARCExporter(dir, prefix, subprefix string, maxSize int64, info WARCInfo) *WARCExporter
NewWARCExporter builds an exporter that writes into dir. An empty or negative maxSize falls back to DefaultWARCSize.
func (*WARCExporter) Close ¶ added in v0.4.0
func (e *WARCExporter) Close() error
Close flushes and closes the current file. It is safe to call when nothing was written.
func (*WARCExporter) Records ¶ added in v0.4.0
func (e *WARCExporter) Records() int
Records reports how many capture records have been written so far.
func (*WARCExporter) Write ¶ added in v0.4.0
func (e *WARCExporter) Write(raw []byte) error
Write appends one raw WARC record (an original gzip member fetched by byte range) to the current file, rotating first if it would overflow maxSize.
type WARCInfo ¶ added in v0.4.0
type WARCInfo struct {
Software string // tool and version, e.g. "ccrawl/0.4.0"
IsPartOf string // prefix, with the subprefix appended when set
Description string // the exact command line used
Format string // e.g. "WARC file version 1.0"
Creator string // optional: a person, organization, or service
Operator string // optional: a person, when the creator is an organization
}
WARCInfo is the provenance written into each exported WARC file's warcinfo record. It mirrors the fields cdx_toolkit writes so the output is self describing: which tool made it, from what, and with which command.
type WARCParquetRow ¶
type WARCParquetRow struct {
RecordID string `parquet:"record_id,dict"`
CrawlID string `parquet:"crawl_id,dict"`
WARCType string `parquet:"warc_type,dict"`
TargetURI string `parquet:"target_uri"`
Date time.Time `parquet:"date,timestamp(microsecond)"`
IPAddress string `parquet:"ip_address,dict"`
PayloadDigest string `parquet:"payload_digest"`
ContentType string `parquet:"content_type,dict"`
ContentLength int64 `parquet:"content_length"`
Truncated string `parquet:"truncated,dict"`
HTTPStatus int32 `parquet:"http_status"`
HTTPMIME string `parquet:"http_mime,dict"`
WARCFilename string `parquet:"warc_filename,dict"`
WARCOffset int64 `parquet:"warc_offset"`
WARCLength int64 `parquet:"warc_length"`
Title string `parquet:"title"`
Language string `parquet:"language,dict"`
Markdown string `parquet:"markdown"`
Text string `parquet:"text"`
}
WARCParquetRow is the columnar schema for parsed WARC record metadata. When a response body is converted, the content fields are populated too.
type WARCRecord ¶
WARCRecord is a parsed WARC record: its header and the raw block bytes. For a response record the block is the full HTTP message (status line, headers, body).
func FetchWARCRecord ¶
func FetchWARCRecord(ctx context.Context, h *HTTPClient, filename string, offset, length int64) (WARCRecord, error)
FetchWARCRecord retrieves a single WARC record from the given file using a byte-range request. This is how a capture's content is pulled without downloading the whole multi-gigabyte WARC.
type WARCURLRecord ¶ added in v0.3.0
WARCURLRecord is one URL extracted from a WARC shard during phase 1.
type WATLink ¶
WATLink is a hyperlink extracted from page HTML.
func ExtractLinks ¶
ExtractLinks returns the outbound hyperlinks of an HTML document, resolved against base when possible.
type WATParquetRow ¶
type WATParquetRow struct {
RecordID string `parquet:"record_id,dict"`
CrawlID string `parquet:"crawl_id,dict"`
URL string `parquet:"url"`
Date time.Time `parquet:"date,timestamp(microsecond)"`
HTTPStatus int32 `parquet:"http_status"`
ContentType string `parquet:"content_type,dict"`
Title string `parquet:"title"`
LinksCount int32 `parquet:"links_count"`
Links string `parquet:"links"` // JSON
Metas string `parquet:"metas"` // JSON
}
WATParquetRow is the columnar schema for WAT link and metadata records.
type WETParquetRow ¶
type WETParquetRow struct {
RecordID string `parquet:"record_id,dict"`
CrawlID string `parquet:"crawl_id,dict"`
URL string `parquet:"url"`
Date time.Time `parquet:"date,timestamp(microsecond)"`
ContentLanguage string `parquet:"content_language,dict"`
TextLength int32 `parquet:"text_length"`
Text string `parquet:"text"`
}
WETParquetRow is the columnar schema for WET plain-text records.
type WebGraph ¶ added in v0.2.0
type WebGraph struct {
ID string // e.g. cc-main-2026-mar-apr-may
BaseURL string // https://data.commoncrawl.org/projects/hyperlinkgraph/{ID}/
HostNodes int64
HostArcs int64
Published string
}
WebGraph describes one Common Crawl web-graph release.
func LatestWebGraph ¶ added in v0.2.0
LatestWebGraph fetches the CC web-graphs index page and returns the most recent host-level graph release. Results are cached for 24 hours.
func (WebGraph) HostEdgesManifestURL ¶ added in v0.2.0
HostEdgesManifestURL is the manifest listing edge part files.
func (WebGraph) HostRankURL ¶ added in v0.2.0
HostRankURL is the single gzipped rank table for hosts.
func (WebGraph) HostVerticesManifestURL ¶ added in v0.2.0
HostVerticesManifestURL is the manifest listing vertex part files.
Source Files
¶
- cache.go
- cdx.go
- client.go
- columnar.go
- config.go
- content.go
- crawl.go
- crawls.go
- diskfree_unix.go
- download.go
- export.go
- extract.go
- hf.go
- hf_readme.go
- host.go
- host_dataset.go
- host_dataset_raw.go
- host_dataset_seq.go
- index.go
- library.go
- markdown.go
- markdown_readme.go
- markdown_run.go
- news.go
- parquet.go
- parquet_stream.go
- rank.go
- refetch.go
- refetch_run.go
- rlimit_unix.go
- sched.go
- seed_export.go
- serve.go
- source.go
- surt.go
- types.go
- util.go
- warc.go
- warc_cache.go
- wat.go
- webgraph.go
- wet.go