doc_cache.rs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. use crate::errors::DocError;
  2. use dashmap::DashMap;
  3. use flowy_ot::{client::Document, core::Delta, errors::OTError};
  4. use std::convert::TryInto;
  5. use tokio::sync::RwLock;
  6. #[derive(Debug, Clone, Eq, PartialEq, Hash)]
  7. pub struct DocId(pub(crate) String);
  8. pub struct OpenDocument {
  9. document: Document,
  10. }
  11. impl<T> std::convert::From<T> for DocId
  12. where
  13. T: ToString,
  14. {
  15. fn from(s: T) -> Self { DocId(s.to_string()) }
  16. }
  17. pub(crate) struct OpenedDocumentCache {
  18. inner: DashMap<DocId, RwLock<OpenDocument>>,
  19. }
  20. impl OpenedDocumentCache {
  21. pub(crate) fn new() -> Self { Self { inner: DashMap::new() } }
  22. pub(crate) fn open<T, D>(&self, id: T, data: D) -> Result<(), DocError>
  23. where
  24. T: Into<DocId>,
  25. D: TryInto<Delta, Error = OTError>,
  26. {
  27. let doc_id = id.into();
  28. let delta = data.try_into()?;
  29. let document = Document::from_delta(delta);
  30. let doc_info = OpenDocument { document };
  31. self.inner.insert(doc_id, RwLock::new(doc_info));
  32. Ok(())
  33. }
  34. pub(crate) fn is_opened<T>(&self, id: T) -> bool
  35. where
  36. T: Into<DocId>,
  37. {
  38. let doc_id = id.into();
  39. self.inner.get(&doc_id).is_some()
  40. }
  41. pub(crate) async fn mut_doc<T, F>(&self, id: T, f: F) -> Result<(), DocError>
  42. where
  43. T: Into<DocId>,
  44. F: FnOnce(&mut Document) -> Result<(), DocError>,
  45. {
  46. let doc_id = id.into();
  47. match self.inner.get(&doc_id) {
  48. None => Err(doc_not_found()),
  49. Some(doc_info) => {
  50. let mut write_guard = doc_info.write().await;
  51. f(&mut write_guard.document)
  52. },
  53. }
  54. }
  55. pub(crate) async fn read_doc<T>(&self, id: T) -> Result<Vec<u8>, DocError>
  56. where
  57. T: Into<DocId> + Clone,
  58. {
  59. if self.is_opened(id.clone()) {
  60. return Err(doc_not_found());
  61. }
  62. let doc_id = id.into();
  63. let doc_info = self.inner.get(&doc_id).unwrap();
  64. let write_guard = doc_info.read().await;
  65. let doc = &(*write_guard).document;
  66. Ok(doc.to_bytes())
  67. }
  68. pub(crate) fn close<T>(&self, id: T) -> Result<(), DocError>
  69. where
  70. T: Into<DocId>,
  71. {
  72. let doc_id = id.into();
  73. self.inner.remove(&doc_id);
  74. Ok(())
  75. }
  76. }
  77. fn doc_not_found() -> DocError { DocError::not_found().context("Doc is close or you should call open first") }