1 // Copyright 2018 Mozilla 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 // this file except in compliance with the License. You may obtain a copy of the 5 // License at http://www.apache.org/licenses/LICENSE-2.0 6 // Unless required by applicable law or agreed to in writing, software distributed 7 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 8 // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 // specific language governing permissions and limitations under the License. 10 11 use std::marker::PhantomData; 12 13 use crate::{ 14 backend::{ 15 BackendDatabase, 16 BackendIter, 17 BackendRoCursor, 18 BackendRwTransaction, 19 }, 20 error::StoreError, 21 readwrite::{ 22 Readable, 23 Writer, 24 }, 25 store::{ 26 keys::{ 27 Key, 28 PrimitiveInt, 29 }, 30 multi::{ 31 Iter, 32 MultiStore, 33 }, 34 }, 35 value::Value, 36 }; 37 38 type EmptyResult = Result<(), StoreError>; 39 40 #[derive(Debug, Eq, PartialEq, Copy, Clone)] 41 pub struct MultiIntegerStore<D, K> { 42 inner: MultiStore<D>, 43 phantom: PhantomData<K>, 44 } 45 46 impl<D, K> MultiIntegerStore<D, K> 47 where 48 D: BackendDatabase, 49 K: PrimitiveInt, 50 { new(db: D) -> MultiIntegerStore<D, K>51 pub(crate) fn new(db: D) -> MultiIntegerStore<D, K> { 52 MultiIntegerStore { 53 inner: MultiStore::new(db), 54 phantom: PhantomData, 55 } 56 } 57 get<'r, R, I, C>(&self, reader: &'r R, k: K) -> Result<Iter<'r, I>, StoreError> where R: Readable<'r, Database = D, RoCursor = C>, I: BackendIter<'r>, C: BackendRoCursor<'r, Iter = I>, K: 'r,58 pub fn get<'r, R, I, C>(&self, reader: &'r R, k: K) -> Result<Iter<'r, I>, StoreError> 59 where 60 R: Readable<'r, Database = D, RoCursor = C>, 61 I: BackendIter<'r>, 62 C: BackendRoCursor<'r, Iter = I>, 63 K: 'r, 64 { 65 self.inner.get(reader, Key::new(&k)?) 66 } 67 get_first<'r, R>(&self, reader: &'r R, k: K) -> Result<Option<Value<'r>>, StoreError> where R: Readable<'r, Database = D>,68 pub fn get_first<'r, R>(&self, reader: &'r R, k: K) -> Result<Option<Value<'r>>, StoreError> 69 where 70 R: Readable<'r, Database = D>, 71 { 72 self.inner.get_first(reader, Key::new(&k)?) 73 } 74 put<T>(&self, writer: &mut Writer<T>, k: K, v: &Value) -> EmptyResult where T: BackendRwTransaction<Database = D>,75 pub fn put<T>(&self, writer: &mut Writer<T>, k: K, v: &Value) -> EmptyResult 76 where 77 T: BackendRwTransaction<Database = D>, 78 { 79 self.inner.put(writer, Key::new(&k)?, v) 80 } 81 put_with_flags<T>(&self, writer: &mut Writer<T>, k: K, v: &Value, flags: T::Flags) -> EmptyResult where T: BackendRwTransaction<Database = D>,82 pub fn put_with_flags<T>(&self, writer: &mut Writer<T>, k: K, v: &Value, flags: T::Flags) -> EmptyResult 83 where 84 T: BackendRwTransaction<Database = D>, 85 { 86 self.inner.put_with_flags(writer, Key::new(&k)?, v, flags) 87 } 88 delete_all<T>(&self, writer: &mut Writer<T>, k: K) -> EmptyResult where T: BackendRwTransaction<Database = D>,89 pub fn delete_all<T>(&self, writer: &mut Writer<T>, k: K) -> EmptyResult 90 where 91 T: BackendRwTransaction<Database = D>, 92 { 93 self.inner.delete_all(writer, Key::new(&k)?) 94 } 95 delete<T>(&self, writer: &mut Writer<T>, k: K, v: &Value) -> EmptyResult where T: BackendRwTransaction<Database = D>,96 pub fn delete<T>(&self, writer: &mut Writer<T>, k: K, v: &Value) -> EmptyResult 97 where 98 T: BackendRwTransaction<Database = D>, 99 { 100 self.inner.delete(writer, Key::new(&k)?, v) 101 } 102 clear<T>(&self, writer: &mut Writer<T>) -> EmptyResult where T: BackendRwTransaction<Database = D>,103 pub fn clear<T>(&self, writer: &mut Writer<T>) -> EmptyResult 104 where 105 T: BackendRwTransaction<Database = D>, 106 { 107 self.inner.clear(writer) 108 } 109 } 110 111 #[cfg(test)] 112 mod tests { 113 use super::*; 114 use crate::*; 115 116 use std::fs; 117 118 use tempfile::Builder; 119 120 #[test] test_integer_keys()121 fn test_integer_keys() { 122 let root = Builder::new().prefix("test_integer_keys").tempdir().expect("tempdir"); 123 fs::create_dir_all(root.path()).expect("dir created"); 124 125 let k = Rkv::new::<backend::Lmdb>(root.path()).expect("new succeeded"); 126 let s = k.open_multi_integer("s", StoreOptions::create()).expect("open"); 127 128 macro_rules! test_integer_keys { 129 ($type:ty, $key:expr) => {{ 130 let mut writer = k.write().expect("writer"); 131 132 s.put(&mut writer, $key, &Value::Str("hello!")).expect("write"); 133 assert_eq!(s.get_first(&writer, $key).expect("read"), Some(Value::Str("hello!"))); 134 writer.commit().expect("committed"); 135 136 let reader = k.read().expect("reader"); 137 assert_eq!(s.get_first(&reader, $key).expect("read"), Some(Value::Str("hello!"))); 138 }}; 139 } 140 141 test_integer_keys!(u32, std::u32::MIN); 142 test_integer_keys!(u32, std::u32::MAX); 143 } 144 145 #[test] test_clear()146 fn test_clear() { 147 let root = Builder::new().prefix("test_multi_integer_clear").tempdir().expect("tempdir"); 148 fs::create_dir_all(root.path()).expect("dir created"); 149 150 let k = Rkv::new::<backend::Lmdb>(root.path()).expect("new succeeded"); 151 let s = k.open_multi_integer("s", StoreOptions::create()).expect("open"); 152 153 { 154 let mut writer = k.write().expect("writer"); 155 s.put(&mut writer, 1, &Value::Str("hello!")).expect("write"); 156 s.put(&mut writer, 1, &Value::Str("hello1!")).expect("write"); 157 s.put(&mut writer, 2, &Value::Str("hello!")).expect("write"); 158 assert_eq!(s.get_first(&writer, 1).expect("read"), Some(Value::Str("hello!"))); 159 assert_eq!(s.get_first(&writer, 2).expect("read"), Some(Value::Str("hello!"))); 160 assert_eq!(s.get_first(&writer, 3).expect("read"), None); 161 writer.commit().expect("committed"); 162 } 163 164 { 165 let mut writer = k.write().expect("writer"); 166 s.clear(&mut writer).expect("cleared"); 167 writer.commit().expect("committed"); 168 169 let reader = k.read().expect("reader"); 170 assert_eq!(s.get_first(&reader, 1).expect("read"), None); 171 assert_eq!(s.get_first(&reader, 2).expect("read"), None); 172 assert_eq!(s.get_first(&reader, 3).expect("read"), None); 173 } 174 } 175 176 #[test] test_dup()177 fn test_dup() { 178 let root = Builder::new().prefix("test_multi_integer_dup").tempdir().expect("tempdir"); 179 fs::create_dir_all(root.path()).expect("dir created"); 180 181 let k = Rkv::new::<backend::Lmdb>(root.path()).expect("new succeeded"); 182 let s = k.open_multi_integer("s", StoreOptions::create()).expect("open"); 183 184 { 185 let mut writer = k.write().expect("writer"); 186 s.put(&mut writer, 1, &Value::Str("hello!")).expect("write"); 187 s.put(&mut writer, 1, &Value::Str("hello!")).expect("write"); 188 s.put(&mut writer, 1, &Value::Str("hello1!")).expect("write"); 189 assert_eq!(s.get_first(&writer, 1).expect("read"), Some(Value::Str("hello!"))); 190 assert_eq!(s.get_first(&writer, 2).expect("read"), None); 191 assert_eq!(s.get_first(&writer, 3).expect("read"), None); 192 writer.commit().expect("committed"); 193 } 194 195 { 196 let mut writer = k.write().expect("writer"); 197 s.clear(&mut writer).expect("cleared"); 198 writer.commit().expect("committed"); 199 200 let reader = k.read().expect("reader"); 201 assert_eq!(s.get_first(&reader, 1).expect("read"), None); 202 assert_eq!(s.get_first(&reader, 2).expect("read"), None); 203 assert_eq!(s.get_first(&reader, 3).expect("read"), None); 204 } 205 } 206 207 #[test] test_dup_2()208 fn test_dup_2() { 209 let root = Builder::new().prefix("test_multi_integer_dup").tempdir().expect("tempdir"); 210 fs::create_dir_all(root.path()).expect("dir created"); 211 212 let k = Rkv::new::<backend::Lmdb>(root.path()).expect("new succeeded"); 213 let s = k.open_multi_integer("s", StoreOptions::create()).expect("open"); 214 215 { 216 let mut writer = k.write().expect("writer"); 217 s.put(&mut writer, 1, &Value::Str("hello!")).expect("write"); 218 s.put(&mut writer, 1, &Value::Str("hello!")).expect("write"); 219 s.put(&mut writer, 1, &Value::Str("hello1!")).expect("write"); 220 221 let mut iter = s.get(&writer, 1).expect("read"); 222 assert_eq!(iter.next().expect("first").expect("ok").1, Value::Str("hello!")); 223 assert_eq!(iter.next().expect("second").expect("ok").1, Value::Str("hello1!")); 224 assert!(iter.next().is_none()); 225 } 226 } 227 228 #[test] test_del()229 fn test_del() { 230 let root = Builder::new().prefix("test_multi_integer_dup").tempdir().expect("tempdir"); 231 fs::create_dir_all(root.path()).expect("dir created"); 232 233 let k = Rkv::new::<backend::Lmdb>(root.path()).expect("new succeeded"); 234 let s = k.open_multi_integer("s", StoreOptions::create()).expect("open"); 235 236 { 237 let mut writer = k.write().expect("writer"); 238 s.put(&mut writer, 1, &Value::Str("hello!")).expect("write"); 239 s.put(&mut writer, 1, &Value::Str("hello!")).expect("write"); 240 s.put(&mut writer, 1, &Value::Str("hello1!")).expect("write"); 241 { 242 let mut iter = s.get(&writer, 1).expect("read"); 243 assert_eq!(iter.next().expect("first").expect("ok").1, Value::Str("hello!")); 244 assert_eq!(iter.next().expect("second").expect("ok").1, Value::Str("hello1!")); 245 assert!(iter.next().is_none()); 246 } 247 writer.commit().expect("committed"); 248 } 249 250 { 251 let mut writer = k.write().expect("writer"); 252 s.delete(&mut writer, 1, &Value::Str("hello!")).expect("deleted"); 253 writer.commit().expect("committed"); 254 255 let reader = k.read().expect("reader"); 256 let mut iter = s.get(&reader, 1).expect("read"); 257 assert_eq!(iter.next().expect("first").expect("ok").1, Value::Str("hello1!")); 258 assert!(iter.next().is_none()); 259 } 260 261 { 262 let mut writer = k.write().expect("writer"); 263 s.delete(&mut writer, 1, &Value::Str("hello!")).expect_err("deleted"); 264 writer.commit().expect("committed"); 265 266 let reader = k.read().expect("reader"); 267 let mut iter = s.get(&reader, 1).expect("read"); 268 assert_eq!(iter.next().expect("first").expect("ok").1, Value::Str("hello1!")); 269 assert!(iter.next().is_none()); 270 } 271 272 { 273 let mut writer = k.write().expect("writer"); 274 s.delete(&mut writer, 1, &Value::Str("hello1!")).expect("deleted"); 275 writer.commit().expect("committed"); 276 277 let reader = k.read().expect("reader"); 278 let mut iter = s.get(&reader, 1).expect("read"); 279 assert!(iter.next().is_none()); 280 } 281 282 { 283 let mut writer = k.write().expect("writer"); 284 s.delete(&mut writer, 1, &Value::Str("hello1!")).expect_err("deleted"); 285 writer.commit().expect("committed"); 286 287 let reader = k.read().expect("reader"); 288 let mut iter = s.get(&reader, 1).expect("read"); 289 assert!(iter.next().is_none()); 290 } 291 } 292 293 #[test] test_persist()294 fn test_persist() { 295 let root = Builder::new().prefix("test_multi_integer_persist").tempdir().expect("tempdir"); 296 fs::create_dir_all(root.path()).expect("dir created"); 297 298 { 299 let k = Rkv::new::<backend::Lmdb>(root.path()).expect("new succeeded"); 300 let s = k.open_multi_integer("s", StoreOptions::create()).expect("open"); 301 302 let mut writer = k.write().expect("writer"); 303 s.put(&mut writer, 1, &Value::Str("hello!")).expect("write"); 304 s.put(&mut writer, 1, &Value::Str("hello1!")).expect("write"); 305 s.put(&mut writer, 2, &Value::Str("hello!")).expect("write"); 306 { 307 let mut iter = s.get(&writer, 1).expect("read"); 308 assert_eq!(iter.next().expect("first").expect("ok").1, Value::Str("hello!")); 309 assert_eq!(iter.next().expect("second").expect("ok").1, Value::Str("hello1!")); 310 assert!(iter.next().is_none()); 311 } 312 writer.commit().expect("committed"); 313 } 314 315 { 316 let k = Rkv::new::<backend::Lmdb>(root.path()).expect("new succeeded"); 317 let s = k.open_multi_integer("s", StoreOptions::create()).expect("open"); 318 319 let reader = k.read().expect("reader"); 320 let mut iter = s.get(&reader, 1).expect("read"); 321 assert_eq!(iter.next().expect("first").expect("ok").1, Value::Str("hello!")); 322 assert_eq!(iter.next().expect("second").expect("ok").1, Value::Str("hello1!")); 323 assert!(iter.next().is_none()); 324 } 325 } 326 } 327 328 #[cfg(test)] 329 mod tests_safe { 330 use super::*; 331 use crate::*; 332 333 use std::fs; 334 335 use tempfile::Builder; 336 337 #[test] test_integer_keys()338 fn test_integer_keys() { 339 let root = Builder::new().prefix("test_integer_keys").tempdir().expect("tempdir"); 340 fs::create_dir_all(root.path()).expect("dir created"); 341 342 let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded"); 343 let s = k.open_multi_integer("s", StoreOptions::create()).expect("open"); 344 345 macro_rules! test_integer_keys { 346 ($type:ty, $key:expr) => {{ 347 let mut writer = k.write().expect("writer"); 348 349 s.put(&mut writer, $key, &Value::Str("hello!")).expect("write"); 350 assert_eq!(s.get_first(&writer, $key).expect("read"), Some(Value::Str("hello!"))); 351 writer.commit().expect("committed"); 352 353 let reader = k.read().expect("reader"); 354 assert_eq!(s.get_first(&reader, $key).expect("read"), Some(Value::Str("hello!"))); 355 }}; 356 } 357 358 test_integer_keys!(u32, std::u32::MIN); 359 test_integer_keys!(u32, std::u32::MAX); 360 } 361 362 #[test] test_clear()363 fn test_clear() { 364 let root = Builder::new().prefix("test_multi_integer_clear").tempdir().expect("tempdir"); 365 fs::create_dir_all(root.path()).expect("dir created"); 366 367 let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded"); 368 let s = k.open_multi_integer("s", StoreOptions::create()).expect("open"); 369 370 { 371 let mut writer = k.write().expect("writer"); 372 s.put(&mut writer, 1, &Value::Str("hello!")).expect("write"); 373 s.put(&mut writer, 1, &Value::Str("hello1!")).expect("write"); 374 s.put(&mut writer, 2, &Value::Str("hello!")).expect("write"); 375 assert_eq!(s.get_first(&writer, 1).expect("read"), Some(Value::Str("hello!"))); 376 assert_eq!(s.get_first(&writer, 2).expect("read"), Some(Value::Str("hello!"))); 377 assert_eq!(s.get_first(&writer, 3).expect("read"), None); 378 writer.commit().expect("committed"); 379 } 380 381 { 382 let mut writer = k.write().expect("writer"); 383 s.clear(&mut writer).expect("cleared"); 384 writer.commit().expect("committed"); 385 386 let reader = k.read().expect("reader"); 387 assert_eq!(s.get_first(&reader, 1).expect("read"), None); 388 assert_eq!(s.get_first(&reader, 2).expect("read"), None); 389 assert_eq!(s.get_first(&reader, 3).expect("read"), None); 390 } 391 } 392 393 #[test] test_dup()394 fn test_dup() { 395 let root = Builder::new().prefix("test_multi_integer_dup").tempdir().expect("tempdir"); 396 fs::create_dir_all(root.path()).expect("dir created"); 397 398 let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded"); 399 let s = k.open_multi_integer("s", StoreOptions::create()).expect("open"); 400 401 { 402 let mut writer = k.write().expect("writer"); 403 s.put(&mut writer, 1, &Value::Str("hello!")).expect("write"); 404 s.put(&mut writer, 1, &Value::Str("hello!")).expect("write"); 405 s.put(&mut writer, 1, &Value::Str("hello1!")).expect("write"); 406 assert_eq!(s.get_first(&writer, 1).expect("read"), Some(Value::Str("hello!"))); 407 assert_eq!(s.get_first(&writer, 2).expect("read"), None); 408 assert_eq!(s.get_first(&writer, 3).expect("read"), None); 409 writer.commit().expect("committed"); 410 } 411 412 { 413 let mut writer = k.write().expect("writer"); 414 s.clear(&mut writer).expect("cleared"); 415 writer.commit().expect("committed"); 416 417 let reader = k.read().expect("reader"); 418 assert_eq!(s.get_first(&reader, 1).expect("read"), None); 419 assert_eq!(s.get_first(&reader, 2).expect("read"), None); 420 assert_eq!(s.get_first(&reader, 3).expect("read"), None); 421 } 422 } 423 424 #[test] test_dup_2()425 fn test_dup_2() { 426 let root = Builder::new().prefix("test_multi_integer_dup").tempdir().expect("tempdir"); 427 fs::create_dir_all(root.path()).expect("dir created"); 428 429 let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded"); 430 let s = k.open_multi_integer("s", StoreOptions::create()).expect("open"); 431 432 { 433 let mut writer = k.write().expect("writer"); 434 s.put(&mut writer, 1, &Value::Str("hello!")).expect("write"); 435 s.put(&mut writer, 1, &Value::Str("hello!")).expect("write"); 436 s.put(&mut writer, 1, &Value::Str("hello1!")).expect("write"); 437 438 let mut iter = s.get(&writer, 1).expect("read"); 439 assert_eq!(iter.next().expect("first").expect("ok").1, Value::Str("hello!")); 440 assert_eq!(iter.next().expect("second").expect("ok").1, Value::Str("hello1!")); 441 assert!(iter.next().is_none()); 442 } 443 } 444 445 #[test] test_del()446 fn test_del() { 447 let root = Builder::new().prefix("test_multi_integer_dup").tempdir().expect("tempdir"); 448 fs::create_dir_all(root.path()).expect("dir created"); 449 450 let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded"); 451 let s = k.open_multi_integer("s", StoreOptions::create()).expect("open"); 452 453 { 454 let mut writer = k.write().expect("writer"); 455 s.put(&mut writer, 1, &Value::Str("hello!")).expect("write"); 456 s.put(&mut writer, 1, &Value::Str("hello!")).expect("write"); 457 s.put(&mut writer, 1, &Value::Str("hello1!")).expect("write"); 458 { 459 let mut iter = s.get(&writer, 1).expect("read"); 460 assert_eq!(iter.next().expect("first").expect("ok").1, Value::Str("hello!")); 461 assert_eq!(iter.next().expect("second").expect("ok").1, Value::Str("hello1!")); 462 assert!(iter.next().is_none()); 463 } 464 writer.commit().expect("committed"); 465 } 466 467 { 468 let mut writer = k.write().expect("writer"); 469 s.delete(&mut writer, 1, &Value::Str("hello!")).expect("deleted"); 470 writer.commit().expect("committed"); 471 472 let reader = k.read().expect("reader"); 473 let mut iter = s.get(&reader, 1).expect("read"); 474 assert_eq!(iter.next().expect("first").expect("ok").1, Value::Str("hello1!")); 475 assert!(iter.next().is_none()); 476 } 477 478 { 479 let mut writer = k.write().expect("writer"); 480 s.delete(&mut writer, 1, &Value::Str("hello!")).expect_err("deleted"); 481 writer.commit().expect("committed"); 482 483 let reader = k.read().expect("reader"); 484 let mut iter = s.get(&reader, 1).expect("read"); 485 assert_eq!(iter.next().expect("first").expect("ok").1, Value::Str("hello1!")); 486 assert!(iter.next().is_none()); 487 } 488 489 { 490 let mut writer = k.write().expect("writer"); 491 s.delete(&mut writer, 1, &Value::Str("hello1!")).expect("deleted"); 492 writer.commit().expect("committed"); 493 494 let reader = k.read().expect("reader"); 495 let mut iter = s.get(&reader, 1).expect("read"); 496 assert!(iter.next().is_none()); 497 } 498 499 { 500 let mut writer = k.write().expect("writer"); 501 s.delete(&mut writer, 1, &Value::Str("hello1!")).expect_err("deleted"); 502 writer.commit().expect("committed"); 503 504 let reader = k.read().expect("reader"); 505 let mut iter = s.get(&reader, 1).expect("read"); 506 assert!(iter.next().is_none()); 507 } 508 } 509 510 #[test] test_persist()511 fn test_persist() { 512 let root = Builder::new().prefix("test_multi_integer_persist").tempdir().expect("tempdir"); 513 fs::create_dir_all(root.path()).expect("dir created"); 514 515 { 516 let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded"); 517 let s = k.open_multi_integer("s", StoreOptions::create()).expect("open"); 518 519 let mut writer = k.write().expect("writer"); 520 s.put(&mut writer, 1, &Value::Str("hello!")).expect("write"); 521 s.put(&mut writer, 1, &Value::Str("hello1!")).expect("write"); 522 s.put(&mut writer, 2, &Value::Str("hello!")).expect("write"); 523 { 524 let mut iter = s.get(&writer, 1).expect("read"); 525 assert_eq!(iter.next().expect("first").expect("ok").1, Value::Str("hello!")); 526 assert_eq!(iter.next().expect("second").expect("ok").1, Value::Str("hello1!")); 527 assert!(iter.next().is_none()); 528 } 529 writer.commit().expect("committed"); 530 } 531 532 { 533 let k = Rkv::new::<backend::SafeMode>(root.path()).expect("new succeeded"); 534 let s = k.open_multi_integer("s", StoreOptions::create()).expect("open"); 535 536 let reader = k.read().expect("reader"); 537 let mut iter = s.get(&reader, 1).expect("read"); 538 assert_eq!(iter.next().expect("first").expect("ok").1, Value::Str("hello!")); 539 assert_eq!(iter.next().expect("second").expect("ok").1, Value::Str("hello1!")); 540 assert!(iter.next().is_none()); 541 } 542 } 543 } 544