wobject 0.1.1

In-memory record-backed objects: Hash, Set, List, and SortedSet implementations
use std::{
  collections::VecDeque,
  io::{self, Read, Write},
};

use parking_lot::Mutex;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum ListOperation {
  Lpop = 0,
  Lpush = 1,
  Lpushx = 2,
  Rpop = 3,
  Rpush = 4,
  Rpushx = 5,
  Llen = 6,
  Ltrim = 7,
  Lrange = 8,
  Lindex = 9,
  Linsert = 10,
  Lrem = 11,
  Rpoplpush = 12,
  Lmove = 13,
  Lset = 14,
  Brpop = 15,
  Blpop = 16,
  Lpos = 17,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum OperationDirection {
  Left = 0,
  Right = 1,
  Unknown = 2,
}

/// 内存列表对象(嵌入式存储层实现,服务层权威实现见 wedb_standalone::objects::list::ListObject)
pub struct ListObject {
  // Using VecDeque instead of LinkedList for better cache locality and performance
  pub list: Mutex<VecDeque<Vec<u8>>>,
}

impl ListObject {
  pub fn new() -> Self {
    Self {
      list: Mutex::new(VecDeque::new()),
    }
  }

  /// 从二进制流反序列化内存列表对象
  pub fn deserialize<R: Read>(reader: &mut R) -> io::Result<Self> {
    let mut buf = Vec::new();
    reader.read_to_end(&mut buf)?;
    let list: VecDeque<Vec<u8>> =
      bitcode::decode(&buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
    Ok(Self {
      list: Mutex::new(list),
    })
  }

  /// 序列化内存列表对象为二进制流
  pub fn serialize<W: Write>(&self, writer: &mut W) -> io::Result<()> {
    let list = self.list.lock();
    let bytes = bitcode::encode(&*list);
    writer.write_all(&bytes)
  }

  /// 内存列表对象操作派发
  pub fn operate(&self, op: ListOperation, item: &[u8]) -> Option<Vec<u8>> {
    let mut list = self.list.lock();
    match op {
      ListOperation::Lpush => {
        list.push_front(item.to_vec());
        None
      }
      ListOperation::Rpush => {
        list.push_back(item.to_vec());
        None
      }
      ListOperation::Lpop => list.pop_front(),
      ListOperation::Rpop => list.pop_back(),
      _ => None,
    }
  }

  /// 在 garnet 中的相对路径:libs/server/Objects/List/ListObject.cs:ListIndex
  pub fn index(&self, index: isize) -> Option<Vec<u8>> {
    let list = self.list.lock();
    let len = list.len() as isize;
    let actual_idx = if index < 0 { len + index } else { index };
    if actual_idx < 0 || actual_idx >= len {
      None
    } else {
      list.get(actual_idx as usize).cloned()
    }
  }

  /// 在 garnet 中的相对路径:libs/server/Objects/List/ListObject.cs:ListRange
  pub fn range(&self, start: isize, stop: isize) -> Vec<Vec<u8>> {
    let list = self.list.lock();
    let len = list.len() as isize;
    let mut s = if start < 0 { len + start } else { start };
    let mut e = if stop < 0 { len + stop } else { stop };

    if s < 0 {
      s = 0;
    }
    if e >= len {
      e = len - 1;
    }
    if s > e || s >= len {
      return vec![];
    }

    list.range((s as usize)..=(e as usize)).cloned().collect()
  }

  /// 在 garnet 中的相对路径:libs/server/Objects/List/ListObject.cs:ListTrim
  pub fn trim(&self, start: isize, stop: isize) {
    let mut list = self.list.lock();
    let len = list.len() as isize;
    let mut s = if start < 0 { len + start } else { start };
    let mut e = if stop < 0 { len + stop } else { stop };

    if s < 0 {
      s = 0;
    }
    if e >= len {
      e = len - 1;
    }
    if s > e || s >= len {
      list.clear();
      return;
    }

    list.truncate((e + 1) as usize);
    for _ in 0..s {
      list.pop_front();
    }
  }

  /// 在 garnet 中的相对路径:libs/server/Objects/List/ListObject.cs:Count
  pub fn count(&self) -> usize {
    self.list.lock().len()
  }
}

impl Default for ListObject {
  fn default() -> Self {
    Self::new()
  }
}