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 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 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 FileURL(path string, src Source) string
- func GenerateDatasetREADME(s DatasetStats) string
- func HFShardPath(crawlID, subset, prefix string) 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 LoadCDXRawPrefix(workDir, prefix string, fn func(CDXRawOutputRow) error) error
- func NormalizeURL(raw string) string
- func ParquetListLiteral(urls []string) string
- 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 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 Library
- type Location
- type MemHostStore
- type NewWARCRecord
- type NewsFile
- type ParquetWriter
- type PostingEntry
- type QualityResult
- type Rank
- type RateLimitError
- type RobotsCache
- type RobotsEntry
- type RobotsRule
- type ScoredDoc
- type SearchResult
- type SearchStore
- type ServeConfig
- type Source
- type TextResult
- type URLDatasetRow
- type VertexRecord
- type WARCHeader
- type WARCParquetRow
- type WARCRecord
- 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 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 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 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 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 HFShardPath ¶ added in v0.2.4
HFShardPath returns the canonical HF repo path for a prefix shard. Uses Hive-partition layout so DuckDB reads with hive_partitioning=true, automatically extracting `crawl` and `subset` as virtual columns:
data/crawl=CC-MAIN-2026-21/subset=urls/hosts-a.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 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 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 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 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
}
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 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 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 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 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 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 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 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 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.