All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.huaweicloud.dis.util.cache.CacheManager Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2002-2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.huaweicloud.dis.util.cache;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.huaweicloud.dis.Constants;
import com.huaweicloud.dis.DISConfig;
import com.huaweicloud.dis.exception.DISClientException;
import com.huaweicloud.dis.iface.data.request.PutRecordsRequest;
import com.huaweicloud.dis.util.IOUtils;
import com.huaweicloud.dis.util.JsonUtils;

/**
 * 

* 本地缓存管理 *

* */ public class CacheManager implements ICacheManager { private static final Logger LOGGER = LoggerFactory.getLogger(CacheManager.class); private static CacheManager instance; private DISConfig disConfig; private File dataTmpFile; // 临时缓存数据文件对象 private String dataTmpFileName; // 临时缓存数据文件名 private long tmpFileCreateTime; // 临时缓存文件创建时间 private int totalIndex; // 已写入临时缓存文件的请求数 private CacheManager() { } private CacheManager(DISConfig disConfig) { this.disConfig = disConfig; } public static synchronized CacheManager getInstance(DISConfig disConfig) { if (instance == null) { instance = new CacheManager(disConfig); instance.init(); } return instance; } @Override public void putToCache(PutRecordsRequest putRecordsRequest) { LOGGER.info("Put records to cache, record size: {}, cache dir: {}.", putRecordsRequest.getRecords().size(), disConfig.getDataCacheDir()); String data = JsonUtils.objToJson(putRecordsRequest); synchronized (this) { // 缓存临时文件不存在则新建 if (dataTmpFile == null || !dataTmpFile.exists()) { try { dataTmpFile.createNewFile(); } catch (IOException e) { LOGGER.error("Failed to create cache tmp file, return.", e); return ; } } if (needToArchive(data)) { // 缓存临时文件归档 LOGGER.debug("Need to archive cache tmp file, filename: '{}'.", dataTmpFileName); archive(); } if (hasEnoughSpace(data)) { IOUtils.appendToFile(data, dataTmpFileName); totalIndex++; } else { LOGGER.error("Put to cache failed, cache space is not enough, configured max dir size: {}.", disConfig.getDataCacheDiskMaxSize()); } } } @Override public boolean hasEnoughSpace(String data) { long dataSize = getDataSize(data); if ((dataSize + FileUtils.sizeOfDirectory(new File(getCacheDir()))) / 1024 / 1024 > disConfig.getDataCacheDiskMaxSize()) { return false; } return true; } private boolean needToArchive(String data) { long dataSize = getDataSize(data); if (((dataSize + FileUtils.sizeOf(dataTmpFile)) / 1024 > disConfig.getDataCacheArchiveMaxSize()) || (System.currentTimeMillis() - tmpFileCreateTime > disConfig.getDataCacheArchiveLifeCycle() * 1000)) { return true; } return false; } private long getDataSize(String data) { long dataSize = 0; try { dataSize = data.getBytes("UTF-8").length; } catch (UnsupportedEncodingException e) { LOGGER.error("Failed to calculate data size."); throw new DISClientException(e); } return dataSize; } /** * 临时缓存文件归档 */ @Override public void archive() { synchronized (this) { if (dataTmpFile == null || !dataTmpFile.exists()) { LOGGER.error("Tmp cache file not exist, filename: '{}'.", dataTmpFileName); return ; } String archiveDataFilename = dataTmpFileName.replace(Constants.CACHE_TMP_FILE_SUFFIX, "") + Constants.CACHE_ARCHIVE_DATA_FILE_SUFFIX; String archiveIndexFilename = dataTmpFileName.replace(Constants.CACHE_TMP_FILE_SUFFIX, "") + Constants.CACHE_ARCHIVE_INDEX_FILE_SUFFIX; File archiveDataFile = new File(archiveDataFilename); File archiveIndexFile = new File(archiveIndexFilename); try { if (dataTmpFile.length() == 0) { dataTmpFile.delete(); // 临时缓存文件为空时,直接删除文件即可 } else { FileUtils.moveFile(dataTmpFile, archiveDataFile); archiveIndexFile.createNewFile(); // 索引文件数据格式:0,记录数 IOUtils.writeToFile("0," + totalIndex, archiveIndexFilename); } } catch (IOException e) { LOGGER.error("Failed to create archive files.", e); archiveDataFile.deleteOnExit(); archiveIndexFile.deleteOnExit(); return ; } // 重置缓存临时文件 reset(); init(); } } /** * 初始化 */ private void init() { Long timestamp = System.currentTimeMillis(); String cacheTmpDataFileName = Constants.CACHE_FILE_PREFIX + timestamp + Constants.CACHE_TMP_FILE_SUFFIX; LOGGER.debug("Cache tmp data file name: '{}'.", cacheTmpDataFileName); if (dataTmpFile == null || !dataTmpFile.exists()) { // 生成缓存数据文件和缓存索引文件 dataTmpFileName = getCacheDir() + File.separator + cacheTmpDataFileName; dataTmpFile = new File(dataTmpFileName); tmpFileCreateTime = System.currentTimeMillis(); } } /** * 重置 */ private void reset() { dataTmpFile = null; dataTmpFileName = null; totalIndex = 0; } /** * 获取配置的缓存目录路径 * @return 存放缓存文件的目录 * @throws IOException */ private String getCacheDir() { String dataCacheDir = disConfig.getDataCacheDir(); File file = new File(dataCacheDir); if (!file.exists()) { file.mkdirs(); } try { return file.getCanonicalPath(); } catch (IOException e) { LOGGER.error("Invalid cache dir: {}.", disConfig.getDataCacheDir()); throw new DISClientException(e); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy