Download merge_full_index.py from HuggingFaceBio/carbon-a-database-explorer: direct link, hf CLI and curl.
- Browser
- Download file 4.77 kB
-
https://huggingface.co/spaces/HuggingFaceBio/carbon-a-database-explorer/resolve/refs%2Fpr%2F6/merge_full_index.py
- Command line
-
hf download hf://spaces/HuggingFaceBio/carbon-a-database-explorer@refs/pr/6/merge_full_index.py
-
curl -L -o merge_full_index.py https://huggingface.co/spaces/HuggingFaceBio/carbon-a-database-explorer/resolve/refs%2Fpr%2F6/merge_full_index.py
4.77 kB
| """Merge disjoint compact-index partitions and validate their inventory.""" | |
| import argparse | |
| from datetime import datetime, timezone | |
| import hashlib | |
| import json | |
| from pathlib import Path | |
| import sqlite3 | |
| from compact_index import DDL, finalize_indexes | |
| from remote_catalog import BUCKET | |
| def main(): | |
| p=argparse.ArgumentParser(description=__doc__) | |
| p.add_argument('--inventory',type=Path,required=True) | |
| p.add_argument('--parts',type=Path,nargs='+',required=True) | |
| p.add_argument('--output',type=Path,required=True) | |
| args=p.parse_args() | |
| work=args.output.with_suffix('.merging.sqlite') | |
| work.unlink(missing_ok=True) | |
| c=sqlite3.connect(work) | |
| c.execute('PRAGMA journal_mode=OFF'); c.execute('PRAGMA synchronous=OFF') | |
| c.execute('PRAGMA cache_size=-262144'); c.executescript(DDL) | |
| file_offset=row_offset=0 | |
| for path in args.parts: | |
| c.execute('ATTACH DATABASE ? AS part',(str(path),)) | |
| manifest=json.loads(c.execute("SELECT value FROM part.metadata WHERE key='manifest'").fetchone()[0]) | |
| if manifest.get('schema_version')!=3: raise ValueError(f'Unexpected schema in {path}') | |
| c.execute('INSERT OR IGNORE INTO contexts(assembly_accession,assembly_base,metadata_json) SELECT assembly_accession,assembly_base,metadata_json FROM part.contexts') | |
| c.execute('CREATE TEMP TABLE context_map(old INTEGER PRIMARY KEY,new INTEGER)') | |
| c.execute('INSERT INTO context_map SELECT p.id,c.id FROM part.contexts p JOIN contexts c ON c.metadata_json=p.metadata_json') | |
| c.execute('INSERT INTO files SELECT id+?,path,hash,size,rows,row_groups,max_group_bytes,bytes_read,range_reads FROM part.files',(file_offset,)) | |
| c.execute('''INSERT INTO segment_data SELECT s.id+?,s.record_name,s.record_base,s.segment_start_bp,s.segment_end_bp, | |
| s.aligned_bp_length,s.segment_index,s.segment_count,s.file_id+?,s.row_group,s.row_in_group,m.new,s.source_key | |
| FROM part.segment_data s JOIN context_map m ON m.old=s.context_id''',(row_offset,file_offset)) | |
| file_offset=c.execute('SELECT max(id) FROM files').fetchone()[0] or 0 | |
| row_offset=c.execute('SELECT max(id) FROM segment_data').fetchone()[0] or 0 | |
| c.execute('DROP TABLE context_map'); c.commit(); c.execute('DETACH DATABASE part') | |
| print('Merged',path,'last_row',row_offset,flush=True) | |
| expected={r['path']:(r['hash'],r['size']) for r in map(json.loads,args.inventory.open())} | |
| actual={r[0]:(r[1],r[2]) for r in c.execute('SELECT path,hash,size FROM files')} | |
| if actual!=expected: raise ValueError('Merged object inventory does not match listing') | |
| print('Building search indexes',flush=True) | |
| finalize_indexes(c); c.commit() | |
| rows,bases=c.execute('SELECT count(*),sum(segment_end_bp-segment_start_bp) FROM segment_data').fetchone() | |
| if rows!=c.execute('SELECT sum(rows) FROM files').fetchone()[0]: raise ValueError('Row totals differ') | |
| assemblies=[r[0] for r in c.execute('SELECT DISTINCT assembly_accession FROM contexts ORDER BY assembly_accession')] | |
| examples={} | |
| for cid,encoded in c.execute('SELECT id,metadata_json FROM contexts'): | |
| division=json.loads(encoded)['division'] | |
| if division not in examples: | |
| row=c.execute('SELECT record_name FROM segment_data WHERE context_id=? ORDER BY id LIMIT 1',(cid,)).fetchone() | |
| if row: examples[division]=row[0] | |
| manifest={'schema_version':3,'bucket_id':BUCKET,'created_at':datetime.now(timezone.utc).isoformat(), | |
| 'scope':'All published annotation Parquet objects in the dated inventory; assemblies may be partial.', | |
| 'full_snapshot':True,'source_count':len(expected),'sources':[], | |
| 'source_ledger':'SQLite files table contains every object path, hash, size and row-group summary.', | |
| 'rows':rows,'bases':bases,'assemblies':assemblies,'divisions':sorted(examples), | |
| 'example_record_names':list(examples.values()), | |
| 'inventory_sha256':hashlib.sha256(args.inventory.read_bytes()).hexdigest(), | |
| 'inventory_at':datetime.fromtimestamp(args.inventory.stat().st_mtime,timezone.utc).isoformat()} | |
| c.execute("INSERT OR REPLACE INTO metadata VALUES ('manifest',?)",(json.dumps(manifest),)); c.commit() | |
| if c.execute('PRAGMA quick_check').fetchone()[0]!='ok': raise ValueError('SQLite check failed') | |
| c.execute('PRAGMA journal_mode=DELETE'); c.close(); work.replace(args.output) | |
| report={k:v for k,v in manifest.items() if k!='assemblies'} | |
| report.update(assembly_count=len(assemblies),index_bytes=args.output.stat().st_size) | |
| args.output.with_suffix('.report.json').write_text(json.dumps(report,indent=2)+'\n') | |
| print(json.dumps(report),flush=True) | |
| if __name__=='__main__': main() | |