<commit_before>var assert = require("assert");
var Q = require("q");
var fs = require("fs");
var path = require("path");
var util = require("./util");

function DiskCache(cacheDirP) {
    var self = this;
    assert.ok(self instanceof DiskCache);

    Object.defineProperties(self, {
        cacheDirP: { value: cacheDirP }
    });
}

var DCp = DiskCache.prototype;

DCp.setDefaultP = util.cachedMethod(function(key, toStringP, fromStringP) {
    return this.cacheDirP.then(function(cacheDir) {
        var file = path.join(cacheDir, key + ".js");
        return util.openExclusiveP(file).then(function(fd) {
            var stringP = Q.resolve(toStringP());
            return stringP.then(function(string) {
                return util.writeFdP(fd, string);
            });
        }, function(err) {
            assert.strictEqual(err.code, "EEXIST"); // TODO
            // TODO Deal with inter-process race condition!
            return util.readFileP(file);
        });
    }).then(fromStringP);
}, function(key, toStringP, fromStringP) {
    return key;
});

DCp.linkP = function(key, file) {
    return Q.all([
        this.cacheDirP,
        util.mkdirP(path.dirname(file))
    ]).spread(function(cacheDir) {
        var cacheFile = path.join(cacheDir, key + ".js");
        return util.linkP(
            cacheFile, file
        ).catch(function(err) {
            // If the new file is not on the same device as the cache
            // file, just make a copy.
            return util.copyP(cacheFile, file);
        });
    });
};

exports.DiskCache = DiskCache;

function ProcessCache() {
    assert.ok(this instanceof ProcessCache);
}

var PCp = ProcessCache.prototype;

PCp.setDefaultP = util.cachedMethod(function(key, toStringP, fromStringP) {
    return fromStringP(toStringP());
}, function(key, toStringP, fromStringP) {
    return key;
});

PCp.linkP = function(key, file) {
    return this.setDefaultP(
        key,
        coldCacheError, // It's a mistake to call .linkP before
        coldCacheError  // calling .setDefaultP.
    ).then(function(source) {
        return util.openExclusiveP(file).then(function(fd) {
            return util.writeFdP(fd, source);
        });
    });
};<commit_msg>Handle case when toStringP and/or fromStringP do not return promises.<commit_after>var assert = require("assert");
var Q = require("q");
var fs = require("fs");
var path = require("path");
var util = require("./util");

function DiskCache(cacheDirP) {
    var self = this;
    assert.ok(self instanceof DiskCache);

    Object.defineProperties(self, {
        cacheDirP: { value: cacheDirP }
    });
}

var DCp = DiskCache.prototype;

DCp.setDefaultP = util.cachedMethod(function(key, toStringP, fromStringP) {
    return this.cacheDirP.then(function(cacheDir) {
        var file = path.join(cacheDir, key + ".js");
        return util.openExclusiveP(file).then(function(fd) {
            var stringP = Q.resolve(toStringP());
            return stringP.then(function(string) {
                return util.writeFdP(fd, string);
            });
        }, function(err) {
            assert.strictEqual(err.code, "EEXIST"); // TODO
            // TODO Deal with inter-process race condition!
            return util.readFileP(file);
        });
    }).then(fromStringP);
}, function(key, toStringP, fromStringP) {
    return key;
});

DCp.linkP = function(key, file) {
    return Q.all([
        this.cacheDirP,
        util.mkdirP(path.dirname(file))
    ]).spread(function(cacheDir) {
        var cacheFile = path.join(cacheDir, key + ".js");
        return util.linkP(
            cacheFile, file
        ).catch(function(err) {
            // If the new file is not on the same device as the cache
            // file, just make a copy.
            return util.copyP(cacheFile, file);
        });
    });
};

exports.DiskCache = DiskCache;

function ProcessCache() {
    assert.ok(this instanceof ProcessCache);
}

var PCp = ProcessCache.prototype;

PCp.setDefaultP = util.cachedMethod(function(key, toStringP, fromStringP) {
    var stringP = Q.resolve(toStringP());
    return stringP.then(function(string) {
        return fromStringP(string);
    });
}, function(key, toStringP, fromStringP) {
    return key;
});

PCp.linkP = function(key, file) {
    return this.setDefaultP(
        key,
        coldCacheError, // It's a mistake to call .linkP before
        coldCacheError  // calling .setDefaultP.
    ).then(function(source) {
        return util.openExclusiveP(file).then(function(fd) {
            return util.writeFdP(fd, source);
        });
    });
};
{'fraction_non_alphanumeric': 0.13436411149825783, 'fraction_numerical': 0.0, 'mean_word_length': 2.5938967136150235, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7004047', 'n_tokens_mistral': 1403, 'n_tokens_neox': 1391, 'n_words': 318}