Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/include/array/RLE.h b/include/array/RLE.h
- index eb10d99..741e221 100644
- --- a/include/array/RLE.h
- +++ b/include/array/RLE.h
- @@ -60,164 +60,6 @@ typedef std::map<position_t, Value> ValueMap;
- extern bool checkChunkMagic(ConstChunk const& chunk);
- -class RLEBitmap
- -{
- - size_t nSegments;
- - position_t* occ; // occ[0] is last occurrence of 0 in first sequence of 0,
- - // occ[1] - last coccurence of 1 of first sequnce of 1,...:
- - // case 1:
- - // 0,0,1,1,1,1,0,0,1,0,0,0,1,1,1
- - // occ= 1,5,7,8,11,14
- - // case 2:
- - // 1,1,0,0,1,0,0,0,0,0,0
- - // occ= -1,1,3,4,10
- -
- - std::vector<position_t> container;
- -
- - public:
- - /**
- - * Check if bit at specified position is set
- - */
- - bool isSet(position_t pos) const {
- - size_t l = 0, r = nSegments;
- - while (l < r) {
- - size_t m = (l + r) >> 1;
- - if (occ[m] < pos) {
- - l = m + 1;
- - } else {
- - r = m;
- - }
- - }
- - assert(r < nSegments);
- - return r & 1;
- - }
- -
- - struct Segment {
- - position_t start;
- - position_t length;
- - };
- -
- - /**
- - * Get next i-th segment of set bits
- - */
- - bool getSetSegment(size_t i, Segment& segm) const {
- - i <<= 1;
- - if (i+1 < nSegments) {
- - segm.start = occ[i] + 1;
- - segm.length = occ[i+1] - segm.start + 1;
- - return true;
- - }
- - return false;
- - }
- -
- - /**
- - * Get next i-th segment of clear bits
- - */
- - bool getClearSegment(size_t i, Segment& segm) const {
- - if (occ[0] < 0) {
- - i += 1;
- - }
- - i <<= 1;
- - if (i < nSegments) {
- - segm.start = i == 0 ? 0 : occ[i-1] + 1;
- - segm.length = occ[i] - segm.start + 1;
- - return true;
- - }
- - return false;
- - }
- -
- -
- - /**
- - * Find segment of clear bits with position greater or equal than specified.
- - * @return segment index which should be used in getClearSegment
- - */
- - size_t findClearSegment(position_t pos) const {
- - size_t l = 0, r = nSegments;
- - while (l < r) {
- - size_t m = (l + r) >> 1;
- - if (occ[m] < pos) {
- - l = m + 1;
- - } else {
- - r = m;
- - }
- - }
- - return (r + 1) >> 1;
- - }
- -
- - /**
- - * Find segment of set bits with position greater or equal than specified.
- - * @return segment index which should be used in getClearSegment
- - */
- - size_t findSetSegment(position_t pos) const {
- - size_t l = 0, r = nSegments;
- - while (l < r) {
- - size_t m = (l + r) >> 1;
- - if (occ[m] < pos) {
- - l = m + 1;
- - } else {
- - r = m;
- - }
- - }
- - return r >> 1;
- - }
- -
- -
- - /**
- - * Method to be called to save bitmap in chunk body
- - */
- - void pack(char* dst) {
- - *(size_t*)dst = nSegments;
- - dst += sizeof(size_t);
- - memcpy(dst, occ, nSegments*sizeof(position_t));
- - }
- -
- - /**
- - * Get size needed to pack bitmap (used to dermine size of chunk)
- - */
- - size_t packedSize() {
- - return sizeof(size_t) + nSegments*sizeof(position_t);
- - }
- -
- - /**
- - * Assignment operator
- - */
- - RLEBitmap& operator=(RLEBitmap const& other);
- -
- - /**
- - * Default constructor
- - */
- - RLEBitmap() {
- - nSegments = 0;
- - occ = NULL;
- - }
- -
- - /**
- - * Copy constructor
- - */
- - RLEBitmap(RLEBitmap const& other) {
- - *this = other;
- - }
- -
- - /**
- - * Constructor for initializing Bitmap with raw chunk data
- - */
- - RLEBitmap(char const* src) {
- - nSegments = *(size_t*)src;
- - occ = (position_t*)(src + sizeof(size_t));
- - }
- -
- - /**
- - * Constructor of bitmap from ValueMap (which is used to be filled by ChunkIterator)
- - */
- - RLEBitmap(ValueMap& vm, uint64_t chunkSize, bool defaultVal);
- -
- - /**
- - * Constructor of RLE bitmap from dense bit vector
- - */
- - RLEBitmap(char* data, size_t chunkSize);
- -};
- -
- -
- class RLEEmptyBitmap;
- class ConstRLEEmptyBitmap
- {
- @@ -431,6 +273,15 @@ public:
- boost::shared_ptr<RLEEmptyBitmap> merge(ConstRLEEmptyBitmap const& other);
- /**
- + * Merge THIS with other bitmap
- + */
- + boost::shared_ptr<RLEEmptyBitmap> cut(
- + Coordinates const& lowerOrigin,
- + Coordinates const& upperOrigin,
- + Coordinates const& lowerResult,
- + Coordinates const& upperResult) const;
- +
- + /**
- * Merge THIS with MERGEBITS and return the result as a new RLEEmptyBitmap
- * MERGEBITS must have one BIT for each "1" in THIS.
- */
- @@ -560,11 +411,6 @@ class RLEEmptyBitmap : public ConstRLEEmptyBitmap
- RLEEmptyBitmap(char* data, size_t numBits);
- /**
- - * Constructor for initializing Bitmap with specified ranges
- - */
- - RLEEmptyBitmap(Coordinates const& chunkSize, Coordinates const& origin, Coordinates const& first, Coordinates const& last);
- -
- - /**
- * Constructor for initializing Bitmap from specified chunk
- */
- RLEEmptyBitmap(ConstChunk const& chunk);
- @@ -919,7 +765,7 @@ public:
- setBits += _payload->checkBit(_cs->valueIndex) ? tail : 0;
- } else {
- position_t beg = _cs->valueIndex + _currPpos - _cs->pPosition;
- - position_t end = _cs->pPosition + _cs->length();
- + position_t end = _cs->valueIndex + _cs->length();
- while (beg < end) {
- setBits += _payload->checkBit(beg++);
- }
- diff --git a/src/array/MemArray.cpp b/src/array/MemArray.cpp
- index bc547c9..175b5ea 100644
- --- a/src/array/MemArray.cpp
- +++ b/src/array/MemArray.cpp
- @@ -2005,7 +2005,10 @@ namespace scidb
- emptyBitmap = shared_ptr<RLEEmptyBitmap>(new RLEEmptyBitmap(logicalChunkSize));
- }
- if (hasOverlap && (iterationMode & IGNORE_OVERLAPS)) {
- - emptyBitmap = emptyBitmap->merge(RLEEmptyBitmap(chunkIntervals, origin, data->getFirstPosition(false), data->getLastPosition(false)));
- + emptyBitmap = emptyBitmap->cut(data->getFirstPosition(true),
- + data->getLastPosition(true),
- + data->getFirstPosition(false),
- + data->getLastPosition(false));
- }
- //assert(emptyBitmap->count() == payload.count() || (hasOverlap && emptyBitmap->count() < payload.count()));
- assert(emptyBitmap->count() <= payload.count());
- @@ -2113,7 +2116,10 @@ namespace scidb
- } else {
- emptyBitmap = data->getEmptyBitmap();
- if (hasOverlap && (iterationMode & IGNORE_OVERLAPS)) {
- - emptyBitmap = emptyBitmap->merge(RLEEmptyBitmap(chunkIntervals, origin, data->getFirstPosition(false), data->getLastPosition(false)));
- + emptyBitmap = emptyBitmap->cut(data->getFirstPosition(true),
- + data->getLastPosition(true),
- + data->getFirstPosition(false),
- + data->getLastPosition(false));
- }
- }
- emptyBitmapIterator = emptyBitmap->getIterator();
- diff --git a/src/array/RLE.cpp b/src/array/RLE.cpp
- index ff8319a..7a901dc 100644
- --- a/src/array/RLE.cpp
- +++ b/src/array/RLE.cpp
- @@ -21,10 +21,13 @@
- * END_COPYRIGHT
- */
- +#include <sstream>
- +#include <fstream>
- #include "array/Array.h"
- #include "query/TypeSystem.h"
- #include "system/Config.h"
- #include "system/SciDBConfigOptions.h"
- +#include "system/Utils.h"
- using namespace boost;
- using namespace std;
- @@ -48,70 +51,6 @@ namespace scidb
- return true;
- }
- - RLEBitmap& RLEBitmap::operator=(RLEBitmap const& other)
- - {
- - nSegments = other.nSegments;
- - if (other.occ == &other.container[0]) {
- - container = other.container;
- - occ = &container[0];
- - } else {
- - occ = other.occ;
- - }
- - return *this;
- - }
- -
- - RLEBitmap::RLEBitmap(ValueMap& vm, uint64_t chunkSize, bool defaultVal)
- - {
- - bool currVal = false;
- - position_t currPos = -1;
- - for (ValueMap::const_iterator i = vm.begin(); i != vm.end(); ++i) {
- - assert(i->first > currPos);
- - if (i->second.getBool() != currVal || (i->first != currPos+1 && currVal != defaultVal)) {
- - if (i->first != currPos+1) { // hole
- - if (currVal != defaultVal) {
- - container.push_back(currPos); // sequence of currVal (where currVal != defaultVal)
- - if (i->second.getBool() != defaultVal) {
- - container.push_back(i->first-1); // sequence of defaultVal
- - }
- - } else {
- - container.push_back(i->first-1); // sequence of defaultVal (where defaultVal != i->second)
- - }
- - } else {
- - container.push_back(currPos);
- - }
- - }
- - currVal = i->second.getBool();
- - currPos = i->first;
- - }
- - if (currVal == defaultVal) {
- - container.push_back(chunkSize-1);
- - } else {
- - container.push_back(currPos);
- - if (currPos != position_t(chunkSize-1)) {
- - container.push_back(chunkSize-1);
- - }
- - }
- - nSegments = container.size();
- - occ = &container[0];
- - }
- -
- - RLEBitmap::RLEBitmap(char* data, size_t chunkSize)
- - {
- - bool currVal = false;
- - for (size_t i = 0; i < chunkSize; i++) {
- - bool newVal = (data[i >> 3] & (1 << (i & 7))) != 0;
- - if (newVal != currVal) {
- - container.push_back(i-1);
- - currVal = newVal;
- - }
- - }
- - if (container.back() != position_t(chunkSize-1)) {
- - container.push_back(chunkSize-1);
- - }
- - nSegments = container.size();
- - occ = &container[0];
- - }
- -
- size_t ConstRLEEmptyBitmap::packedSize() const {
- return sizeof(Header) + nSegs*sizeof(Segment);
- }
- @@ -395,64 +334,261 @@ namespace scidb
- ppos += len;
- }
- return ppos;
- - }
- -
- - RLEEmptyBitmap::RLEEmptyBitmap(Coordinates const& chunkSize, Coordinates const& origin, Coordinates const& first, Coordinates const& last)
- + }
- +
- + class CutBuilder : boost::noncopyable
- {
- - //This constructor is used to create fully dense bitmasks for chunks that are assumed to be 100% dense,
- - //AND they are missing a tail section (say chunk size is 100 and array ends at 120) or maybe they
- - //are missing overlap. I personally think we should NEVER need to call this constructor. There is no reason
- - //why we need to build such masks. We can always start with empty masks and go from there. But this bad
- - //behavior is hard to get rid of quickly. I will try to get rid of it slowly -poliocough, 5/2/12
- -
- - //Why is this behavior bad? Assume you have a 4x4 chunk that's truncated to be 3x3. What does the bitmask look
- - //like?. Uncompressed, it looks like this:
- - //
- - // 1110
- - // 1110
- - // 1110
- - // 0000
- - //
- - //So this bitmask contains 3 segments. One segment for each row of 1s.
- - //Now imagine this is a 5-dimensional array with chunk sizes of thousands. We could create a very large bitmask.
- - //for no reason at all!
- -
- - uint64_t nElems = 1;
- - size_t n = chunkSize.size();
- - size_t lastTruncatedDim = 0;
- - for (size_t i = 0; i < n; i++)
- + public:
- + typedef ConstRLEEmptyBitmap::Segment Segment;
- +
- + private:
- + boost::shared_ptr<RLEEmptyBitmap> _resultBitmap;
- +
- + Segment const * _sourceArray;
- +
- + size_t _sourceCount;
- + size_t _sourceIndex;
- +
- + Segment _sourceSegment;
- + Segment _resultSegment;
- +
- + public:
- + CutBuilder(Segment* sourceArray, size_t sourceCount) :
- + _resultBitmap(new RLEEmptyBitmap()),
- + _sourceArray(sourceArray),
- + _sourceCount(sourceCount),
- + _sourceIndex(0)
- {
- - if(chunkSize[i]!= last[i]-first[i]+1)
- - {
- - lastTruncatedDim=i;
- + if (!endSource()) {
- + _sourceSegment = _sourceArray[0];
- + _resultSegment.lPosition = _sourceSegment.lPosition;
- + _resultSegment.pPosition = _sourceSegment.pPosition;
- + _resultSegment.length = 0;
- }
- - nElems *= chunkSize[i];
- }
- - //Turns out, the number of segments is the product of all dimensions UP TO the LAST truncated dimension:
- - uint64_t numSegments = 1;
- - for(size_t i =0; i<lastTruncatedDim; i++)
- + position_t logical() const
- {
- - numSegments *= (last[i]-first[i]+1);
- + SCIDB_ASSERT(!endSource());
- + return _sourceSegment.lPosition;
- }
- -#ifndef SCIDB_CLIENT
- - size_t memUsage = numSegments*sizeof(Segment);
- - if (memUsage > scidb::Config::getInstance()->getOption<int>(CONFIG_MEM_ARRAY_THRESHOLD)*MB)
- + position_t length() const
- {
- - //We are stupid! We just made one chunk bitmask that is larger than MEM_ARRAY_THRESHOLD.
- - //We should kill ourselves and warn the user of our stupidity!
- - throw SYSTEM_EXCEPTION(SCIDB_SE_INTERNAL, SCIDB_LE_ILLEGAL_OPERATION) << "Truncated chunk bitmask constructor error";
- + SCIDB_ASSERT(!endSource());
- + return _sourceSegment.length;
- }
- -#endif //if it doesn't happen on the server - it shouldn't happen on the client
- - reserve(numSegments);
- + void skipSource(position_t count)
- + {
- + SCIDB_ASSERT(!endSource());
- + SCIDB_ASSERT(count <= _sourceSegment.length);
- + _sourceSegment.lPosition += count;
- + _sourceSegment.pPosition += count;
- + _sourceSegment.length -= count;
- + }
- - nNonEmptyElements = addRange(0, 0, nElems, 0, chunkSize, origin, first, last);
- - nSegs = container.size();
- - seg = &container[0];
- + void skipResult(position_t count)
- + {
- + if (_resultSegment.length > 0 && count > 0) {
- + _resultBitmap->addSegment(_resultSegment);
- + _resultSegment.length = 0;
- + }
- + }
- +
- + void flush()
- + {
- + skipResult(1);
- + }
- +
- + void copy(position_t count)
- + {
- + SCIDB_ASSERT(!endSource());
- + SCIDB_ASSERT(count <= _sourceSegment.length);
- + if (_resultSegment.length == 0) {
- + _resultSegment.lPosition = _sourceSegment.lPosition;
- + _resultSegment.pPosition = _sourceSegment.pPosition;
- + }
- + _resultSegment.length += count;
- + skipSource(count);
- + }
- +
- + void nextSourceSegment()
- + {
- + SCIDB_ASSERT(!endSource());
- + SCIDB_ASSERT(_sourceSegment.length == 0);
- + ++_sourceIndex;
- + if (!endSource()) {
- + Segment const& previous = _sourceSegment;
- + Segment const& current = _sourceArray[_sourceIndex];
- + SCIDB_ASSERT(previous.lPosition >= current.lPosition);
- + SCIDB_ASSERT(previous.pPosition >= current.pPosition);
- + }
- + }
- +
- + bool endSource() const
- + {
- + return _sourceIndex == _sourceCount;
- + }
- +
- + boost::shared_ptr<RLEEmptyBitmap> result() const
- + {
- + return _resultBitmap;
- + }
- + };
- +
- + class CutDimension : boost::noncopyable
- + {
- + private:
- + position_t _prefix;
- + position_t _suffix;
- + position_t _interval;
- + position_t _copy;
- + boost::shared_ptr<CutDimension> _nested;
- +
- + private:
- + CutDimension()
- + {
- + }
- +
- + position_t init(Coordinates const& lowerOrigin,
- + Coordinates const& upperOrigin,
- + Coordinates const& lowerResult,
- + Coordinates const& upperResult,
- + size_t index)
- + {
- + SCIDB_ASSERT(lowerOrigin[index] <= lowerResult[index]);
- + SCIDB_ASSERT(lowerResult[index] <= upperResult[index]);
- + SCIDB_ASSERT(upperResult[index] <= upperOrigin[index]);
- + _prefix = lowerResult[index] - lowerOrigin[index];
- + _suffix = upperOrigin[index] - upperResult[index];
- + _interval = upperOrigin[index] + 1 - lowerOrigin[index];
- + ++index;
- + position_t multiplier = _interval;
- + if (index < lowerOrigin.size()) {
- + _nested = boost::shared_ptr<CutDimension>(new CutDimension());
- + multiplier *= _nested->init(lowerOrigin, lowerResult,
- + upperResult, upperOrigin,
- + index);
- + if (!bool(_nested->_nested) && _prefix == 0 && _suffix == 0) {
- + /* nested dimension fully included */
- + _nested.reset();
- + }
- + }
- + _copy = _interval - _prefix - _suffix;
- + return multiplier;
- + }
- +
- + public:
- + CutDimension(Coordinates const& lowerOrigin,
- + Coordinates const& upperOrigin,
- + Coordinates const& lowerResult,
- + Coordinates const& upperResult)
- + {
- + size_t const n(lowerOrigin.size());
- + SCIDB_ASSERT(n > 0);
- + SCIDB_ASSERT(n == upperOrigin.size());
- + SCIDB_ASSERT(n == lowerResult.size());
- + SCIDB_ASSERT(n == upperResult.size());
- + init(lowerOrigin, lowerResult, upperResult, upperOrigin, 0);
- + }
- +
- + void cut(CutBuilder& builder) const
- + {
- + if (builder.length() == 0) {
- + return;
- + }
- +
- + position_t resultOffset = builder.logical() % _interval;
- + builder.skipResult(resultOffset);
- +
- + position_t prefixLeft = 0;
- + if (resultOffset < _prefix) {
- + prefixLeft = min(_prefix - resultOffset, builder.length());
- + }
- + builder.skipSource(prefixLeft);
- + builder.skipResult(prefixLeft);
- +
- + if (builder.length() == 0) {
- + return;
- + }
- +
- +
- + if (_nested) {
- + position_t left = _copy;
- + SCIDB_ASSERT(left > 0);
- +
- + while(builder.length() > 0 && left > 0) {
- + _nested->cut(builder);
- + left -= _nested->_interval;
- + }
- + } else {
- + builder.copy(min(_copy, builder.length()));
- + }
- +
- + if (builder.length() == 0) {
- + return ;
- + }
- +
- + position_t left = min(_suffix, builder.length());
- + builder.skipSource(left);
- + builder.skipResult(left);
- + }
- + };
- +
- +
- + boost::shared_ptr<RLEEmptyBitmap> ConstRLEEmptyBitmap::cut(
- + Coordinates const& lowerOrigin,
- + Coordinates const& upperOrigin,
- + Coordinates const& lowerResult,
- + Coordinates const& upperResult) const
- + {
- + CutBuilder builder(seg, nSegs);
- + CutDimension cut(lowerOrigin, upperOrigin, lowerResult, upperResult);
- +
- + while(!builder.endSource()) {
- + cut.cut(builder);
- + SCIDB_ASSERT(builder.length() == 0);
- + builder.nextSourceSegment();
- + }
- + builder.flush();
- +
- + if (true) {
- + boost::shared_ptr<RLEEmptyBitmap> result = builder.result();
- + std::ofstream f("/tmp/zabivator", std::ios_base::app | std::ios_base::out);
- + std::ostringstream ori;
- + std::ostringstream res;
- + ori << "OR [";
- + res << "RE [";
- + for (std::size_t i = 0; i < lowerOrigin.size(); ++i) {
- + if (i > 0) {
- + ori << ";";
- + res << ";";
- + }
- + ori << lowerOrigin[i] << "," << upperOrigin[i];
- + res << lowerResult[i] << "," << upperResult[i];
- + }
- + ori << "] " << nSegs;
- + res << "] " << result->nSegs;
- + for (size_t i = 0; i < nSegs; ++i) {
- + ori << " (logical=" << seg[i].lPosition;
- + ori << ", physical=" << seg[i].pPosition;
- + ori << ", length=" << seg[i].length;
- + ori << ")";
- + }
- + for (size_t i = 0; i < result->nSegs; ++i) {
- + res << "(logical=" << result->seg[i].lPosition;
- + res << ", physical=" << result->seg[i].pPosition;
- + res << ", length=" << result->seg[i].length;
- + res << ")";
- + }
- + ori << "\n";
- + res << "\n";
- + f << (ori.str() + res.str() + "\n") << std::flush;
- + }
- +
- + return builder.result();
- }
- -
- RLEEmptyBitmap::RLEEmptyBitmap(ValueMap& vm, bool all)
- {
- diff --git a/src/query/ops/between/BetweenArray.cpp b/src/query/ops/between/BetweenArray.cpp
- index b76202c..2470a99 100644
- --- a/src/query/ops/between/BetweenArray.cpp
- +++ b/src/query/ops/between/BetweenArray.cpp
- @@ -147,7 +147,11 @@ namespace scidb
- while (i < nDims && coord[i] >= chunk.firstPos[i]) {
- if (coord[i] > chunk.lastPos[i]) {
- do {
- - if (i == 0) {
- + if (i == 0) {
- + size_t left = emptyBitmap->count() - pos;
- + if (left > 0) {
- + appender.add(falseVal, left);
- + }
- goto EndOfTile;
- }
- i -= 1;
- diff --git a/tests/harness/testcases/r/other/NID_basics.expected b/tests/harness/testcases/r/other/NID_basics.expected
- index 6347cb7..5059ecb 100644
- --- a/tests/harness/testcases/r/other/NID_basics.expected
- +++ b/tests/harness/testcases/r/other/NID_basics.expected
- @@ -425,7 +425,7 @@ SCIDB QUERY : <bernoulli (filter (Timeseries_Example, Total_Qty > 150 ), 0.85, 1
- [Query was executed successfully, ignoring data output by this query.]
- SCIDB QUERY : <between (filter (Timeseries_Example, Total_Qty > 150 ), 'Foo', 'T_003', 'Wump', 'T_006' )>
- -{1,3}[[{1,3}(12.75,250)],[{2,3}(61.75,200)]];[[{2,5}(9.5,250)]];[[{3,3}(7.25,300),{3,4}(6,300)]]
- +{1,3}[[{1,3}(12.5,200)],[{2,3}(62.5,200)]];[[{2,5}(61,175)]];[[{3,3}(7.5,200),{3,4}(8,250)]]
- SCIDB QUERY : <cast ( filter (Timeseries_Example, Total_Qty > 150 ), EMPTY < Avg_Price : double NULL, Total_Qty : int64 NULL > [ TS(string)=*,4,0, Symbol(string)=*,14,0 ])>
- {0,1}[[{0,1}(110.5,200)]];[[{0,3}(112.5,200)]];[[{0,5}(111,175)]];[[{0,7}(113,200),{0,8}(112.75,250)]];[[{1,0}(10.25,300)]];[[{1,3}(12.5,200)]];[[{1,7}(13,200),{1,8}(12.75,250)]];[[{2,1}(60.5,200)]];[[{2,3}(62.5,200)]];[[{2,5}(61,175),{2,6}(61.75,200)]];[[{3,1}(9.5,250)]];[[{3,3}(7.5,200),{3,4}(8,250)]];[[{3,8}(7.25,300),{3,9}(6,300)]]
- diff --git a/tests/harness/testcases/r/other/UB_basics.expected b/tests/harness/testcases/r/other/UB_basics.expected
- index e0580f4..8585d9d 100644
- --- a/tests/harness/testcases/r/other/UB_basics.expected
- +++ b/tests/harness/testcases/r/other/UB_basics.expected
- @@ -425,7 +425,7 @@ SCIDB QUERY : <bernoulli (filter (Timeseries_Example, Total_Qty > 150 ), 0.85, 1
- [Query was executed successfully, ignoring data output by this query.]
- SCIDB QUERY : <between (filter (Timeseries_Example, Total_Qty > 150 ), 'Foo', 'T_003', 'Wump', 'T_006' )>
- -{1,3}[[{1,3}(12.75,250)],[{2,3}(61.75,200)]];[[{2,5}(9.5,250)]];[[{3,3}(7.25,300),{3,4}(6,300)]]
- +{1,3}[[{1,3}(12.5,200)],[{2,3}(62.5,200)]];[[{2,5}(61,175)]];[[{3,3}(7.5,200),{3,4}(8,250)]]
- SCIDB QUERY : <cast ( filter (Timeseries_Example, Total_Qty > 150 ), EMPTY < Avg_Price : double NULL, Total_Qty : int64 NULL > [ TS(string)=*,4,0, Symbol(string)=*,14,0 ])>
- {0,1}[[{0,1}(110.5,200)]];[[{0,3}(112.5,200)]];[[{0,5}(111,175)]];[[{0,7}(113,200),{0,8}(112.75,250)]];[[{1,0}(10.25,300)]];[[{1,3}(12.5,200)]];[[{1,7}(13,200),{1,8}(12.75,250)]];[[{2,1}(60.5,200)]];[[{2,3}(62.5,200)]];[[{2,5}(61,175),{2,6}(61.75,200)]];[[{3,1}(9.5,250)]];[[{3,3}(7.5,200),{3,4}(8,250)]];[[{3,8}(7.25,300),{3,9}(6,300)]]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement