diff --git a/src/merk/mod.rs b/src/merk/mod.rs index bfc6cec..88834b2 100644 --- a/src/merk/mod.rs +++ b/src/merk/mod.rs @@ -86,9 +86,8 @@ impl Merk { let mut db = rocksdb::DB::open_cf_descriptors(&db_opts, &path_buf, column_families())?; let format_version = load_format_version(&db)?; - let has_root = load_root(&db)?.is_some(); - if has_root { + if has_root(&db)? { if format_version == 0 { log::info!("Migrating store from version 0 to {}...", FORMAT_VERSION); @@ -305,54 +304,29 @@ impl Merk { } pub fn migrate_from_v0>(path: P) -> Result<()> { - use rocksdb::IteratorMode; - let path = path.as_ref().to_path_buf(); let db = - rocksdb::DB::open_cf_descriptors(&Merk::default_db_opts(), &path, column_families())?; - - let create_path = |suffix| { - let mut tmp_path = path.clone(); - let tmp_file_name = - format!("{}-{}", path.file_name().unwrap().to_str().unwrap(), suffix); - tmp_path.set_file_name(tmp_file_name); - tmp_path - }; + rocksdb::DB::open_cf_descriptors(&Merk::default_db_opts(), path, column_families())?; - let tmp_path = create_path("migrate1"); - let tmp = Merk::open(&tmp_path)?; - tmp.destroy()?; + let mut iter = db.raw_iterator(); + iter.seek_to_first(); - // TODO: split up batch - let batch: Vec<_> = db - .iterator(IteratorMode::Start) - .map(|entry| -> Result<_> { - dbg!(); - let (key, node_bytes) = entry.unwrap(); // TODO - dbg!(&key, node_bytes.len()); - let node = Tree::decode_v0(&mut &node_bytes[..])?; - dbg!(); - Ok((key.to_vec(), Op::Put(node.value().to_vec()))) - }) - .collect::>()?; + while iter.valid() { + let key = iter.key().unwrap(); + let mut value = iter.value().unwrap(); - let aux_cf = db.cf_handle(AUX_CF_NAME).unwrap(); - let aux: Vec<_> = db - .iterator_cf(aux_cf, IteratorMode::Start) - .map(|entry| { - let (key, value) = entry.unwrap(); // TODO - (key.to_vec(), Op::Put(value.to_vec())) - }) - .collect(); + let node = Tree::decode_v0(&mut value)?; + let new_value = node.encode(); + db.put(key, new_value.as_slice())?; - let mut tmp = Self::open(&tmp_path)?; - tmp.apply(&batch, &aux)?; - drop(tmp); + iter.next(); + } - let tmp_path2 = create_path("migrate2"); - std::fs::rename(&path, &tmp_path2)?; - std::fs::rename(&tmp_path, &path)?; - std::fs::remove_dir_all(&tmp_path2)?; + db.put_cf( + db.cf_handle(INTERNAL_CF_NAME).unwrap(), + FORMAT_VERSION_KEY, + FORMAT_VERSION.to_be_bytes(), + )?; Ok(()) } @@ -578,6 +552,11 @@ where Ok(bytes) } +fn has_root(db: &DB) -> Result { + let internal_cf = db.cf_handle(INTERNAL_CF_NAME).unwrap(); + Ok(db.get_pinned_cf(internal_cf, ROOT_KEY_KEY)?.is_some()) +} + fn load_root(db: &DB) -> Result> { let internal_cf = db.cf_handle(INTERNAL_CF_NAME).unwrap(); db.get_pinned_cf(internal_cf, ROOT_KEY_KEY)?