Skip to content

Commit

Permalink
Project import generated by Copybara
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 301311140
  • Loading branch information
rafi-kamal authored and copybara-github committed Mar 17, 2020
1 parent 422053f commit da1c464
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 113 deletions.
130 changes: 130 additions & 0 deletions js/experimental/runtime/kernel/binary_storage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
goog.module('protobuf.runtime.BinaryStorage');

const Storage = goog.require('protobuf.runtime.Storage');
const {checkDefAndNotNull} = goog.require('protobuf.internal.checks');

/**
* Class storing all the fields of a binary protobuf message.
*
* @package
* @template FieldType
* @implements {Storage}
*/
class BinaryStorage {
/**
* @param {number=} pivot
*/
constructor(pivot = Storage.DEFAULT_PIVOT) {
/**
* Fields having a field number no greater than the pivot value are stored
* into an array for fast access. A field with field number X is stored into
* the array position X - 1.
*
* @private @const {!Array<!FieldType|undefined>}
*/
this.array_ = new Array(pivot);

/**
* Fields having a field number higher than the pivot value are stored into
* the map. We create the map only when it's needed, since even an empty map
* takes up a significant amount of memory.
*
* @private {?Map<number, !FieldType>}
*/
this.map_ = null;
}

/**
* Fields having a field number no greater than the pivot value are stored
* into an array for fast access. A field with field number X is stored into
* the array position X - 1.
* @return {number}
* @override
*/
getPivot() {
return this.array_.length;
}

/**
* Sets a field in the specified field number.
*
* @param {number} fieldNumber
* @param {!FieldType} field
* @override
*/
set(fieldNumber, field) {
if (fieldNumber <= this.getPivot()) {
this.array_[fieldNumber - 1] = field;
} else {
if (this.map_) {
this.map_.set(fieldNumber, field);
} else {
this.map_ = new Map([[fieldNumber, field]]);
}
}
}

/**
* Returns a field at the specified field number.
*
* @param {number} fieldNumber
* @return {!FieldType|undefined}
* @override
*/
get(fieldNumber) {
if (fieldNumber <= this.getPivot()) {
return this.array_[fieldNumber - 1];
} else {
return this.map_ ? this.map_.get(fieldNumber) : undefined;
}
}

/**
* Deletes a field from the specified field number.
*
* @param {number} fieldNumber
* @override
*/
delete(fieldNumber) {
if (fieldNumber <= this.getPivot()) {
delete this.array_[fieldNumber - 1];
} else {
if (this.map_) {
this.map_.delete(fieldNumber);
}
}
}

/**
* Executes the provided function once for each field.
*
* @param {function(!FieldType, number): void} callback
* @override
*/
forEach(callback) {
this.array_.forEach((field, fieldNumber) => {
if (field) {
callback(checkDefAndNotNull(field), fieldNumber + 1);
}
});
if (this.map_) {
this.map_.forEach(callback);
}
}

/**
* Creates a shallow copy of the storage.
*
* @return {!BinaryStorage}
* @override
*/
shallowCopy() {
const copy = new BinaryStorage(this.getPivot());
this.forEach(
(field, fieldNumber) =>
void copy.set(fieldNumber, field.shallowCopy()));
return copy;
}
}

exports = BinaryStorage;
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/**
* @fileoverview Tests for storage.js.
*/
goog.module('protobuf.binary.StorageTest');
goog.module('protobuf.runtime.BinaryStorageTest');

goog.setTestOnly();

const Storage = goog.require('protobuf.binary.Storage');
const BinaryStorage = goog.require('protobuf.runtime.BinaryStorage');
const {Field} = goog.require('protobuf.binary.field');

/**
Expand All @@ -25,7 +25,7 @@ const /** !Field */ field4 =
/**
* Returns the number of fields stored.
*
* @param {!Storage} storage
* @param {!BinaryStorage} storage
* @return {number}
*/
function getStorageSize(storage) {
Expand All @@ -34,9 +34,9 @@ function getStorageSize(storage) {
return size;
}

describe('Storage', () => {
describe('BinaryStorage', () => {
it('sets and gets a field not greater than the pivot', () => {
const storage = new Storage(DEFAULT_PIVOT);
const storage = new BinaryStorage(DEFAULT_PIVOT);

storage.set(1, field1);
storage.set(DEFAULT_PIVOT, field2);
Expand All @@ -47,7 +47,7 @@ describe('Storage', () => {
});

it('sets and gets a field greater than the pivot', () => {
const storage = new Storage(DEFAULT_PIVOT);
const storage = new BinaryStorage(DEFAULT_PIVOT);

storage.set(DEFAULT_PIVOT + 1, field1);
storage.set(100000, field2);
Expand All @@ -57,7 +57,7 @@ describe('Storage', () => {
});

it('sets and gets a field when pivot is zero', () => {
const storage = new Storage(0);
const storage = new BinaryStorage(0);

storage.set(0, field1);
storage.set(100000, field2);
Expand All @@ -68,7 +68,7 @@ describe('Storage', () => {
});

it('sets and gets a field when pivot is undefined', () => {
const storage = new Storage();
const storage = new BinaryStorage();

storage.set(0, field1);
storage.set(DEFAULT_PIVOT, field2);
Expand All @@ -81,7 +81,7 @@ describe('Storage', () => {
});

it('returns undefined for nonexistent fields', () => {
const storage = new Storage(DEFAULT_PIVOT);
const storage = new BinaryStorage(DEFAULT_PIVOT);

expect(storage.get(1)).toBeUndefined();
expect(storage.get(DEFAULT_PIVOT)).toBeUndefined();
Expand All @@ -91,7 +91,7 @@ describe('Storage', () => {

it('returns undefined for nonexistent fields after map initialization',
() => {
const storage = new Storage(DEFAULT_PIVOT);
const storage = new BinaryStorage(DEFAULT_PIVOT);
storage.set(100001, field1);

expect(storage.get(1)).toBeUndefined();
Expand All @@ -101,7 +101,7 @@ describe('Storage', () => {
});

it('deletes a field in delete() when values are only in array', () => {
const storage = new Storage(DEFAULT_PIVOT);
const storage = new BinaryStorage(DEFAULT_PIVOT);
storage.set(1, field1);

storage.delete(1);
Expand All @@ -111,7 +111,7 @@ describe('Storage', () => {

it('deletes a field in delete() when values are both in array and map',
() => {
const storage = new Storage(DEFAULT_PIVOT);
const storage = new BinaryStorage(DEFAULT_PIVOT);
storage.set(DEFAULT_PIVOT, field2);
storage.set(DEFAULT_PIVOT + 1, field3);

Expand All @@ -123,7 +123,7 @@ describe('Storage', () => {
});

it('deletes a field in delete() when values are only in map', () => {
const storage = new Storage(DEFAULT_PIVOT);
const storage = new BinaryStorage(DEFAULT_PIVOT);
storage.set(100000, field4);

storage.delete(100000);
Expand All @@ -132,7 +132,7 @@ describe('Storage', () => {
});

it('loops over all the elements in forEach()', () => {
const storage = new Storage(DEFAULT_PIVOT);
const storage = new BinaryStorage(DEFAULT_PIVOT);
storage.set(1, field1);
storage.set(DEFAULT_PIVOT, field2);
storage.set(DEFAULT_PIVOT + 1, field3);
Expand All @@ -150,7 +150,7 @@ describe('Storage', () => {
});

it('creates a shallow copy of the storage in shallowCopy()', () => {
const storage = new Storage(DEFAULT_PIVOT);
const storage = new BinaryStorage(DEFAULT_PIVOT);
storage.set(1, field1);
storage.set(100000, field2);

Expand Down
8 changes: 4 additions & 4 deletions js/experimental/runtime/kernel/indexer.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
*/
goog.module('protobuf.binary.indexer');

const BinaryStorage = goog.require('protobuf.runtime.BinaryStorage');
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
const Storage = goog.require('protobuf.binary.Storage');
const WireType = goog.require('protobuf.binary.WireType');
const {Field} = goog.require('protobuf.binary.field');
const {checkCriticalElementIndex, checkCriticalState} = goog.require('protobuf.internal.checks');

/**
* Appends a new entry in the index array for the given field number.
* @param {!Storage<!Field>} storage
* @param {!BinaryStorage<!Field>} storage
* @param {number} fieldNumber
* @param {!WireType} wireType
* @param {number} startIndex
Expand Down Expand Up @@ -50,13 +50,13 @@ function tagToFieldNumber(tag) {
* Creates an index of field locations in a given binary protobuf.
* @param {!BufferDecoder} bufferDecoder
* @param {number|undefined} pivot
* @return {!Storage<!Field>}
* @return {!BinaryStorage<!Field>}
* @package
*/
function buildIndex(bufferDecoder, pivot) {
bufferDecoder.setCursor(bufferDecoder.startIndex());

const storage = new Storage(pivot);
const storage = new BinaryStorage(pivot);
while (bufferDecoder.hasNext()) {
const tag = bufferDecoder.getUnsignedVarint32();
const wireType = tagToWireType(tag);
Expand Down
6 changes: 3 additions & 3 deletions js/experimental/runtime/kernel/indexer_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ goog.setTestOnly();
// in this file have to know which checking level is enabled to make correct
// assertions.
// Test are run in all checking levels.
const BinaryStorage = goog.require('protobuf.runtime.BinaryStorage');
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
const Storage = goog.require('protobuf.binary.Storage');
const WireType = goog.require('protobuf.binary.WireType');
const {CHECK_CRITICAL_STATE} = goog.require('protobuf.internal.checks');
const {Field, IndexEntry} = goog.require('protobuf.binary.field');
Expand All @@ -21,7 +21,7 @@ const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'
/**
* Returns the number of fields stored.
*
* @param {!Storage} storage
* @param {!BinaryStorage} storage
* @return {number}
*/
function getStorageSize(storage) {
Expand All @@ -37,7 +37,7 @@ const PIVOT = 1;

/**
* Asserts a single IndexEntry at a given field number.
* @param {!Storage} storage
* @param {!BinaryStorage} storage
* @param {number} fieldNumber
* @param {...!IndexEntry} expectedEntries
*/
Expand Down
5 changes: 3 additions & 2 deletions js/experimental/runtime/kernel/kernel.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@
*/
goog.module('protobuf.runtime.Kernel');

const BinaryStorage = goog.require('protobuf.runtime.BinaryStorage');
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
const ByteString = goog.require('protobuf.ByteString');
const Int64 = goog.require('protobuf.Int64');
const InternalMessage = goog.require('protobuf.binary.InternalMessage');
const Storage = goog.require('protobuf.binary.Storage');
const Storage = goog.require('protobuf.runtime.Storage');
const WireType = goog.require('protobuf.binary.WireType');
const Writer = goog.require('protobuf.binary.Writer');
const reader = goog.require('protobuf.binary.reader');
Expand Down Expand Up @@ -278,7 +279,7 @@ class Kernel {
* @return {!Kernel}
*/
static createEmpty(pivot = undefined) {
return new Kernel(/* bufferDecoder= */ null, new Storage(pivot));
return new Kernel(/* bufferDecoder= */ null, new BinaryStorage(pivot));
}

/**
Expand Down
Loading

0 comments on commit da1c464

Please sign in to comment.