Skip to content

Commit 2feb3fa

Browse files
committed
map complete near cache
1 parent 2d42ce7 commit 2feb3fa

20 files changed

+1825
-785
lines changed

src/ClientMessage.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@ class ClientMessage {
231231
return result;
232232
}
233233

234+
isComplete(): boolean {
235+
return (this.cursor >= BitsUtil.HEADER_SIZE) && (this.cursor === this.getFrameLength());
236+
}
237+
234238
readMapEntry(): any {
235239
// TODO
236240
}

src/Config.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,6 @@ export enum InMemoryFormat {
151151
BINARY
152152
}
153153

154-
export enum LocalUpdatePolicy {
155-
INVALIDATE,
156-
CACHE
157-
}
158-
159154
export class NearCacheConfig {
160155
name: string = 'default';
161156
/**

src/DataStoreHashMap.ts

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import {Data} from './serialization/Data';
2+
export class DataKeyedHashMap<T> {
3+
4+
private internalStore: Map<number, Array<InternalRecord<T>>>;
5+
6+
size: number;
7+
8+
constructor() {
9+
this.internalStore = new Map();
10+
this.size = 0;
11+
}
12+
13+
clear(): void {
14+
this.size = 0;
15+
this.internalStore = new Map();
16+
}
17+
18+
delete(key: Data): boolean {
19+
var existingIndex = this.findIndexInBucket(key);
20+
if (existingIndex === -1) {
21+
return false;
22+
} else {
23+
this.getOrCreateBucket(key.hashCode()).splice(existingIndex, 1);
24+
this.size--;
25+
return true;
26+
}
27+
}
28+
29+
has(key: Data): boolean {
30+
return this.findIndexInBucket(key) !== -1;
31+
}
32+
33+
get(key: Data): T {
34+
var keyHash = key.hashCode();
35+
var existingIndex = this.findIndexInBucket(key);
36+
if (existingIndex !== -1) {
37+
return this.getOrCreateBucket(keyHash)[existingIndex].value;
38+
} else {
39+
return undefined;
40+
}
41+
}
42+
43+
set(key: Data, value: any): this {
44+
var keyHash = key.hashCode();
45+
var existingIndex = this.findIndexInBucket(key);
46+
if (existingIndex !== -1) {
47+
this.getOrCreateBucket(keyHash)[existingIndex].value = value;
48+
} else {
49+
this.getOrCreateBucket(keyHash).push({key: key, value: value});
50+
this.size++;
51+
}
52+
return this;
53+
}
54+
55+
values(): Array<T> {
56+
var snapshot: Array<T> = [];
57+
this.internalStore.forEach((bucket: Array<InternalRecord<T>>) => {
58+
snapshot.push(...(bucket.map((item: InternalRecord<T>) => { return item.value; })));
59+
});
60+
return snapshot;
61+
}
62+
63+
entries(): Array<[Data, T]> {
64+
var snapshot: Array<[Data, T]> = [];
65+
this.internalStore.forEach((bucket: Array<InternalRecord<T>>) => {
66+
snapshot.push(...(bucket.map((item: InternalRecord<T>) => {
67+
return <[Data, T]>[item.key, item.value];
68+
})));
69+
});
70+
return snapshot;
71+
}
72+
73+
/**
74+
*
75+
* @param key
76+
* @returns index of the key if it exists, -1 if either bucket or item does not exist
77+
*/
78+
private findIndexInBucket(key: Data): number {
79+
var keyHash = key.hashCode();
80+
var bucket = this.internalStore.get(keyHash);
81+
if (bucket === undefined) {
82+
return -1;
83+
} else {
84+
return bucket.findIndex((item: InternalRecord<T> ) => {
85+
return item.key.equals(key);
86+
});
87+
}
88+
}
89+
90+
private getOrCreateBucket(key: number): Array<InternalRecord<T>> {
91+
var bucket: Array<InternalRecord<T>>;
92+
bucket = this.internalStore.get(key);
93+
if (bucket === undefined) {
94+
bucket = [];
95+
this.internalStore.set(key, bucket);
96+
}
97+
return bucket;
98+
}
99+
}
100+
101+
class InternalRecord<T> {
102+
key: Data;
103+
value: T;
104+
}

src/PartitionService.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ class PartitionService {
5858
}
5959
return Math.abs(partitionHash) % this.partitionCount;
6060
}
61+
62+
getPartitionCount(): number {
63+
return this.partitionCount;
64+
}
6165
}
6266

6367
export = PartitionService;

src/codec/MapAddNearCacheEntryListenerCodec.ts

Lines changed: 72 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
/* tslint:disable */
22
import ClientMessage = require('../ClientMessage');
33
import {BitsUtil} from '../BitsUtil';
4-
import {Data} from '../serialization/Data';
5-
import {MapMessageType} from './MapMessageType';
64
import Address = require('../Address');
5+
import {AddressCodec} from './AddressCodec';
6+
import {UUIDCodec} from './UUIDCodec';
7+
import {MemberCodec} from './MemberCodec';
8+
import {Data} from '../serialization/Data';
9+
import {EntryViewCodec} from './EntryViewCodec';
710
import DistributedObjectInfoCodec = require('./DistributedObjectInfoCodec');
11+
import {MapMessageType} from './MapMessageType';
812

913
var REQUEST_TYPE = MapMessageType.MAP_ADDNEARCACHEENTRYLISTENER;
1014
var RESPONSE_TYPE = 104;
1115
var RETRYABLE = false;
1216

13-
1417
export class MapAddNearCacheEntryListenerCodec {
1518

16-
1719
static calculateSize(name: string, listenerFlags: number, localOnly: boolean) {
1820
// Calculates the request payload size
1921
var dataSize: number = 0;
@@ -47,23 +49,77 @@ export class MapAddNearCacheEntryListenerCodec {
4749

4850
var messageType = clientMessage.getMessageType();
4951
if (messageType === BitsUtil.EVENT_IMAPINVALIDATION && handleEventImapinvalidation !== null) {
50-
var key: Data;
52+
var messageFinished = false;
53+
var key: Data = undefined;
54+
if (!messageFinished) {
5155

52-
if (clientMessage.readBoolean() !== true) {
53-
key = clientMessage.readData();
56+
if (clientMessage.readBoolean() !== true) {
57+
key = clientMessage.readData();
58+
}
59+
}
60+
var sourceUuid: string = undefined;
61+
if (!messageFinished) {
62+
messageFinished = clientMessage.isComplete();
5463
}
55-
handleEventImapinvalidation(key);
64+
if (!messageFinished) {
65+
sourceUuid = clientMessage.readString();
66+
}
67+
var partitionUuid: any = undefined;
68+
if (!messageFinished) {
69+
partitionUuid = UUIDCodec.decode(clientMessage, toObjectFunction);
70+
}
71+
var sequence: any = undefined;
72+
if (!messageFinished) {
73+
sequence = clientMessage.readLong();
74+
}
75+
handleEventImapinvalidation(key, sourceUuid, partitionUuid, sequence);
5676
}
5777
if (messageType === BitsUtil.EVENT_IMAPBATCHINVALIDATION && handleEventImapbatchinvalidation !== null) {
58-
var keys: any;
59-
var keysSize = clientMessage.readInt32();
60-
keys = [];
61-
for (var keysIndex = 0; keysIndex < keysSize; keysIndex++) {
62-
var keysItem: Data;
63-
keysItem = clientMessage.readData();
64-
keys.push(keysItem)
78+
var messageFinished = false;
79+
var keys: any = undefined;
80+
if (!messageFinished) {
81+
var keysSize = clientMessage.readInt32();
82+
keys = [];
83+
for (var keysIndex = 0; keysIndex < keysSize; keysIndex++) {
84+
var keysItem: Data;
85+
keysItem = clientMessage.readData();
86+
keys.push(keysItem)
87+
}
88+
}
89+
var sourceUuids: any = undefined;
90+
if (!messageFinished) {
91+
messageFinished = clientMessage.isComplete();
92+
}
93+
if (!messageFinished) {
94+
var sourceUuidsSize = clientMessage.readInt32();
95+
sourceUuids = [];
96+
for (var sourceUuidsIndex = 0; sourceUuidsIndex < sourceUuidsSize; sourceUuidsIndex++) {
97+
var sourceUuidsItem: string;
98+
sourceUuidsItem = clientMessage.readString();
99+
sourceUuids.push(sourceUuidsItem)
100+
}
101+
}
102+
var partitionUuids: any = undefined;
103+
if (!messageFinished) {
104+
var partitionUuidsSize = clientMessage.readInt32();
105+
partitionUuids = [];
106+
for (var partitionUuidsIndex = 0; partitionUuidsIndex < partitionUuidsSize; partitionUuidsIndex++) {
107+
var partitionUuidsItem: any;
108+
partitionUuidsItem = UUIDCodec.decode(clientMessage, toObjectFunction);
109+
partitionUuids.push(partitionUuidsItem)
110+
}
111+
}
112+
var sequences: any = undefined;
113+
if (!messageFinished) {
114+
var sequencesSize = clientMessage.readInt32();
115+
sequences = [];
116+
for (var sequencesIndex = 0; sequencesIndex < sequencesSize; sequencesIndex++) {
117+
var sequencesItem: any;
118+
sequencesItem = clientMessage.readLong();
119+
sequences.push(sequencesItem)
120+
}
65121
}
66-
handleEventImapbatchinvalidation(keys);
122+
handleEventImapbatchinvalidation(keys, sourceUuids, partitionUuids, sequences);
67123
}
68124
}
69125

src/codec/UUIDCodec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import ClientMessage = require('../ClientMessage');
2+
import {UUID} from '../core/UUID';
3+
export class UUIDCodec {
4+
static decode(clientMessage: ClientMessage, toObject: Function): UUID {
5+
var uuid: UUID;
6+
uuid.mostSignificant = clientMessage.readLong();
7+
uuid.leastSignificant = clientMessage.readLong();
8+
return uuid;
9+
}
10+
}

src/core/UUID.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import * as Long from 'long';
2+
export interface UUID {
3+
leastSignificant: Long;
4+
mostSignificant: Long;
5+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import {NearCache, NearCacheStatistics} from './NearCache';
2+
import {Data} from '../serialization/Data';
3+
import {KeyStateMarker, KeyStateMarkerImpl} from './KeyStateMarker';
4+
export class InvalidationAwareWrapper implements NearCache {
5+
6+
private nearCache: NearCache;
7+
private keyStateMarker: KeyStateMarker;
8+
9+
public static asInvalidationAware(nearCache: NearCache, markerCount: number): InvalidationAwareWrapper {
10+
return new InvalidationAwareWrapper(nearCache, markerCount);
11+
}
12+
13+
private constructor(nearCache: NearCache, markerCount: number) {
14+
this.nearCache = nearCache;
15+
this.keyStateMarker = new KeyStateMarkerImpl(markerCount);
16+
}
17+
18+
put(key: Data, value: any): void {
19+
return this.nearCache.put(key, value);
20+
}
21+
22+
get(key: Data): Data|any {
23+
return this.nearCache.get(key);
24+
}
25+
26+
invalidate(key: Data): void {
27+
this.keyStateMarker.removeIfMarked(key);
28+
return this.nearCache.invalidate(key);
29+
}
30+
31+
clear(): void {
32+
this.keyStateMarker.unmarkAllForcibly();
33+
return this.nearCache.clear();
34+
}
35+
36+
getStatistics(): NearCacheStatistics {
37+
return this.nearCache.getStatistics();
38+
}
39+
40+
isInvalidatedOnChange(): boolean {
41+
return this.nearCache.isInvalidatedOnChange();
42+
}
43+
44+
getKeyStateMarker(): KeyStateMarker {
45+
return this.keyStateMarker;
46+
}
47+
}

0 commit comments

Comments
 (0)