hash.rs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. use crate::{
  2. check_arg, connection::Connection, error::Error, value::bytes_to_number, value::Value,
  3. };
  4. use bytes::Bytes;
  5. use rand::Rng;
  6. use std::{
  7. collections::{BTreeMap, HashMap},
  8. convert::TryFrom,
  9. ops::AddAssign,
  10. str::FromStr,
  11. };
  12. pub async fn hdel(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  13. let result = conn.db().get_map_or(
  14. &args[1],
  15. |v| match v {
  16. Value::Hash(h) => {
  17. let mut h = h.write();
  18. let mut total: i64 = 0;
  19. for key in (&args[2..]).iter() {
  20. if h.remove(key).is_some() {
  21. total += 1;
  22. }
  23. }
  24. Ok(total.into())
  25. }
  26. _ => Err(Error::WrongType),
  27. },
  28. || Ok(0.into()),
  29. )?;
  30. conn.db().bump_version(&args[1]);
  31. Ok(result)
  32. }
  33. pub async fn hexists(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  34. conn.db().get_map_or(
  35. &args[1],
  36. |v| match v {
  37. Value::Hash(h) => Ok(if h.read().get(&args[2]).is_some() {
  38. 1.into()
  39. } else {
  40. 0.into()
  41. }),
  42. _ => Err(Error::WrongType),
  43. },
  44. || Ok(0.into()),
  45. )
  46. }
  47. pub async fn hget(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  48. conn.db().get_map_or(
  49. &args[1],
  50. |v| match v {
  51. Value::Hash(h) => Ok(if let Some(v) = h.read().get(&args[2]) {
  52. Value::Blob(v.clone())
  53. } else {
  54. Value::Null
  55. }),
  56. _ => Err(Error::WrongType),
  57. },
  58. || Ok(Value::Null),
  59. )
  60. }
  61. pub async fn hgetall(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  62. conn.db().get_map_or(
  63. &args[1],
  64. |v| match v {
  65. Value::Hash(h) => {
  66. let mut ret = vec![];
  67. for (key, value) in h.read().iter() {
  68. ret.push(Value::Blob(key.clone()));
  69. ret.push(Value::Blob(value.clone()));
  70. }
  71. Ok(ret.into())
  72. }
  73. _ => Err(Error::WrongType),
  74. },
  75. || Ok(Value::Array(vec![])),
  76. )
  77. }
  78. pub async fn hincrby<
  79. T: ToString + FromStr + AddAssign + for<'a> TryFrom<&'a Value, Error = Error> + Into<Value> + Copy,
  80. >(
  81. conn: &Connection,
  82. args: &[Bytes],
  83. ) -> Result<Value, Error> {
  84. let result = conn.db().get_map_or(
  85. &args[1],
  86. |v| match v {
  87. Value::Hash(h) => {
  88. let mut incr_by: T = bytes_to_number(&args[3])?;
  89. let mut h = h.write();
  90. if let Some(n) = h.get(&args[2]) {
  91. incr_by += bytes_to_number(n)?;
  92. }
  93. h.insert(args[2].clone(), incr_by.to_string().into());
  94. Ok(incr_by.into())
  95. }
  96. _ => Err(Error::WrongType),
  97. },
  98. || {
  99. let incr_by: T = bytes_to_number(&args[3])?;
  100. #[allow(clippy::mutable_key_type)]
  101. let mut h = HashMap::new();
  102. h.insert(args[2].clone(), incr_by.to_string().into());
  103. conn.db().set(&args[1], h.into(), None);
  104. Ok(incr_by.into())
  105. },
  106. )?;
  107. conn.db().bump_version(&args[1]);
  108. Ok(result)
  109. }
  110. pub async fn hkeys(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  111. conn.db().get_map_or(
  112. &args[1],
  113. |v| match v {
  114. Value::Hash(h) => {
  115. let mut ret = vec![];
  116. for key in h.read().keys() {
  117. ret.push(Value::Blob(key.clone()));
  118. }
  119. Ok(ret.into())
  120. }
  121. _ => Err(Error::WrongType),
  122. },
  123. || Ok(Value::Array(vec![])),
  124. )
  125. }
  126. pub async fn hlen(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  127. conn.db().get_map_or(
  128. &args[1],
  129. |v| match v {
  130. Value::Hash(h) => Ok((h.read().len() as i64).into()),
  131. _ => Err(Error::WrongType),
  132. },
  133. || Ok(0.into()),
  134. )
  135. }
  136. pub async fn hmget(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  137. conn.db().get_map_or(
  138. &args[1],
  139. |v| match v {
  140. Value::Hash(h) => {
  141. let h = h.read();
  142. Ok((&args[2..])
  143. .iter()
  144. .map(|key| {
  145. if let Some(value) = h.get(key) {
  146. Value::Blob(value.clone())
  147. } else {
  148. Value::Null
  149. }
  150. })
  151. .collect::<Vec<Value>>()
  152. .into())
  153. }
  154. _ => Err(Error::WrongType),
  155. },
  156. || Ok(Value::Array(vec![])),
  157. )
  158. }
  159. pub async fn hrandfield(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  160. let (count, with_values) = match args.len() {
  161. 2 => (None, false),
  162. 3 => (Some(bytes_to_number::<i64>(&args[2])?), false),
  163. 4 => {
  164. if !(check_arg!(args, 3, "WITHVALUES")) {
  165. return Err(Error::Syntax);
  166. }
  167. (Some(bytes_to_number::<i64>(&args[2])?), true)
  168. }
  169. _ => return Err(Error::InvalidArgsCount("hrandfield".to_owned())),
  170. };
  171. let (count, single, repeat) = if let Some(count) = count {
  172. if count > 0 {
  173. (count, false, 1)
  174. } else {
  175. (count.abs(), false, count.abs())
  176. }
  177. } else {
  178. (1, true, 1)
  179. };
  180. conn.db().get_map_or(
  181. &args[1],
  182. |v| match v {
  183. Value::Hash(h) => {
  184. let mut ret = vec![];
  185. let mut i = 0;
  186. let mut rand_sorted = BTreeMap::new();
  187. let mut rng = rand::thread_rng();
  188. let h = h.read();
  189. for _ in 0..repeat {
  190. for (key, value) in h.iter() {
  191. let rand = rng.gen::<u64>();
  192. rand_sorted.insert((rand, i), (key, value));
  193. i += 1;
  194. }
  195. }
  196. i = 0;
  197. for val in rand_sorted.values() {
  198. if single {
  199. return Ok(Value::Blob(val.0.clone()));
  200. }
  201. if i == count {
  202. break;
  203. }
  204. ret.push(Value::Blob(val.0.clone()));
  205. if with_values {
  206. ret.push(Value::Blob(val.1.clone()));
  207. }
  208. i += 1;
  209. }
  210. Ok(ret.into())
  211. }
  212. _ => Err(Error::WrongType),
  213. },
  214. || Ok(Value::Array(vec![])),
  215. )
  216. }
  217. pub async fn hset(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  218. if args.len() % 2 == 1 {
  219. return Err(Error::InvalidArgsCount("hset".to_owned()));
  220. }
  221. let result = conn.db().get_map_or(
  222. &args[1],
  223. |v| match v {
  224. Value::Hash(h) => {
  225. let mut h = h.write();
  226. let mut e: i64 = 0;
  227. for i in (2..args.len()).step_by(2) {
  228. if h.insert(args[i].clone(), args[i + 1].clone()).is_none() {
  229. e += 1;
  230. }
  231. }
  232. Ok(e.into())
  233. }
  234. _ => Err(Error::WrongType),
  235. },
  236. || {
  237. #[allow(clippy::mutable_key_type)]
  238. let mut h = HashMap::new();
  239. for i in (2..args.len()).step_by(2) {
  240. h.insert(args[i].clone(), args[i + 1].clone());
  241. }
  242. let len = h.len() as i64;
  243. conn.db().set(&args[1], h.into(), None);
  244. Ok(len.into())
  245. },
  246. )?;
  247. conn.db().bump_version(&args[1]);
  248. Ok(result)
  249. }
  250. pub async fn hsetnx(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  251. let result = conn.db().get_map_or(
  252. &args[1],
  253. |v| match v {
  254. Value::Hash(h) => {
  255. let mut h = h.write();
  256. if h.get(&args[2]).is_some() {
  257. Ok(0.into())
  258. } else {
  259. h.insert(args[2].clone(), args[3].clone());
  260. Ok(1.into())
  261. }
  262. }
  263. _ => Err(Error::WrongType),
  264. },
  265. || {
  266. #[allow(clippy::mutable_key_type)]
  267. let mut h = HashMap::new();
  268. for i in (2..args.len()).step_by(2) {
  269. h.insert(args[i].clone(), args[i + 1].clone());
  270. }
  271. let len = h.len() as i64;
  272. conn.db().set(&args[1], h.into(), None);
  273. Ok(len.into())
  274. },
  275. )?;
  276. if result == Value::Integer(1) {
  277. conn.db().bump_version(&args[1]);
  278. }
  279. Ok(result)
  280. }
  281. pub async fn hstrlen(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  282. conn.db().get_map_or(
  283. &args[1],
  284. |v| match v {
  285. Value::Hash(h) => Ok(if let Some(v) = h.read().get(&args[2]) {
  286. (v.len() as i64).into()
  287. } else {
  288. 0.into()
  289. }),
  290. _ => Err(Error::WrongType),
  291. },
  292. || Ok(0.into()),
  293. )
  294. }
  295. pub async fn hvals(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  296. conn.db().get_map_or(
  297. &args[1],
  298. |v| match v {
  299. Value::Hash(h) => {
  300. let mut ret = vec![];
  301. for value in h.read().values() {
  302. ret.push(Value::Blob(value.clone()));
  303. }
  304. Ok(ret.into())
  305. }
  306. _ => Err(Error::WrongType),
  307. },
  308. || Ok(Value::Array(vec![])),
  309. )
  310. }
  311. #[cfg(test)]
  312. mod test {
  313. use crate::{
  314. cmd::test::{create_connection, run_command},
  315. value::Value,
  316. };
  317. #[tokio::test]
  318. async fn hget() {
  319. let c = create_connection();
  320. let r = run_command(&c, &["hset", "foo", "f1", "1", "f2", "2", "f3", "3"]).await;
  321. assert_eq!(Ok(Value::Integer(3)), r);
  322. let r = run_command(&c, &["hget", "foo", "f1"]).await;
  323. assert_eq!(Ok(Value::Blob("1".into())), r);
  324. }
  325. #[tokio::test]
  326. async fn hgetall() {
  327. let c = create_connection();
  328. let r = run_command(&c, &["hset", "foo", "f1", "1", "f2", "2", "f3", "3"]).await;
  329. assert_eq!(Ok(Value::Integer(3)), r);
  330. let r = run_command(&c, &["hgetall", "foo"]).await;
  331. match r {
  332. Ok(Value::Array(x)) => {
  333. assert_eq!(6, x.len());
  334. assert!(
  335. x[0] == Value::Blob("f1".into())
  336. || x[0] == Value::Blob("f2".into())
  337. || x[0] == Value::Blob("f3".into())
  338. )
  339. }
  340. _ => assert!(false),
  341. };
  342. }
  343. #[tokio::test]
  344. async fn hrandfield() {
  345. let c = create_connection();
  346. let r = run_command(&c, &["hset", "foo", "f1", "1", "f2", "2", "f3", "3"]).await;
  347. assert_eq!(Ok(Value::Integer(3)), r);
  348. let r = run_command(&c, &["hrandfield", "foo"]).await;
  349. match r {
  350. Ok(Value::Blob(x)) => {
  351. let x = unsafe { std::str::from_utf8_unchecked(&x) };
  352. assert!(x == "f1".to_owned() || x == "f2".to_owned() || x == "f3".to_owned());
  353. }
  354. _ => assert!(false),
  355. };
  356. }
  357. #[tokio::test]
  358. async fn hmget() {
  359. let c = create_connection();
  360. let r = run_command(&c, &["hset", "foo", "f1", "1", "f2", "2", "f3", "3"]).await;
  361. assert_eq!(Ok(Value::Integer(3)), r);
  362. let r = run_command(&c, &["hmget", "foo", "f1", "f2"]).await;
  363. assert_eq!(
  364. Ok(Value::Array(vec![
  365. Value::Blob("1".into()),
  366. Value::Blob("2".into()),
  367. ])),
  368. r
  369. );
  370. }
  371. #[tokio::test]
  372. async fn hexists() {
  373. let c = create_connection();
  374. let r = run_command(&c, &["hset", "foo", "f1", "1", "f2", "2", "f3", "3"]).await;
  375. assert_eq!(Ok(Value::Integer(3)), r);
  376. assert_eq!(
  377. Ok(Value::Integer(1)),
  378. run_command(&c, &["hexists", "foo", "f1"]).await
  379. );
  380. assert_eq!(
  381. Ok(Value::Integer(1)),
  382. run_command(&c, &["hexists", "foo", "f3"]).await
  383. );
  384. assert_eq!(
  385. Ok(Value::Integer(0)),
  386. run_command(&c, &["hexists", "foo", "f4"]).await
  387. );
  388. }
  389. #[tokio::test]
  390. async fn hstrlen() {
  391. let c = create_connection();
  392. let r = run_command(&c, &["hset", "foo", "f1", "1", "f2", "2", "f3", "3"]).await;
  393. assert_eq!(Ok(Value::Integer(3)), r);
  394. let r = run_command(&c, &["hstrlen", "foo", "f1"]).await;
  395. assert_eq!(Ok(Value::Integer(1)), r);
  396. }
  397. #[tokio::test]
  398. async fn hlen() {
  399. let c = create_connection();
  400. let r = run_command(&c, &["hset", "foo", "f1", "1", "f2", "2", "f3", "3"]).await;
  401. assert_eq!(Ok(Value::Integer(3)), r);
  402. let r = run_command(&c, &["hset", "foo", "f1", "2", "f4", "2", "f5", "3"]).await;
  403. assert_eq!(Ok(Value::Integer(2)), r);
  404. let r = run_command(&c, &["hlen", "foo"]).await;
  405. assert_eq!(Ok(Value::Integer(5)), r);
  406. }
  407. #[tokio::test]
  408. async fn hkeys() {
  409. let c = create_connection();
  410. let r = run_command(&c, &["hset", "foo", "f1", "1"]).await;
  411. assert_eq!(Ok(Value::Integer(1)), r);
  412. let r = run_command(&c, &["hkeys", "foo"]).await;
  413. assert_eq!(Ok(Value::Array(vec![Value::Blob("f1".into()),])), r);
  414. }
  415. #[tokio::test]
  416. async fn hvals() {
  417. let c = create_connection();
  418. let r = run_command(&c, &["hset", "foo", "f1", "1"]).await;
  419. assert_eq!(Ok(Value::Integer(1)), r);
  420. let r = run_command(&c, &["hvals", "foo"]).await;
  421. assert_eq!(Ok(Value::Array(vec![Value::Blob("1".into()),])), r);
  422. }
  423. }