backingstore: add backingstore struct

Summary:
This diff adds a new crate `backingstore` that is responsible to help Eden to read data from hgcache.

This diff only implements the initialization logic where it loads the path from hg's configuration files. This diff also contains a struct `CFallible` to help us handling errors from Rust in C++.

Reviewed By: xavierd

Differential Revision: D17593226

fbshipit-source-id: 3dfa8b2b13553cf49ecadd2a589f0ce2e25524b5
This commit is contained in:
Zeyi (Rice) Fan 2019-10-19 18:46:34 -07:00 committed by Facebook Github Bot
parent 4bf54d3d37
commit a045d9538d
8 changed files with 147 additions and 1 deletions

View File

@ -5,5 +5,8 @@ authors = ["Facebook Source Control Team <sourcecontrol-dev@fb.com>"]
edition = "2018"
[dependencies]
revisionstore = { path = "../revisionstore" }
configparser = { path = "../configparser" }
bytes = "*"
failure = "*"
libc = "*"

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/
#include "scm/hg/lib/backingstore/c_api/HgNativeBackingStore.h"
#include <folly/Range.h>
#include <memory>
#include <stdexcept>
#include "scm/hg/lib/backingstore/c_api/RustBackingStore.h"
namespace facebook {
namespace eden {
HgNativeBackingStore::HgNativeBackingStore(folly::StringPiece repository) {
RustCFallible<RustBackingStore> store(
rust_backingstore_new(repository.data(), repository.size()),
rust_backingstore_free);
if (store.isError()) {
throw std::runtime_error(store.getError());
}
store_ = store.unwrap();
}
} // namespace eden
} // namespace facebook

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/
#pragma once
#include <folly/Range.h>
#include <memory>
#include "scm/hg/lib/backingstore/c_api/RustBackingStore.h"
namespace facebook {
namespace eden {
class HgNativeBackingStore {
public:
explicit HgNativeBackingStore(folly::StringPiece repository);
private:
std::unique_ptr<RustBackingStore, std::function<void(RustBackingStore*)>>
store_;
};
} // namespace eden
} // namespace facebook

View File

@ -7,7 +7,7 @@
* This file is generated with cbindgen. Please run `./tools/cbindgen.sh` to
* update this file.
*
* @generated SignedSource<<b6ea2b8425b6c250eefd001f49810f72>>
* @generated SignedSource<<c6051bcd5d2d58ea14574bd2ed931e19>>
*
*/
@ -75,8 +75,15 @@ public:
#include <cstdlib>
#include <new>
struct RustBackingStore;
extern "C" {
void rust_backingstore_free(RustBackingStore *store);
RustCFallibleBase rust_backingstore_new(const char *repository,
size_t repository_len);
void rust_cfallible_free_error(char *ptr);
/// Returns a `CFallible` with error message "failure!". This function is intended to be called

View File

@ -0,0 +1,28 @@
// Copyright 2019 Facebook, Inc.
//
// This software may be used and distributed according to the terms of the
// GNU General Public License version 2 or any later version.
use configparser::config::ConfigSet;
use configparser::hg::ConfigSetHgExt;
use failure::Fallible;
use revisionstore::ContentStore;
use std::path::Path;
pub struct BackingStore {
#[allow(dead_code)]
store: ContentStore,
}
impl BackingStore {
pub fn new<P: AsRef<Path>>(repository: P) -> Fallible<Self> {
let mut config = ConfigSet::new();
config.load_system();
config.load_user();
config.load_hgrc(repository.as_ref().join(".hg").join("hgrc"), "repository");
let store = ContentStore::new(repository, &config, None)?;
Ok(Self { store })
}
}

View File

@ -3,4 +3,13 @@
// This software may be used and distributed according to the terms of the
// GNU General Public License version 2 or any later version.
//! backingstore - The crate provides backing store interface for EdenFS.
//!
//! This crate aims to provide EdenFS's backing store interface so EdenFS could use types in this
//! crate to import SCM blobs and trees directly from Mercurial's data store.
//!
//! The C++ code in `c_api` directory encapsulate Rust functions exposed from this crate into
//! regular C++ classes.
mod backingstore;
mod raw;

View File

@ -0,0 +1,44 @@
// Copyright 2019 Facebook, Inc.
//
// This software may be used and distributed according to the terms of the
// GNU General Public License version 2 or any later version.
//! Provides the c-bindings for `crate::backingstore`.
use failure::{ensure, Fallible};
use libc::{c_char, size_t};
use std::{slice, str};
use crate::backingstore::BackingStore;
use crate::raw::CFallible;
fn stringpiece_to_slice<'a>(ptr: *const c_char, length: size_t) -> Fallible<&'a [u8]> {
ensure!(!ptr.is_null(), "string ptr is null");
Ok(unsafe { slice::from_raw_parts(ptr as *const u8, length) })
}
fn backingstore_new(
repository: *const c_char,
repository_len: size_t,
) -> Fallible<*mut BackingStore> {
let repository = stringpiece_to_slice(repository, repository_len)?;
let repo = str::from_utf8(repository)?;
let store = Box::new(BackingStore::new(repo)?);
Ok(Box::into_raw(store))
}
#[no_mangle]
pub extern "C" fn rust_backingstore_new(
repository: *const c_char,
repository_len: size_t,
) -> CFallible<BackingStore> {
backingstore_new(repository, repository_len).into()
}
#[no_mangle]
pub extern "C" fn rust_backingstore_free(store: *mut BackingStore) {
assert!(!store.is_null());
let store = unsafe { Box::from_raw(store) };
drop(store);
}

View File

@ -8,6 +8,7 @@
//! the function is written in Rust. Changes to this mod may need regenerations of the C/C++
//! binding header. To regenerate the binding header, run `./tools/cbindgen.sh`.
mod backingstore;
mod cfallible;
mod tests;