Rename to FileSystemBlobStore

This commit is contained in:
Antonio Scandurra
2015-10-30 18:42:38 +01:00
parent f8c2c912e3
commit abcfc8579b
7 changed files with 187 additions and 187 deletions

View File

@@ -0,0 +1,69 @@
temp = require 'temp'
FileSystemBlobStore = require '../src/file-system-blob-store'
describe "FileSystemBlobStore", ->
[storageDirectory, blobStore] = []
beforeEach ->
storageDirectory = temp.path()
blobStore = FileSystemBlobStore.load(storageDirectory)
it "is empty when the file doesn't exist", ->
expect(blobStore.get("foo")).toBeUndefined()
expect(blobStore.get("bar")).toBeUndefined()
it "allows to read and write buffers from/to memory without persisting them", ->
blobStore.set("foo", new Buffer("foo"))
blobStore.set("bar", new Buffer("bar"))
expect(blobStore.get("foo")).toEqual(new Buffer("foo"))
expect(blobStore.get("bar")).toEqual(new Buffer("bar"))
it "persists buffers when saved and retrieves them on load, giving priority to in-memory ones", ->
blobStore.set("foo", new Buffer("foo"))
blobStore.set("bar", new Buffer("bar"))
blobStore.save()
blobStore = FileSystemBlobStore.load(storageDirectory)
expect(blobStore.get("foo")).toEqual(new Buffer("foo"))
expect(blobStore.get("bar")).toEqual(new Buffer("bar"))
blobStore.set("foo", new Buffer("changed"))
expect(blobStore.get("foo")).toEqual(new Buffer("changed"))
it "persists both in-memory and previously stored buffers when saved", ->
blobStore.set("foo", new Buffer("foo"))
blobStore.set("bar", new Buffer("bar"))
blobStore.save()
blobStore = FileSystemBlobStore.load(storageDirectory)
blobStore.set("bar", new Buffer("changed"))
blobStore.set("qux", new Buffer("qux"))
blobStore.save()
blobStore = FileSystemBlobStore.load(storageDirectory)
expect(blobStore.get("foo")).toEqual(new Buffer("foo"))
expect(blobStore.get("bar")).toEqual(new Buffer("changed"))
expect(blobStore.get("qux")).toEqual(new Buffer("qux"))
it "allows to delete keys from both memory and stored buffers", ->
blobStore.set("a", new Buffer("a"))
blobStore.set("b", new Buffer("b"))
blobStore.save()
blobStore = FileSystemBlobStore.load(storageDirectory)
blobStore.set("b", new Buffer("b"))
blobStore.set("c", new Buffer("c"))
blobStore.delete("b")
blobStore.delete("c")
blobStore.save()
blobStore = FileSystemBlobStore.load(storageDirectory)
expect(blobStore.get("a")).toEqual(new Buffer("a"))
expect(blobStore.get("b")).toBeUndefined()
expect(blobStore.get("c")).toBeUndefined()

View File

@@ -1,69 +0,0 @@
temp = require 'temp'
FileSystemCacheBlobStorage = require '../src/file-system-cache-blob-storage'
describe "FileSystemCacheBlobStorage", ->
[storageDirectory, cacheBlobStorage] = []
beforeEach ->
storageDirectory = temp.path()
cacheBlobStorage = FileSystemCacheBlobStorage.load(storageDirectory)
it "is empty when the file doesn't exist", ->
expect(cacheBlobStorage.get("foo")).toBeUndefined()
expect(cacheBlobStorage.get("bar")).toBeUndefined()
it "allows to read and write buffers from/to memory without persisting them", ->
cacheBlobStorage.set("foo", new Buffer("foo"))
cacheBlobStorage.set("bar", new Buffer("bar"))
expect(cacheBlobStorage.get("foo")).toEqual(new Buffer("foo"))
expect(cacheBlobStorage.get("bar")).toEqual(new Buffer("bar"))
it "persists buffers when saved and retrieves them on load, giving priority to in-memory ones", ->
cacheBlobStorage.set("foo", new Buffer("foo"))
cacheBlobStorage.set("bar", new Buffer("bar"))
cacheBlobStorage.save()
cacheBlobStorage = FileSystemCacheBlobStorage.load(storageDirectory)
expect(cacheBlobStorage.get("foo")).toEqual(new Buffer("foo"))
expect(cacheBlobStorage.get("bar")).toEqual(new Buffer("bar"))
cacheBlobStorage.set("foo", new Buffer("changed"))
expect(cacheBlobStorage.get("foo")).toEqual(new Buffer("changed"))
it "persists both in-memory and previously stored buffers when saved", ->
cacheBlobStorage.set("foo", new Buffer("foo"))
cacheBlobStorage.set("bar", new Buffer("bar"))
cacheBlobStorage.save()
cacheBlobStorage = FileSystemCacheBlobStorage.load(storageDirectory)
cacheBlobStorage.set("bar", new Buffer("changed"))
cacheBlobStorage.set("qux", new Buffer("qux"))
cacheBlobStorage.save()
cacheBlobStorage = FileSystemCacheBlobStorage.load(storageDirectory)
expect(cacheBlobStorage.get("foo")).toEqual(new Buffer("foo"))
expect(cacheBlobStorage.get("bar")).toEqual(new Buffer("changed"))
expect(cacheBlobStorage.get("qux")).toEqual(new Buffer("qux"))
it "allows to delete keys from both memory and stored buffers", ->
cacheBlobStorage.set("a", new Buffer("a"))
cacheBlobStorage.set("b", new Buffer("b"))
cacheBlobStorage.save()
cacheBlobStorage = FileSystemCacheBlobStorage.load(storageDirectory)
cacheBlobStorage.set("b", new Buffer("b"))
cacheBlobStorage.set("c", new Buffer("c"))
cacheBlobStorage.delete("b")
cacheBlobStorage.delete("c")
cacheBlobStorage.save()
cacheBlobStorage = FileSystemCacheBlobStorage.load(storageDirectory)
expect(cacheBlobStorage.get("a")).toEqual(new Buffer("a"))
expect(cacheBlobStorage.get("b")).toBeUndefined()
expect(cacheBlobStorage.get("c")).toBeUndefined()

View File

@@ -1,16 +1,16 @@
describe "NativeCompileCache", ->
nativeCompileCache = require '../src/native-compile-cache'
[fakeCacheStorage, cachedFiles] = []
[fakeCacheStore, cachedFiles] = []
beforeEach ->
cachedFiles = []
fakeCacheStorage = jasmine.createSpyObj("cache storage", ["set", "get", "has", "delete"])
nativeCompileCache.setCacheStorage(fakeCacheStorage)
fakeCacheStore = jasmine.createSpyObj("cache store", ["set", "get", "has", "delete"])
nativeCompileCache.setCacheStore(fakeCacheStore)
nativeCompileCache.install()
it "writes and reads from the cache storage when requiring files", ->
fakeCacheStorage.has.andReturn(false)
fakeCacheStorage.set.andCallFake (filename, cacheBuffer) ->
fakeCacheStore.has.andReturn(false)
fakeCacheStore.set.andCallFake (filename, cacheBuffer) ->
cachedFiles.push({filename, cacheBuffer})
fn1 = require('./fixtures/native-cache/file-1')
@@ -28,20 +28,20 @@ describe "NativeCompileCache", ->
expect(cachedFiles[1].cacheBuffer.length).toBeGreaterThan(0)
expect(fn2()).toBe(2)
fakeCacheStorage.has.andReturn(true)
fakeCacheStorage.get.andReturn(cachedFiles[0].cacheBuffer)
fakeCacheStorage.set.reset()
fakeCacheStore.has.andReturn(true)
fakeCacheStore.get.andReturn(cachedFiles[0].cacheBuffer)
fakeCacheStore.set.reset()
fn1 = require('./fixtures/native-cache/file-1')
expect(fakeCacheStorage.set).not.toHaveBeenCalled()
expect(fakeCacheStore.set).not.toHaveBeenCalled()
expect(fn1()).toBe(1)
it "deletes previously cached code when the cache is not valid", ->
fakeCacheStorage.has.andReturn(true)
fakeCacheStorage.get.andCallFake -> new Buffer("an invalid cache")
fakeCacheStore.has.andReturn(true)
fakeCacheStore.get.andCallFake -> new Buffer("an invalid cache")
fn3 = require('./fixtures/native-cache/file-3')
expect(fakeCacheStorage.delete).toHaveBeenCalledWith(require.resolve('./fixtures/native-cache/file-3'))
expect(fakeCacheStore.delete).toHaveBeenCalledWith(require.resolve('./fixtures/native-cache/file-3'))
expect(fn3()).toBe(3)

View File

@@ -0,0 +1,94 @@
'use strict'
const fs = require('fs-plus')
const path = require('path')
module.exports =
class FileSystemBlobStore {
static load (directory) {
let instance = new FileSystemBlobStore(directory)
instance.load()
return instance
}
constructor (directory) {
this.inMemoryBlobs = new Map()
this.blobFilename = path.join(directory, 'BLOB')
this.mapFilename = path.join(directory, 'MAP')
this.storedBlob = new Buffer(0)
this.storedMap = {}
}
load () {
if (!fs.existsSync(this.mapFilename)) {
return
}
if (!fs.existsSync(this.blobFilename)) {
return
}
this.storedBlob = fs.readFileSync(this.blobFilename)
this.storedMap = JSON.parse(fs.readFileSync(this.mapFilename))
}
save () {
let dump = this.getDump()
let cacheBlob = Buffer.concat(dump[0])
let cacheMap = JSON.stringify(dump[1])
fs.writeFileSync(this.blobFilename, cacheBlob)
fs.writeFileSync(this.mapFilename, cacheMap)
}
has (key) {
return this.inMemoryBlobs.hasOwnProperty(key) || this.storedMap.hasOwnProperty(key)
}
get (key) {
return this.getFromMemory(key) || this.getFromStorage(key)
}
set (key, buffer) {
return this.inMemoryBlobs.set(key, buffer)
}
delete (key) {
this.inMemoryBlobs.delete(key)
delete this.storedMap[key]
}
getFromMemory (key) {
return this.inMemoryBlobs.get(key)
}
getFromStorage (key) {
if (this.storedMap[key] == null) {
return
}
return this.storedBlob.slice.apply(this.storedBlob, this.storedMap[key])
}
getDump () {
let buffers = []
let cacheMap = {}
let currentBufferStart = 0
function dump (key, getBufferByKey) {
let buffer = getBufferByKey(key)
buffers.push(buffer)
cacheMap[key] = [currentBufferStart, currentBufferStart + buffer.length]
currentBufferStart += buffer.length
}
for (let key of this.inMemoryBlobs.keys()) {
dump(key, this.getFromMemory.bind(this))
}
for (let key of Object.keys(this.storedMap)) {
if (!cacheMap[key]) {
dump(key, this.getFromStorage.bind(this))
}
}
return [buffers, cacheMap]
}
}

View File

@@ -1,94 +0,0 @@
'use strict'
const fs = require('fs-plus')
const path = require('path')
module.exports =
class FileSystemCacheBlobStorage {
static load (directory) {
let instance = new FileSystemCacheBlobStorage(directory)
instance.load()
return instance
}
constructor (directory) {
this.inMemoryCache = new Map()
this.cacheBlobFilename = path.join(directory, 'v8-compile-cache.blob')
this.cacheMapFilename = path.join(directory, 'v8-compile-cache.map')
this.storedCacheBlob = new Buffer(0)
this.storedCacheMap = {}
}
load () {
if (!fs.existsSync(this.cacheMapFilename)) {
return
}
if (!fs.existsSync(this.cacheBlobFilename)) {
return
}
this.storedCacheBlob = fs.readFileSync(this.cacheBlobFilename)
this.storedCacheMap = JSON.parse(fs.readFileSync(this.cacheMapFilename))
}
save () {
let dump = this.getDump()
let cacheBlob = Buffer.concat(dump[0])
let cacheMap = JSON.stringify(dump[1])
fs.writeFileSync(this.cacheBlobFilename, cacheBlob)
fs.writeFileSync(this.cacheMapFilename, cacheMap)
}
has (key) {
return this.inMemoryCache.hasOwnProperty(key) || this.storedCacheMap.hasOwnProperty(key)
}
get (key) {
return this.getFromMemory(key) || this.getFromStorage(key)
}
set (key, buffer) {
return this.inMemoryCache.set(key, buffer)
}
delete (key) {
this.inMemoryCache.delete(key)
delete this.storedCacheMap[key]
}
getFromMemory (key) {
return this.inMemoryCache.get(key)
}
getFromStorage (key) {
if (this.storedCacheMap[key] == null) {
return
}
return this.storedCacheBlob.slice.apply(this.storedCacheBlob, this.storedCacheMap[key])
}
getDump () {
let buffers = []
let cacheMap = {}
let currentBufferStart = 0
function dump (key, getBufferByKey) {
let buffer = getBufferByKey(key)
buffers.push(buffer)
cacheMap[key] = [currentBufferStart, currentBufferStart + buffer.length]
currentBufferStart += buffer.length
}
for (let key of this.inMemoryCache.keys()) {
dump(key, this.getFromMemory.bind(this))
}
for (let key of Object.keys(this.storedCacheMap)) {
if (!cacheMap[key]) {
dump(key, this.getFromStorage.bind(this))
}
}
return [buffers, cacheMap]
}
}

View File

@@ -6,12 +6,12 @@ const cachedVm = require('cached-run-in-this-context')
class NativeCompileCache {
constructor () {
this.cacheStorage = null
this.cacheStore = null
this.previousModuleCompile = null
}
setCacheStorage (storage) {
this.cacheStorage = storage
setCacheStore (store) {
this.cacheStore = store
}
install () {
@@ -28,7 +28,7 @@ class NativeCompileCache {
}
overrideModuleCompile () {
let cacheStorage = this.cacheStorage
let cacheStore = this.cacheStore
let resolvedArgv = null
Module.prototype._compile = function (content, filename) {
let self = this
@@ -52,17 +52,17 @@ class NativeCompileCache {
let wrapper = Module.wrap(content)
let compiledWrapper = null
if (cacheStorage.has(filename)) {
let buffer = cacheStorage.get(filename)
if (cacheStore.has(filename)) {
let buffer = cacheStore.get(filename)
let compilationResult = cachedVm.runInThisContextCached(wrapper, filename, buffer)
compiledWrapper = compilationResult.result
if (compilationResult.wasRejected) {
cacheStorage.delete(filename)
cacheStore.delete(filename)
}
} else {
let compilationResult = cachedVm.runInThisContext(wrapper, filename)
if (compilationResult.cacheBuffer) {
cacheStorage.set(filename, compilationResult.cacheBuffer)
cacheStore.set(filename, compilationResult.cacheBuffer)
}
compiledWrapper = compilationResult.result
}

View File

@@ -2,7 +2,7 @@
var app = require('remote').require('app')
var fs = require('fs-plus')
var path = require('path')
var FileSystemCacheBlobStorage = require('../src/file-system-cache-blob-storage')
var FileSystemBlobStore = require('../src/file-system-blob-store')
var NativeCompileCache = require('../src/native-compile-cache')
var loadSettings = null
@@ -26,10 +26,10 @@
// Ensure ATOM_HOME is always set before anything else is required
setupAtomHome()
cacheStorage = FileSystemCacheBlobStorage.load(
path.join(process.env.ATOM_HOME, 'native-compile-cache/')
blobStore = FileSystemBlobStore.load(
path.join(process.env.ATOM_HOME, 'blob-store/')
)
NativeCompileCache.setCacheStorage(cacheStorage)
NativeCompileCache.setCacheStore(blobStore)
NativeCompileCache.install()
// Normalize to make sure drive letter case is consistent on Windows