mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
![Martin Kustermann](/assets/img/avatar_default.png)
The [FixedCache] will be accessible by multiple isolates within an isolate group as well as the GC, so we add locking around it's accessors. This is a preparation step for the shared heap. Issue https://github.com/dart-lang/sdk/issues/36097 Change-Id: Ief113419b3f7a69eda02084ce36cef0e25984315 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/133580 Reviewed-by: Ryan Macnak <rmacnak@google.com> Commit-Queue: Martin Kustermann <kustermann@google.com>
94 lines
2.1 KiB
C++
94 lines
2.1 KiB
C++
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#ifndef RUNTIME_VM_FIXED_CACHE_H_
|
|
#define RUNTIME_VM_FIXED_CACHE_H_
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#include "vm/lockers.h"
|
|
|
|
namespace dart {
|
|
|
|
// A simple sorted fixed size Key-Value storage.
|
|
//
|
|
// Assumes both Key and Value are default-constructible objects.
|
|
//
|
|
// Keys must be comparable with operator<.
|
|
//
|
|
// Duplicates are not allowed - check with Lookup before insertion.
|
|
//
|
|
template <class K, class V, intptr_t kCapacity>
|
|
class FixedCache {
|
|
public:
|
|
struct Entry {
|
|
K key;
|
|
V value;
|
|
};
|
|
|
|
FixedCache() : length_(0) {}
|
|
|
|
~FixedCache() { Clear(); }
|
|
|
|
V* Lookup(K key) {
|
|
MutexLocker ml(&mutex_);
|
|
|
|
intptr_t i = LowerBound(key);
|
|
if (i != length_ && pairs_[i].key == key) return &pairs_[i].value;
|
|
return NULL;
|
|
}
|
|
|
|
void Insert(K key, V value) {
|
|
MutexLocker ml(&mutex_);
|
|
|
|
intptr_t i = LowerBound(key);
|
|
|
|
if (length_ == kCapacity) {
|
|
length_ = kCapacity - 1;
|
|
if (i == kCapacity) i = kCapacity - 1;
|
|
}
|
|
|
|
for (intptr_t j = length_ - 1; j >= i; j--) {
|
|
pairs_[j + 1] = pairs_[j];
|
|
}
|
|
|
|
length_ += 1;
|
|
pairs_[i].key = key;
|
|
pairs_[i].value = value;
|
|
}
|
|
|
|
void Clear() {
|
|
MutexLocker ml(&mutex_);
|
|
length_ = 0;
|
|
}
|
|
|
|
private:
|
|
intptr_t LowerBound(K key) {
|
|
intptr_t low = 0, high = length_;
|
|
while (low != high) {
|
|
intptr_t mid = low + (high - low) / 2;
|
|
if (key < pairs_[mid].key) {
|
|
high = mid;
|
|
} else if (key > pairs_[mid].key) {
|
|
low = mid + 1;
|
|
} else {
|
|
low = high = mid;
|
|
}
|
|
}
|
|
return low;
|
|
}
|
|
|
|
// We protect any operation on the [FixedCache] because multiple isolates from
|
|
// the same [IsolateGroup] can access this cache concurrently (as can the GC
|
|
// when it clears it).
|
|
Mutex mutex_;
|
|
Entry pairs_[kCapacity]; // Sorted array of pairs.
|
|
intptr_t length_;
|
|
};
|
|
|
|
} // namespace dart
|
|
|
|
#endif // RUNTIME_VM_FIXED_CACHE_H_
|