Browse Source

Add an allocator for packet IDs.

Mathias Gottschlag 5 years ago
parent
commit
979b444736
4 changed files with 92 additions and 0 deletions
  1. 20
    0
      Cargo.lock
  2. 1
    0
      Cargo.toml
  3. 70
    0
      src/network/idalloc.rs
  4. 1
    0
      src/network/mod.rs

+ 20
- 0
Cargo.lock View File

@@ -847,6 +847,15 @@ dependencies = [
847 847
  "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
848 848
 ]
849 849
 
850
+[[package]]
851
+name = "range-set"
852
+version = "0.0.5"
853
+source = "registry+https://github.com/rust-lang/crates.io-index"
854
+dependencies = [
855
+ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
856
+ "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
857
+]
858
+
850 859
 [[package]]
851 860
 name = "rayon"
852 861
 version = "1.3.0"
@@ -1040,6 +1049,14 @@ name = "slab"
1040 1049
 version = "0.4.2"
1041 1050
 source = "registry+https://github.com/rust-lang/crates.io-index"
1042 1051
 
1052
+[[package]]
1053
+name = "smallvec"
1054
+version = "0.6.13"
1055
+source = "registry+https://github.com/rust-lang/crates.io-index"
1056
+dependencies = [
1057
+ "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
1058
+]
1059
+
1043 1060
 [[package]]
1044 1061
 name = "smallvec"
1045 1062
 version = "1.2.0"
@@ -1187,6 +1204,7 @@ dependencies = [
1187 1204
  "fswatcher 0.1.0 (git+https://github.com/mgottschlag/fswatcher-rs.git)",
1188 1205
  "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
1189 1206
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
1207
+ "range-set 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
1190 1208
  "rmp-serde 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)",
1191 1209
  "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1192 1210
  "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1473,6 +1491,7 @@ dependencies = [
1473 1491
 "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
1474 1492
 "checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
1475 1493
 "checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
1494
+"checksum range-set 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e51c363412e87a2d92e8730f95cbdae590a46959bbcb17d0b5c1ad2c7af98d11"
1476 1495
 "checksum rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098"
1477 1496
 "checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
1478 1497
 "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
@@ -1496,6 +1515,7 @@ dependencies = [
1496 1515
 "checksum sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
1497 1516
 "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41"
1498 1517
 "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
1518
+"checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6"
1499 1519
 "checksum smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc"
1500 1520
 "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
1501 1521
 "checksum structopt 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "df136b42d76b1fbea72e2ab3057343977b04b4a2e00836c3c7c0673829572713"

+ 1
- 0
Cargo.toml View File

@@ -18,6 +18,7 @@ log = "0.4"
18 18
 rmp-serde = "0.14"
19 19
 fswatcher = { git = "https://github.com/mgottschlag/fswatcher-rs.git" }
20 20
 url = "*"
21
+range-set = "*"
21 22
 
22 23
 [dev-dependencies]
23 24
 criterion = "0.3"

+ 70
- 0
src/network/idalloc.rs View File

@@ -0,0 +1,70 @@
1
+use range_set::RangeSet;
2
+use std::ops::RangeInclusive;
3
+
4
+/// Allocator for packet IDs.
5
+pub struct IdAllocator {
6
+    free_ids: RangeSet<[RangeInclusive<u32>; 4]>,
7
+}
8
+
9
+impl IdAllocator {
10
+    /// Creates a new allocator for IDs in the range between 0 and 1<<31-1.
11
+    pub fn new() -> IdAllocator {
12
+        IdAllocator {
13
+            free_ids: RangeSet::<[RangeInclusive<u32>; 4]>::from(0..=(1 << 31) - 1),
14
+        }
15
+    }
16
+
17
+    /// Allocates an ID.
18
+    ///
19
+    /// The ID needs to be manually freed by calling `free(id)` once the server
20
+    /// has sent a response..
21
+    pub fn alloc(&mut self) -> u32 {
22
+        assert!(!self.free_ids.is_empty());
23
+        let id = self.free_ids.iter().next().unwrap();
24
+        self.free_ids.remove(id);
25
+        id
26
+    }
27
+
28
+    /// Frees an ID to allow reuse.
29
+    pub fn free(&mut self, id: u32) {
30
+        assert!(id < 1 << 31);
31
+        let inserted = self.free_ids.insert(id);
32
+        if !inserted {
33
+            panic!("free() called for invalid packet ID.");
34
+        }
35
+    }
36
+}
37
+
38
+#[cfg(test)]
39
+mod tests {
40
+    use super::*;
41
+
42
+    #[test]
43
+    fn test_alloc() {
44
+        let mut ids = IdAllocator::new();
45
+        assert_eq!(ids.alloc(), 0);
46
+        assert_eq!(ids.alloc(), 1);
47
+        assert_eq!(ids.alloc(), 2);
48
+        assert_eq!(ids.alloc(), 3);
49
+        assert_eq!(ids.alloc(), 4);
50
+        ids.free(2);
51
+        ids.free(3);
52
+        assert_eq!(ids.alloc(), 2);
53
+        assert_eq!(ids.alloc(), 3);
54
+        assert_eq!(ids.alloc(), 5);
55
+    }
56
+
57
+    #[test]
58
+    #[should_panic]
59
+    fn test_invalid_free() {
60
+        let mut ids = IdAllocator::new();
61
+        ids.free(42);
62
+    }
63
+
64
+    #[test]
65
+    #[should_panic]
66
+    fn test_invalid_free2() {
67
+        let mut ids = IdAllocator::new();
68
+        ids.free(1 << 31);
69
+    }
70
+}

+ 1
- 0
src/network/mod.rs View File

@@ -1,4 +1,5 @@
1 1
 pub mod client;
2
+pub mod idalloc;
2 3
 pub mod packet;
3 4
 pub mod server;
4 5
 pub mod websocket;

Loading…
Cancel
Save