Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pyo3v021 #118

Merged
merged 3 commits into from
Mar 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,14 @@ crate-type = ["cdylib"]
[dependencies]
rocksdb = { git = "https://github.com/Congyuwang/rust-rocksdb", tag = "v0.22.0+8.10.0" }
librocksdb-sys = { git = "https://github.com/Congyuwang/rust-rocksdb", tag = "v0.22.0+8.10.0" }
pyo3-log = "0.9"
log = "0.4"
serde = { version = "1", features = ["derive"] }
serde_json = "1.0.87"
num-bigint = "^0.4.3"
libc = "0.2.112"
serde_json = "1"
num-bigint = "0.4"
libc = "0.2"

[dependencies.pyo3]
version = "0.20"
version = "0.21"
features = ["extension-module", "num-bigint"]

[profile.release]
Expand Down
41 changes: 21 additions & 20 deletions src/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub(crate) enum ValueTypes<'a, 'b> {
Int(BigInt),
Float(f64),
Bool(bool),
Any(&'b PyAny),
Any(&'a Bound<'b, PyAny>),
}

#[inline(always)]
Expand All @@ -26,9 +26,9 @@ pub(crate) fn encoding_byte(v_type: &ValueTypes) -> u8 {
}

#[inline(always)]
pub(crate) fn encode_key(key: &PyAny, raw_mode: bool) -> PyResult<Cow<[u8]>> {
pub(crate) fn encode_key<'a>(key: &'a Bound<PyAny>, raw_mode: bool) -> PyResult<Cow<'a, [u8]>> {
if raw_mode {
return if let Ok(value) = <PyBytes as PyTryFrom>::try_from(key) {
return if let Ok(value) = key.downcast::<PyBytes>() {
Ok(Cow::Borrowed(value.as_bytes()))
} else {
Err(PyKeyError::new_err("raw mode only support bytes"))
Expand Down Expand Up @@ -65,12 +65,12 @@ pub(crate) fn encode_key(key: &PyAny, raw_mode: bool) -> PyResult<Cow<[u8]>> {
///
#[inline(always)]
pub(crate) fn encode_value<'a>(
value: &'a PyAny,
value: &'a Bound<PyAny>,
dumps: &PyObject,
raw_mode: bool,
) -> PyResult<Cow<'a, [u8]>> {
if raw_mode {
if let Ok(value) = <PyBytes as PyTryFrom>::try_from(value) {
if let Ok(value) = value.downcast::<PyBytes>() {
Ok(Cow::Borrowed(value.as_bytes()))
} else {
Err(PyValueError::new_err("raw mode only support bytes"))
Expand All @@ -91,31 +91,32 @@ pub(crate) fn encode_value<'a>(
concat_type_encoding(type_encoding, if value { &[1u8] } else { &[0u8] })
}
ValueTypes::Any(value) => {
let pickle_bytes: Vec<u8> =
Python::with_gil(|py| dumps.call1(py, (value,))?.extract(py))?;
concat_type_encoding(type_encoding, &pickle_bytes[..])
let py = value.py();
let pickle_bytes = dumps.call1(py, (value,))?;
let bytes: &[u8] = pickle_bytes.downcast_bound::<PyBytes>(py)?.as_bytes();
concat_type_encoding(type_encoding, bytes)
}
};
Ok(Cow::Owned(owned_bytes))
}
}

#[inline(always)]
fn py_to_value_types(value: &PyAny) -> PyResult<ValueTypes> {
if let Ok(value) = <PyBool as PyTryFrom>::try_from(value) {
fn py_to_value_types<'a, 'b>(value: &'a Bound<'b, PyAny>) -> PyResult<ValueTypes<'a, 'b>> {
if let Ok(value) = value.downcast::<PyBool>() {
return Ok(ValueTypes::Bool(value.extract()?));
}
if let Ok(value) = <PyBytes as PyTryFrom>::try_from(value) {
if let Ok(value) = value.downcast::<PyBytes>() {
return Ok(ValueTypes::Bytes(value.as_bytes()));
}
if let Ok(value) = <PyString as PyTryFrom>::try_from(value) {
if let Ok(value) = value.downcast::<PyString>() {
return Ok(ValueTypes::String(value.to_string()));
}
if let Ok(value) = <PyInt as PyTryFrom>::try_from(value) {
if let Ok(value) = value.downcast::<PyInt>() {
return Ok(ValueTypes::Int(value.extract()?));
}
if let Ok(value) = <PyFloat as PyTryFrom>::try_from(value) {
return Ok(ValueTypes::Float(value.extract()?));
if let Ok(value) = value.downcast::<PyFloat>() {
return Ok(ValueTypes::Float(value.value()));
}
Ok(ValueTypes::Any(value))
}
Expand All @@ -130,18 +131,18 @@ pub(crate) fn decode_value(
) -> PyResult<PyObject> {
// directly return bytes if raw_mode is true
if raw_mode {
return Ok(PyBytes::new(py, bytes).to_object(py));
return Ok(PyBytes::new_bound(py, bytes).to_object(py));
}
match bytes.first() {
None => Err(PyException::new_err("Unknown value type")),
Some(byte) => match byte {
1 => Ok(PyBytes::new(py, &bytes[1..]).to_object(py)),
1 => Ok(PyBytes::new_bound(py, &bytes[1..]).to_object(py)),
2 => {
let string = match String::from_utf8(bytes[1..].to_vec()) {
Ok(s) => s,
Err(_) => return Err(PyException::new_err("utf-8 decoding error")),
};
Ok(string.into_py(py))
Ok(PyString::new_bound(py, &string).to_object(py))
}
3 => {
let big_int = BigInt::from_signed_bytes_be(&bytes[1..]);
Expand All @@ -151,8 +152,8 @@ pub(crate) fn decode_value(
let float: f64 = f64::from_be_bytes(bytes[1..].try_into().unwrap());
Ok(float.into_py(py))
}
5 => Ok((bytes[1] != 0).to_object(py)),
6 => loads.call1(py, (PyBytes::new(py, &bytes[1..]),)),
5 => Ok(PyBool::new_bound(py, bytes[1] != 0).to_object(py)),
6 => loads.call1(py, (PyBytes::new_bound(py, &bytes[1..]),)),
_ => Err(PyException::new_err("Unknown value type")),
},
}
Expand Down
6 changes: 3 additions & 3 deletions src/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ impl RdictIter {
///
/// del iter, db
/// Rdict.destroy(path, Options())
pub fn seek(&mut self, key: &PyAny) -> PyResult<()> {
pub fn seek(&mut self, key: &Bound<PyAny>) -> PyResult<()> {
let key = encode_key(key, self.raw_mode)?;
unsafe {
librocksdb_sys::rocksdb_iter_seek(
Expand Down Expand Up @@ -224,7 +224,7 @@ impl RdictIter {
///
/// del iter, db
/// Rdict.destroy(path, Options())
pub fn seek_for_prev(&mut self, key: &PyAny) -> PyResult<()> {
pub fn seek_for_prev(&mut self, key: &Bound<PyAny>) -> PyResult<()> {
let key = encode_key(key, self.raw_mode)?;
unsafe {
librocksdb_sys::rocksdb_iter_seek_for_prev(
Expand Down Expand Up @@ -321,7 +321,7 @@ macro_rules! impl_iter {
}

impl $iter_name {
pub(crate) fn new(inner: RdictIter, backwards: bool, from_key: Option<&PyAny>) -> PyResult<Self> {
pub(crate) fn new(inner: RdictIter, backwards: bool, from_key: Option<&Bound<PyAny>>) -> PyResult<Self> {
let mut inner = inner;
if let Some(from_key) = from_key {
if backwards {
Expand Down
5 changes: 2 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ use pyo3::prelude::*;
/// supports `pickle`.
///
#[pymodule]
fn rocksdict(py: Python, m: &PyModule) -> PyResult<()> {
fn rocksdict(py: Python, m: &Bound<PyModule>) -> PyResult<()> {
m.add_class::<Rdict>()?;
m.add_class::<OptionsPy>()?;
m.add_class::<MemtableFactoryPy>()?;
Expand Down Expand Up @@ -144,8 +144,7 @@ fn rocksdict(py: Python, m: &PyModule) -> PyResult<()> {
m.add_class::<ChecksumTypePy>()?;
m.add_class::<KeyEncodingTypePy>()?;

m.add("DbClosedError", py.get_type::<DbClosedError>())?;
m.add("DbClosedError", py.get_type_bound::<DbClosedError>())?;

pyo3_log::init();
Ok(())
}
24 changes: 12 additions & 12 deletions src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -614,11 +614,11 @@ impl OptionsPy {
let (options, column_families) =
OptionsPy::load_latest_inner(path, env, ignore_unknown_options, cache)?;
let options = Py::new(py, options)?;
let columns = PyDict::new(py);
let columns = PyDict::new_bound(py);
for (name, opt) in column_families {
columns.set_item(name, Py::new(py, opt)?)?
}
let returned_tuple = PyTuple::new(py, [options.to_object(py), columns.to_object(py)]);
let returned_tuple = PyTuple::new_bound(py, [options.to_object(py), columns.to_object(py)]);
Ok(returned_tuple.to_object(py))
}

Expand Down Expand Up @@ -745,10 +745,10 @@ impl OptionsPy {
/// flash_path = DBPath("/flash_path", 10 * 1024 * 1024 * 1024) # 10 GB
/// hard_drive = DBPath("/hard_drive", 2 * 1024 * 1024 * 1024 * 1024) # 2 TB
/// opt.set_db_paths([flash_path, hard_drive])
pub fn set_db_paths(&mut self, paths: &PyList) -> PyResult<()> {
pub fn set_db_paths(&mut self, paths: &Bound<PyList>) -> PyResult<()> {
let mut db_paths = Vec::with_capacity(paths.len());
for p in paths.iter() {
let path: &PyCell<DBPathPy> = PyTryFrom::try_from(p)?;
let path: &Bound<DBPathPy> = p.downcast()?;
db_paths.push(
match DBPath::new(&path.borrow().path, path.borrow().target_size) {
Ok(p) => p,
Expand Down Expand Up @@ -805,10 +805,10 @@ impl OptionsPy {
/// DBCompressionType.snappy(),
/// DBCompressionType.snappy()
/// ])
pub fn set_compression_per_level(&mut self, level_types: &PyList) -> PyResult<()> {
pub fn set_compression_per_level(&mut self, level_types: &Bound<PyList>) -> PyResult<()> {
let mut result = Vec::with_capacity(level_types.len());
for py_any in level_types.iter() {
let level_type: &PyCell<DBCompressionTypePy> = PyTryFrom::try_from(py_any)?;
let level_type: &Bound<DBCompressionTypePy> = py_any.downcast()?;
result.push(level_type.borrow().0)
}
self.inner_opt.set_compression_per_level(&result);
Expand Down Expand Up @@ -1960,13 +1960,13 @@ impl ReadOptionsPy {
}

/// Sets the upper bound for an iterator.
pub fn set_iterate_upper_bound(&mut self, key: &PyAny, py: Python) -> PyResult<()> {
pub fn set_iterate_upper_bound(&mut self, key: &Bound<PyAny>, py: Python) -> PyResult<()> {
self.iterate_upper_bound = key.to_object(py);
Ok(())
}

/// Sets the lower bound for an iterator.
pub fn set_iterate_lower_bound(&mut self, key: &PyAny, py: Python) -> PyResult<()> {
pub fn set_iterate_lower_bound(&mut self, key: &Bound<PyAny>, py: Python) -> PyResult<()> {
self.iterate_upper_bound = key.to_object(py);
Ok(())
}
Expand Down Expand Up @@ -2075,11 +2075,11 @@ impl ReadOptionsPy {
let mut opt = ReadOptions::default();
opt.fill_cache(self.fill_cache);
if !self.iterate_lower_bound.is_none(py) {
let lower_bound = encode_key(self.iterate_lower_bound.as_ref(py), raw_mode)?;
let lower_bound = encode_key(self.iterate_lower_bound.bind(py), raw_mode)?;
opt.set_iterate_lower_bound(lower_bound);
}
if !self.iterate_upper_bound.is_none(py) {
let upper_bound = encode_key(self.iterate_upper_bound.as_ref(py), raw_mode)?;
let upper_bound = encode_key(self.iterate_upper_bound.bind(py), raw_mode)?;
opt.set_iterate_upper_bound(upper_bound);
}
opt.set_prefix_same_as_start(self.prefix_same_as_start);
Expand All @@ -2098,7 +2098,7 @@ impl ReadOptionsPy {
pub(crate) fn to_read_opt(&self, raw_mode: bool, py: Python) -> PyResult<ReadOpt> {
let opt = unsafe { ReadOpt(librocksdb_sys::rocksdb_readoptions_create()) };
if !self.iterate_lower_bound.is_none(py) {
let lower_bound = encode_key(self.iterate_lower_bound.as_ref(py), raw_mode)?;
let lower_bound = encode_key(self.iterate_lower_bound.bind(py), raw_mode)?;

unsafe {
librocksdb_sys::rocksdb_readoptions_set_iterate_lower_bound(
Expand All @@ -2109,7 +2109,7 @@ impl ReadOptionsPy {
}
}
if !self.iterate_upper_bound.is_none(py) {
let upper_bound = encode_key(self.iterate_upper_bound.as_ref(py), raw_mode)?;
let upper_bound = encode_key(self.iterate_upper_bound.bind(py), raw_mode)?;

unsafe {
librocksdb_sys::rocksdb_readoptions_set_iterate_upper_bound(
Expand Down
Loading
Loading