blob: f2dcb519ac6dbd01e77581bcc4b76690cafaa5f5 [file] [log] [blame]
Akrond8540bd2017-02-06 15:05:26 +01001package Krawfish::Query::Base::Sorted;
2use parent 'Krawfish::Query';
Akron6ff7b482017-02-09 01:29:29 +01003use Krawfish::Log;
Akrond8540bd2017-02-06 15:05:26 +01004use strict;
5use warnings;
6
Akron12736192017-03-08 20:31:58 +01007use constant DEBUG => 0;
Akron6ff7b482017-02-09 01:29:29 +01008
9# TODO:
Akron15fc1972017-07-20 22:53:00 +020010# Implement using Krawfish::Util::Heap
11
12# TODO:
Akron6ff7b482017-02-09 01:29:29 +010013# Implement as an overwriting ring buffer (FIFO) with
14# byte precision.
15#
16# The recent element indicates the last freed element,
17# to know, whenever a sorting fails (i.e. an element has
18# an ordering earlier then the earliest element.
Akrond8540bd2017-02-06 15:05:26 +010019#
20# TODO:
21# 0 points to the last bubbled element. That means, if an element
22# tries to be buffered that needs to be before this element, a warning
23# should be issued, that the buffer was exceeded!
24
Akron6ff7b482017-02-09 01:29:29 +010025# Elements have:
26# <size><data>
27
Akrond8540bd2017-02-06 15:05:26 +010028sub new {
29 my $class = shift;
30 bless {
Akron6ff7b482017-02-09 01:29:29 +010031 span => shift,
32 capacity => shift, # The size of the buffer, in the future given in bytes
33 offset => 0, # The numerical offset for numbered access
34 size => 0, # The number of elements in the buffer
35 recent => 0, # Pointer to the last freed element in the buffer
36 first => 0, # Pointer to the first element in the buffer
37 last => 0, # Pointer to the last element in the buffer
38 buffer => [] # Array holding all elements in the buffer
Akrond8540bd2017-02-06 15:05:26 +010039 }, $class;
40};
41
42
43# Next sorted element
44sub next {
45 my $self = shift;
46
47 while ($self->{span}->next) {
48 my $next_post = $self->{span}->current;
49
50 # Sort buffer
51 my $last_index = $self->buffer_last;
Akron6ff7b482017-02-09 01:29:29 +010052
53 print_log('sortbuf', "Last position in buffer is $last_index") if DEBUG;
54
Akrond8540bd2017-02-06 15:05:26 +010055 my $buffer_post = $self->buffer_get($last_index);
56
Akron6ff7b482017-02-09 01:29:29 +010057 if (DEBUG) {
58 print_log(
59 'sortbuf',
60 'Last buffer element is ' . ($buffer_post ? '' : 'not') . ' given'
61 );
62 };
63
Akrond8540bd2017-02-06 15:05:26 +010064 # Compare next posting with last element in buffer
65 while ($next_post->compare($buffer_post) == -1) {
66 $last_index--;
67
68 if ($last_index == 0) {
69 # todo! Add at beginning!
70 ...
71 };
72
73 # Get last buffer post
74 $buffer_post = $self->buffer_get($last_index);
75 };
76
77 # Insert posting at the correct position in the buffered stream
78 $self->buffer_insert_after($last_index, $next_post);
79
80 # The buffer has reached its limit
81 if ($self->buffer_length >= $self->capacity) {
82 return $self->buffer_shift;
83 };
84 };
85
86 return $self->buffer_shift;
87};
88
89# Return index to last added element
Akron290f59f2017-08-17 21:55:07 +020090sub buffer_last {
91 ...
92};
Akron6ff7b482017-02-09 01:29:29 +010093
94# Points to the latest freed element in the buffer
95# (normally this is -1 to first)
96sub buffer_recent {
97 return $_[0]->{recent};
Akrond8540bd2017-02-06 15:05:26 +010098};
99
Akron6ff7b482017-02-09 01:29:29 +0100100
101# Points to the first accessible element in the buffer
102sub buffer_first {
103 return $_[0]->{first};
104};
105
106# sub buffer_push;
Akron290f59f2017-08-17 21:55:07 +0200107sub buffer_shift {
108 ...
109};
110
111sub buffer_get {
112 ...
113};
114
Akron6ff7b482017-02-09 01:29:29 +0100115sub buffer_insert_after {
116 my ($self, $index, $element) = @_;
Akron6ff7b482017-02-09 01:29:29 +0100117};
Akrond8540bd2017-02-06 15:05:26 +0100118
1191;