/**************************************************************************/ /* */ /* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ /* Copyright (c) 2008-2017 Oleksandr Shneyder */ /* Copyright (c) 2014-2022 Ulrich Sibiller */ /* Copyright (c) 2014-2019 Mihai Moldovan */ /* Copyright (c) 2011-2022 Mike Gabriel */ /* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ /* */ /* NXCOMP, NX protocol compression and NX extensions to this software */ /* are copyright of the aforementioned persons and companies. */ /* */ /* Redistribution and use of the present software is allowed according */ /* to terms specified in the file LICENSE.nxcomp which comes in the */ /* source distribution. */ /* */ /* All rights reserved. */ /* */ /* NOTE: This software has received contributions from various other */ /* contributors, only the core maintainers and supporters are listed as */ /* copyright holders. Please contact us, if you feel you should be listed */ /* as copyright holder, as well. */ /* */ /**************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "Misc.h" #include "BlockCacheSet.h" BlockCacheSet::BlockCacheSet(unsigned int numCaches): caches_(new BlockCache *[numCaches]), size_(numCaches), length_(0) { for (unsigned int i = 0; i < numCaches; i++) caches_[i] = new BlockCache(); } BlockCacheSet::~BlockCacheSet() { // // TODO: There is still a strange segfault occurring // at random time under Cygwin, when proxy is being // shutdown. Problem appeared just after upgrading // to the latest version of the Cygwin DLL. A stack // trace, obtained at the last minute, reveals that // failure happens in this destructor. // #if !(defined(__CYGWIN__) || defined(__CYGWIN32__)) for (unsigned int i = 0; i < size_; i++) delete caches_[i]; delete[]caches_; #endif /* if !(defined(__CYGWIN__) || defined(__CYGWIN32__)) */ } int BlockCacheSet::lookup(unsigned int dataLength, const unsigned char *data, unsigned int &index) { unsigned int checksum = BlockCache::checksum(dataLength, data); for (unsigned int i = 0; i < length_; i++) if ((caches_[i]->getChecksum() == checksum) && (caches_[i]->compare(dataLength, data, 0))) { // match index = i; if (i) { BlockCache *save = caches_[i]; unsigned int target = (i >> 1); do { caches_[i] = caches_[i - 1]; i--; } while (i > target); caches_[target] = save; } return 1; } // no match unsigned int insertionPoint = (length_ >> 1); unsigned int start; if (length_ >= size_) start = size_ - 1; else { start = length_; length_++; } BlockCache *save = caches_[start]; for (unsigned int k = start; k > insertionPoint; k--) caches_[k] = caches_[k - 1]; caches_[insertionPoint] = save; save->set(dataLength, data); return 0; } void BlockCacheSet::get(unsigned index, unsigned int &size, const unsigned char *&data) { size = caches_[index]->getLength(); data = caches_[index]->getData(); if (index) { BlockCache *save = caches_[index]; unsigned int target = (index >> 1); do { caches_[index] = caches_[index - 1]; index--; } while (index > target); caches_[target] = save; } } void BlockCacheSet::set(unsigned int dataLength, const unsigned char *data) { unsigned int insertionPoint = (length_ >> 1); unsigned int start; if (length_ >= size_) start = size_ - 1; else { start = length_; length_++; } BlockCache *save = caches_[start]; for (unsigned int k = start; k > insertionPoint; k--) caches_[k] = caches_[k - 1]; caches_[insertionPoint] = save; save->set(dataLength, data); }