Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: lib/typedObjects/dictionaryTypes.js

Issue 6253377650425856: WIP - Dictionary types implementation (Closed)
Patch Set: Created Jan. 9, 2015, 3:34 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | lib/typedObjects/hash.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * This file is part of Adblock Plus <http://adblockplus.org/>,
3 * Copyright (C) 2006-2014 Eyeo GmbH
4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 "use strict";
19
20 const LOAD_FACTOR = 0.75;
21
22 let {calculateHash} = require("typedObjects/hash");
23 let {ilog2, nextPow2, alloc, dealloc, addBuffer, removeBuffer} = require("typedO bjects/utils");
24
25 function defaultDictionaryConstructor()
26 {
27 this.dictionaryBufferIndex = -1;
28 };
29
30 function defaultDictionaryDestructor()
31 {
32 this.buckets = 0;
33 };
34
35 function lookup(key, groups, view, offset)
36 {
37 let bucketCount = groups << 5;
38 let bucket = calculateHash(key) & (bucketCount - 1);
39 let group = bucket >>> 5;
40 let bit = 1 << (bucket & 0x1F);
41
42 }
43
44 function createCombinedConstructor(customConstructor)
45 {
46 return function()
47 {
48 defaultDictionaryConstructor.apply(this);
49 customConstructor.apply(this, arguments);
50 }
51 }
52
53 function createCombinedDestructor(customDestructor)
54 {
55 return function()
56 {
57 try
58 {
59 customDestructor.apply(this);
60 }
61 finally
62 {
63 defaultDictionaryDestructor.apply(this);
64 }
65 }
66 }
67
68 function capacityWatcher(newCapacity)
69 {
70 newCapacity = newCapacity | 0;
71 let newBuckets = Math.ceil(newCapacity / LOAD_FACTOR) | 0;
72 if (newBuckets > this.buckets)
73 this.buckets = newBuckets;
74
75 return (this.buckets * LOAD_FACTOR) | 0;
76 }
77
78 function createBucketsWatcher(bucketSize, bufferSize, buffers, viewTypes, views, firstFree)
79 {
80 bufferSize = bufferSize | 0;
81 return function bucketsWatcher(newBuckets)
82 {
83 newBuckets = newBuckets | 0;
84 if (newBuckets < 0)
85 newBuckets = 0;
86 newBuckets = nextPow2(newBuckets);
87
88 let buckets = this.buckets;
89 if (buckets != newBuckets)
90 {
91 let origBufferIndex = this.dictionaryBufferIndex;
92 let origByteOffset = this.dictionaryByteOffset;
93 if (newBuckets > 0)
94 {
95 // Allocate new buffer
96 let bufferIndex, byteOffset;
97 let reference = firstFree[newGroups];
98 if (typeof reference != "undefined")
99 {
100 [bufferIndex, byteOffset] = alloc(reference,
101 bucketSize * newBuckets, (bufferSize / newBuckets) | 0,
102 buffers, viewTypes, views);
103 }
104 else
105 {
106 // This dictionary is too large, it needs an individual buffer
107 bufferIndex = addBuffer(bucketSize * newBuckets, buffers, viewTypes, v iews);
108 byteOffset = 0;
109 }
110
111 if (buckets > 0)
112 {
113 // TODO: Copy data
114 }
115
116 this.dictionaryBufferIndex = bufferIndex;
117 this.dictionaryByteOffset = byteOffset;
118 }
119 else
120 this.dictionaryBufferIndex = -1;
121
122 if (buckets > 0)
123 {
124 // TODO: Release values
125
126 // Release old buffer
127 let reference = firstFree[buckets];
128 if (typeof reference != "undefined")
129 dealloc(reference, origBufferIndex, origByteOffset);
130 else
131 removeBuffer(origBufferIndex, buffers, views);
132 }
133 }
134
135 return newBuckets;
136 }
137 }
138
139 function createDictionaryType(elementType, typeDescriptor, meta)
140 {
141 if (typeof meta != "object" || meta == null)
142 meta = {};
143
144 let {int16, uint32} = require("typedObjects/primitiveTypes");
145 let {string} = require("typedObjects/stringType");
146 let {Reference, TypedReference} = require("typedObjects/references");
147
148 let groupSize = (elementType.referenceLength + string.referenceLength) * SLOTS _PER_GROUP + uint32.byteLength * 2;
149 groupSize = Math.max(groupSize, TypedReference.byteLength);
150 let bufferSize = ("dictionaryBufferSize" in meta ? meta.dictionaryBufferSize | 0 : 128);
151 bufferSize = nextPow2(Math.max(bufferSize, 2)) | 0;
152
153 let buffers = [];
154 let viewTypes = elementType.viewTypes.slice();
155 let views = [];
156 for (let i = 0, l = viewTypes.length | 0; i < l; i++)
157 views.push([]);
158
159 let elementGetter = elementType.createGetter.apply(elementType, [0].concat(vie ws));
160 let elementSetter = elementType.createSetter.apply(elementType, [0].concat(vie ws));
161
162 let typedReferenceTypes = TypedReference.viewTypes;
163 let typedReferenceViews = [];
164 for (let i = 0, l = typedReferenceTypes.length | 0; i < l; i++)
165 {
166 let type = typedReferenceTypes[i];
167 let index = viewTypes.indexOf(type);
168 if (index < 0)
169 {
170 viewTypes.push(type);
171 views.push([]);
172 index = viewTypes.length - 1;
173 }
174 typedReferenceViews.push(views[index]);
175 }
176
177 let firstFree = [];
178 for (let i = 2; i < bufferSize; i <<= 1)
179 firstFree[i] = new TypedReference(-1, typedReferenceViews);
180
181 // Ensure there is a view for uint32
182 let uint32Index = viewTypes.indexOf(uint32.viewTypes[0]);
183 if (uint32Index < 0)
184 {
185 viewTypes.push(uint32.viewTypes[0]);
186 views.push([]);
187 uint32Index = viewTypes.length - 1;
188 }
189
190 let keyGetter = string.createSetter(0)
191 let occupancyGetter = uint32.createGetter(
192 (elementType.referenceLength + string.referenceLength) * SLOTS_PER_GROUP,
193 views[uint32Index]
194 );
195 let deletedGetter = uint32.createGetter(
196 (elementType.referenceLength + string.referenceLength) * SLOTS_PER_GROUP + u int32.byteLength,
197 views[uint32Index]
198 );
199
200 typeDescriptor = Object.create(typeDescriptor || {});
201 typeDescriptor.dictionaryBufferIndex = int16;
202 typeDescriptor.dictionaryByteOffset = uint32;
203 typeDescriptor.getDictionaryBuffer = function()
204 {
205 return this.dictionaryBufferIndex >= 0 ? buffers[this.dictionaryBufferIndex] : null;
206 };
207 typeDescriptor.groups = uint32;
208 typeDescriptor.capacity = uint32;
209
210 // typeDescriptor.get = createGetter(elementGetter);
211 // typeDescriptor.set = createSetter(elementSetter);
212
213 if (meta.hasOwnProperty("constructor") && typeof meta.constructor == "function ")
214 meta.constructor = createCombinedConstructor(meta.constructor);
215 else
216 meta.constructor = defaultDictionaryConstructor;
217
218 if (meta.hasOwnProperty("destructor") && typeof meta.destructor == "function")
219 meta.destructor = createCombinedDestructor(meta.destructor);
220 else
221 meta.destructor = defaultDictionaryDestructor;
222
223 if (!meta.watch || typeof meta.watch != "object")
224 meta.watch = {};
225
226 meta.watch.groups = createGroupsWatcher(groupSize, bufferSize, buffers, viewTy pes, views, firstFree);
227 meta.watch.capacity = capacityWatcher;
228
229 let {ObjectBase} = require("typedObjects/objectTypes");
230 return ObjectBase.extend(typeDescriptor, meta);
231 }
232
233 exports.createDictionaryType = createDictionaryType;
OLDNEW
« no previous file with comments | « no previous file | lib/typedObjects/hash.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld