Skip to content

Commit

Permalink
Moving linked list handling of Page into a separate class
Browse files Browse the repository at this point in the history
  • Loading branch information
cruppstahl committed Feb 5, 2016
1 parent 97d778e commit a94da54
Show file tree
Hide file tree
Showing 12 changed files with 332 additions and 258 deletions.
30 changes: 17 additions & 13 deletions TODO
Expand Up @@ -121,7 +121,7 @@ x queries must be able to return a "result set" with a range of keys
x add to remote API
x add to python API (w/ sample)
x ups_result_get_{key|record}: swap parameters (OUT is the last one!)
x uqi_select_range: begin-pointer no need to be a pointer of pointer!!
x uqi_select_range: begin-pointer no need to be a pointer of pointer!!
x add to java API (w/ sample)
x add unittests
x make sure that the "begin" cursor is advanced!
Expand Down Expand Up @@ -157,7 +157,7 @@ x add numeric record types
x add monster tests with duplicates
x add monster tests without duplicates

x merge isset, notset, issetany from topic/txn
x merge isset, notset, issetany from topic/txn

x the python UQI tests still has failures

Expand Down Expand Up @@ -265,15 +265,8 @@ x add top-k/bottom-k functionality
x disallow "limit" clause for all other commands
x add unittests

o 2page:
x Page::usable_page_size() should not require parameter
x remove "const" versions of those getters
x reduce getters (data, payload, raw_payload...)
x rewrite as struct - nein, erstmal so lassen
- use boost intrusive_list (or my own one)

o some functions need to run on a single stream, but they have to store keys
AND records as a result, i.e. "min". it's usually not interesting to
AND records as a result, i.e. "min". it's usually not interesting to
know about the minimum record without knowing the key as well. fix this
(and fix the tests) for the following functions:
o min
Expand All @@ -292,9 +285,20 @@ o improve unittests, just as planned for 2.2.1
o create a generic implementation for the predicate-style functions

o refactoring
o continue with 2page/*
o continue with 2worker/*
o continue with 3*
o 3cache
o 3changeset
o 3journal
o 3page_manager
o 3blob_manager
o 3btree
o 4context
o 4txn
o 4cursor
o 4db
o 4env
o 4uqi
o 5server
o 5upscaledb

o increase versions
o new version is 2.2.0
Expand Down
142 changes: 142 additions & 0 deletions src/1base/intrusive_list.h
@@ -0,0 +1,142 @@
/*
* Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
* All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* See the file COPYING for License information.
*/

/*
* An intrusive list
*
* usage:
*
* struct P {
* IntrusiveListNode<P> list_node; // don't change that name!
* };
*
* IntrusiveList<P> list;
*
* P p;
* list.put(&p);
* list.del(&p);
* assert(list.has(&p));
*
* If |P| should be a member in multiple lists:
*
* struct P {
* IntrusiveListNode<P, 3> list_node; // for 3 lists
* };
*
* IntrusiveList<P, 0> list1;
* IntrusiveList<P, 1> list2;
* IntrusiveList<P, 2> list3;
*/

#ifndef UPS_INTRUSIVE_LIST_H
#define UPS_INTRUSIVE_LIST_H

#include "0root/root.h"
#include "1base/uncopyable.h"

// Always verify that a file of level N does not include headers > N!

#ifndef UPS_ROOT_H
# error "root.h was not included"
#endif

namespace upscaledb {

template<typename T, int I = 1>
struct IntrusiveListNode : public Uncopyable {
IntrusiveListNode() {
for (int i = 0; i < I; i++)
previous[i] = next[i] = 0;
}

T *previous[I];
T *next[I];
};

template<typename T, int I = 0>
struct IntrusiveList {
IntrusiveList()
: head_(0), tail_(0), size_(0) {
}

T *head() const {
return head_;
}

T *tail() const {
return tail_;
}

bool is_empty() const {
return size_ == 0;
}

size_t size() const {
return size_;
}

void put(T *t) {
t->list_node.previous[I] = 0;
t->list_node.next[I] = 0;
if (head_) {
t->list_node.next[I] = head_;
head_->list_node.previous[I] = t;
}
head_ = t;
if (!tail_)
tail_ = t;
size_++;
}

void del(T *t) {
assert(has(t));

if (t == tail_)
tail_ = t->list_node.previous[I];
if (t == head_) {
T *next = head_->list_node.next[I];
if (next)
next->list_node.previous[I] = 0;
head_ = next;
}
else {
T *next = t->list_node.next[I];
T *prev = t->list_node.previous[I];
if (prev)
prev->list_node.next[I] = next;
if (next)
next->list_node.previous[I] = prev;
}
t->list_node.next[I] = 0;
t->list_node.previous[I] = 0;
size_--;
}

bool has(const T *t) const {
return t->list_node.previous[I] != 0
|| t->list_node.next[I] != 0
|| t == head_;
}

T *head_;
T *tail_;
size_t size_;
};

} // namespace upscaledb

#endif // UPS_INTRUSIVE_LIST_H
43 changes: 43 additions & 0 deletions src/1base/uncopyable.h
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
* All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* See the file COPYING for License information.
*/

#ifndef UPS_UNCOPYABLE_H
#define UPS_UNCOPYABLE_H

#include "0root/root.h"

// Always verify that a file of level N does not include headers > N!

#ifndef UPS_ROOT_H
# error "root.h was not included"
#endif

namespace upscaledb {

class Uncopyable {
public:
Uncopyable() {
}

private:
Uncopyable(const Uncopyable&);
Uncopyable& operator=(const Uncopyable&);
};

} // namespace upscaledb

#endif // UPS_UNCOPYABLE_H
3 changes: 0 additions & 3 deletions src/2page/page.cc
Expand Up @@ -33,9 +33,6 @@ uint64_t Page::ms_page_count_flushed = 0;
Page::Page(Device *device, LocalDatabase *db)
: device_(device), db_(db), cursor_list_(0), node_proxy_(0)
{
::memset(&m_prev[0], 0, sizeof(m_prev));
::memset(&m_next[0], 0, sizeof(m_next));

persisted_data.raw_data = 0;
persisted_data.is_dirty = false;
persisted_data.is_allocated = false;
Expand Down

0 comments on commit a94da54

Please sign in to comment.