mirror of
https://github.com/denoland/deno.git
synced 2025-01-10 16:11:13 -05:00
parent
cd19da62d9
commit
961f87e1c5
3 changed files with 84 additions and 3 deletions
|
@ -1,4 +1,20 @@
|
||||||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||||
|
/*
|
||||||
|
SharedQueue Binary Layout
|
||||||
|
+-------------------------------+-------------------------------+
|
||||||
|
| NUM_RECORDS (32) |
|
||||||
|
+---------------------------------------------------------------+
|
||||||
|
| NUM_SHIFTED_OFF (32) |
|
||||||
|
+---------------------------------------------------------------+
|
||||||
|
| HEAD (32) |
|
||||||
|
+---------------------------------------------------------------+
|
||||||
|
| OFFSETS (32) |
|
||||||
|
+---------------------------------------------------------------+
|
||||||
|
| RECORD_ENDS (*MAX_RECORDS) ...
|
||||||
|
+---------------------------------------------------------------+
|
||||||
|
| RECORDS (*MAX_RECORDS) ...
|
||||||
|
+---------------------------------------------------------------+
|
||||||
|
*/
|
||||||
|
|
||||||
(window => {
|
(window => {
|
||||||
const GLOBAL_NAMESPACE = "Deno";
|
const GLOBAL_NAMESPACE = "Deno";
|
||||||
|
@ -69,7 +85,7 @@
|
||||||
let off = head();
|
let off = head();
|
||||||
let end = off + buf.byteLength;
|
let end = off + buf.byteLength;
|
||||||
let index = numRecords();
|
let index = numRecords();
|
||||||
if (end > shared32.byteLength) {
|
if (end > shared32.byteLength || index >= MAX_RECORDS) {
|
||||||
console.log("shared_queue.ts push fail");
|
console.log("shared_queue.ts push fail");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -141,6 +157,7 @@
|
||||||
setAsyncHandler,
|
setAsyncHandler,
|
||||||
dispatch,
|
dispatch,
|
||||||
sharedQueue: {
|
sharedQueue: {
|
||||||
|
MAX_RECORDS,
|
||||||
head,
|
head,
|
||||||
numRecords,
|
numRecords,
|
||||||
size,
|
size,
|
||||||
|
|
|
@ -1,4 +1,21 @@
|
||||||
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
||||||
|
/*
|
||||||
|
SharedQueue Binary Layout
|
||||||
|
+-------------------------------+-------------------------------+
|
||||||
|
| NUM_RECORDS (32) |
|
||||||
|
+---------------------------------------------------------------+
|
||||||
|
| NUM_SHIFTED_OFF (32) |
|
||||||
|
+---------------------------------------------------------------+
|
||||||
|
| HEAD (32) |
|
||||||
|
+---------------------------------------------------------------+
|
||||||
|
| OFFSETS (32) |
|
||||||
|
+---------------------------------------------------------------+
|
||||||
|
| RECORD_ENDS (*MAX_RECORDS) ...
|
||||||
|
+---------------------------------------------------------------+
|
||||||
|
| RECORDS (*MAX_RECORDS) ...
|
||||||
|
+---------------------------------------------------------------+
|
||||||
|
*/
|
||||||
|
|
||||||
use crate::libdeno::deno_buf;
|
use crate::libdeno::deno_buf;
|
||||||
|
|
||||||
const MAX_RECORDS: usize = 100;
|
const MAX_RECORDS: usize = 100;
|
||||||
|
@ -36,6 +53,7 @@ impl SharedQueue {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset(&mut self) {
|
fn reset(&mut self) {
|
||||||
|
debug!("rust:shared_queue:reset");
|
||||||
let s: &mut [u32] = self.as_u32_slice_mut();
|
let s: &mut [u32] = self.as_u32_slice_mut();
|
||||||
s[INDEX_NUM_RECORDS] = 0;
|
s[INDEX_NUM_RECORDS] = 0;
|
||||||
s[INDEX_NUM_SHIFTED_OFF] = 0;
|
s[INDEX_NUM_SHIFTED_OFF] = 0;
|
||||||
|
@ -75,6 +93,11 @@ impl SharedQueue {
|
||||||
s[INDEX_HEAD] as usize
|
s[INDEX_HEAD] as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn num_shifted_off(&self) -> usize {
|
||||||
|
let s = self.as_u32_slice();
|
||||||
|
return s[INDEX_NUM_SHIFTED_OFF] as usize;
|
||||||
|
}
|
||||||
|
|
||||||
fn set_end(&mut self, index: usize, end: usize) {
|
fn set_end(&mut self, index: usize, end: usize) {
|
||||||
let s = self.as_u32_slice_mut();
|
let s = self.as_u32_slice_mut();
|
||||||
s[INDEX_OFFSETS + index] = end as u32;
|
s[INDEX_OFFSETS + index] = end as u32;
|
||||||
|
@ -120,7 +143,12 @@ impl SharedQueue {
|
||||||
} else {
|
} else {
|
||||||
self.reset();
|
self.reset();
|
||||||
}
|
}
|
||||||
|
debug!(
|
||||||
|
"rust:shared_queue:shift: num_records={}, num_shifted_off={}, head={}",
|
||||||
|
self.num_records(),
|
||||||
|
self.num_shifted_off(),
|
||||||
|
self.head()
|
||||||
|
);
|
||||||
Some(&self.bytes[off..end])
|
Some(&self.bytes[off..end])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +156,7 @@ impl SharedQueue {
|
||||||
let off = self.head();
|
let off = self.head();
|
||||||
let end = off + record.len();
|
let end = off + record.len();
|
||||||
let index = self.num_records();
|
let index = self.num_records();
|
||||||
if end > self.bytes.len() {
|
if end > self.bytes.len() || index >= MAX_RECORDS {
|
||||||
debug!("WARNING the sharedQueue overflowed");
|
debug!("WARNING the sharedQueue overflowed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -138,6 +166,12 @@ impl SharedQueue {
|
||||||
let u32_slice = self.as_u32_slice_mut();
|
let u32_slice = self.as_u32_slice_mut();
|
||||||
u32_slice[INDEX_NUM_RECORDS] += 1;
|
u32_slice[INDEX_NUM_RECORDS] += 1;
|
||||||
u32_slice[INDEX_HEAD] = end as u32;
|
u32_slice[INDEX_HEAD] = end as u32;
|
||||||
|
debug!(
|
||||||
|
"rust:shared_queue:push: num_records={}, num_shifted_off={}, head={}",
|
||||||
|
self.num_records(),
|
||||||
|
self.num_shifted_off(),
|
||||||
|
self.head()
|
||||||
|
);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,4 +247,16 @@ mod tests {
|
||||||
assert_eq!(q.shift().unwrap().len(), 1);
|
assert_eq!(q.shift().unwrap().len(), 1);
|
||||||
assert_eq!(q.size(), 0);
|
assert_eq!(q.size(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn full_records() {
|
||||||
|
let mut q = SharedQueue::new(RECOMMENDED_SIZE);
|
||||||
|
for _ in 0..MAX_RECORDS {
|
||||||
|
assert!(q.push(&alloc_buf(1)))
|
||||||
|
}
|
||||||
|
assert_eq!(q.push(&alloc_buf(1)), false);
|
||||||
|
// Even if we shift one off, we still cannot push a new record.
|
||||||
|
assert_eq!(q.shift().unwrap().len(), 1);
|
||||||
|
assert_eq!(q.push(&alloc_buf(1)), false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,21 @@ function assert(cond) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check overflow (corresponds to full_records test in rust)
|
||||||
|
function fullRecords(q) {
|
||||||
|
q.reset();
|
||||||
|
const oneByte = new Uint8Array([42]);
|
||||||
|
for (let i = 0; i < q.MAX_RECORDS; i++) {
|
||||||
|
assert(q.push(oneByte));
|
||||||
|
}
|
||||||
|
assert(!q.push(oneByte));
|
||||||
|
r = q.shift();
|
||||||
|
assert(r.byteLength == 1);
|
||||||
|
assert(r[0] == 42);
|
||||||
|
// Even if we shift one off, we still cannot push a new record.
|
||||||
|
assert(!q.push(oneByte));
|
||||||
|
}
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
const q = Deno.core.sharedQueue;
|
const q = Deno.core.sharedQueue;
|
||||||
|
|
||||||
|
@ -56,7 +71,10 @@ function main() {
|
||||||
assert(q.numRecords() == 0);
|
assert(q.numRecords() == 0);
|
||||||
assert(q.size() == 0);
|
assert(q.size() == 0);
|
||||||
|
|
||||||
|
fullRecords(q);
|
||||||
|
|
||||||
Deno.core.print("shared_queue_test.js ok\n");
|
Deno.core.print("shared_queue_test.js ok\n");
|
||||||
|
q.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
main();
|
main();
|
||||||
|
|
Loading…
Reference in a new issue