all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bug#405: Emacs 22.2.1 in X behaves improperly when run with low memory limits
@ 2008-06-13 18:12 Kwang Ketcham
  2008-06-14  4:42 ` Stefan Monnier
  0 siblings, 1 reply; 2+ messages in thread
From: Kwang Ketcham @ 2008-06-13 18:12 UTC (permalink / raw
  To: bug-gnu-emacs

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1123 bytes --]

When run in an X window session and with low process memory limits, Emacs 
fails to open and/or syntax highlight some files properly.  To reproduce, 
run:

   bash --noprofile --norc
   ulimit -d 10240
   emacs
     Open treeset-private.hpp [attached]

If things are still going smoothly, try turning on font-lock-mode.  At 
this point, I get the error 'Invalid regexp: "Regular expression too 
big"'.  If the ulimit is set to 8MB instead of 10MB, Emacs encounters this 
error on startup while attempting to load the splash screen.  I have 
encountered similar errors while loading or highlighting this file with 
memory limits up to at least 12MB, if not larger.  Sometimes the file will 
fail to load; sometimes it will load but be improperly highlighted; other 
times it will load but nothing will be highlighted and the modified flag 
will be set.  Behavior is inconsistent; sometimes, simply reissuing the 
open file command or toggling font-lock-mode will fix things.  If you have 
further questions about the bug, contact me at kketcham@cs.hmc.edu.  Thank 
you.

Kwang Ketcham
Harvey Mudd College
CS Department Staff

[-- Attachment #2: Type: TEXT/x-c++hdr, Size: 5982 bytes --]

#ifndef TREESET_PRIVATE_HPP_INCLUDED
#define TREESET_PRIVATE_HPP_INCLUDED 1

#include <iostream>
#include <cassert>

using namespace std;

/*
 * Public member functions.  Most of these call recursive private helper
 * functions on the root of the TreeSet.
 */

template <typename T>
TreeSet<T>::TreeSet()
    : size_(0), rotations_(0), root_(NULL)
{
    // Nothing else to do!
}

template <typename T>
TreeSet<T>::~TreeSet()
{
    destroySubtree(root_);
}

template <typename T>
size_t TreeSet<T>::size() const
{
    return size_;
}

template <typename T>
void TreeSet<T>::insert(const T& item)
{
    insert(item, root_);
    ++size_;
}

template <typename T>
bool TreeSet<T>::exists(const T& item) const
{
    return exists(item, root_);
}

template <typename T>
void TreeSet<T>::printStatistics()
{
    cerr << "height " << height() << ", " <<  rotations_ << " rotations, "
         << "size " << size() << endl;
}

template <typename T>
ostream& TreeSet<T>::print(ostream& out) const
{
    return print(out, root_);
}

template <typename T>
size_t TreeSet<T>::height()
{
    return height(root_);
}

/*
 * Recursive private helper functions.
 */

template <typename T>
void TreeSet<T>::destroySubtree(Node* here)
{
    if (here != NULL) {
        destroySubtree(here->left_);
        destroySubtree(here->right_);
    }
    
    delete here;
}

template <typename T>
void TreeSet<T>::insert(const T& item, Node*& here)
{
    if (here == NULL)
        here = new Node(item);
    else {
        here->maybeRecolor();
        
        // Don't make root_ red!
        if (here == root_)
            here->isRed_ = false;
        
        if (item < here->value_)
            insert(item, here->left_);
        else
            insert(item, here->right_);
        
        rotations_ += Node::maybeRotate(here);
    }
}

template <typename T>
bool TreeSet<T>::exists(const T& item, const Node* const& here) const
{
    if (here == NULL)
        return false;
    
    if (item == here->value_)
        return true;
    
    if (item < here-> value_)
        return exists(item, here->left_);
    else
        return exists(item, here->right_);
}

template <typename T>
ostream& TreeSet<T>::print(ostream& out, const Node* const& here) const
{
    if (here == NULL)
        out << "-";
    else {
        out << "(";
        print(out, here->left_);
        out << ", " << here->value_ << ", ";
        print(out, here->right_);
        out << ")";
    }
    
    return out;
}

template <typename T>
int TreeSet<T>::height(Node*& here)
{
    if (here == NULL)
        return -1;
    else
        return 1 + max(height(here->left_), height(here->right_));
}

/*
 * Public node member functions
 */

template <typename T>
TreeSet<T>::Node::Node(const T& item)
    : isRed_(true), value_(item), left_(NULL), right_(NULL)
{
    // Nothing else to do!
}


// A node needs rotating if one of its children and one of that child's children
// are both red. It should be rotated in the opposite direction of the red child.
// If the grandchild is an inner child (a.k.a. right's left or
// left's right, as opposed to right's right or left's left), then the child
// also needs rotating, in the opposite direction of the red grandchild.
// In addition, the original node should become red and the new root of the
// subtree should become black.

template <typename T>
size_t TreeSet<T>::Node::maybeRotate(Node*& rotateThis)
{
    size_t rotations = 0;
   
    if (isRed(rotateThis->left_) && hasRedKids(rotateThis->left_)) {
        rotateThis->isRed_ = true;
        
        if (isRed(rotateThis->left_->right_)) {
            rotateLeft(rotateThis->left_);
            ++rotations;
        }
        
        rotateRight(rotateThis);
        ++rotations;
        
        // Set the new subtree root to be black
        rotateThis->isRed_ = false;
    }
    
    if (isRed(rotateThis->right_) && hasRedKids(rotateThis->right_)) {
        rotateThis->isRed_ = true;
        
        if (isRed(rotateThis->right_->left_)) {
            rotateRight(rotateThis->right_);
            ++rotations;
        }
        
        rotateLeft(rotateThis);
        ++rotations;
        
        // Set the new subtree root to be black
        rotateThis->isRed_ = false;
    }
    // If we've rotated more than twice, the tree was unbalanced.
    assert(rotations <= 2);
        
    return rotations;
}

template <typename T>
void TreeSet<T>::Node::maybeRecolor()
{
    if (isRed(left_) && isRed(right_) && !isRed_) {
        left_->isRed_ = false;
        right_->isRed_ = false;
        isRed_ = true;
    }
}

/* 
 * Private Node member functions
 */
 
template <typename T>
void TreeSet<T>::Node::rotateLeft(Node*& rotateThis)
{
    
    assert(rotateThis->right_ != NULL);
    
    // Move pointers around
    Node* newTop       = rotateThis->right_;
    rotateThis->right_ = newTop->left_;
    newTop->left_      = rotateThis;
    
    // The top of the subtree is what used to be rotateThis->right_
    rotateThis = newTop;
}

template <typename T>
void TreeSet<T>::Node::rotateRight(Node*& rotateThis)
{
    
    assert(rotateThis->left_ != NULL);
    
    // Move pointers around
    Node* newTop       = rotateThis->left_;
    rotateThis->left_  = newTop->right_;
    newTop->right_     = rotateThis;
    
    // The top of the subtree is what used to be rotateThis->left_
    rotateThis = newTop;
}

template <typename T>
bool TreeSet<T>::Node::isRed(Node*& here)
{
    if (here == NULL)
        return false;
    
    return here->isRed_;
}

template <typename T>
bool TreeSet<T>::Node::hasRedKids(Node*& here)
{
    if (here == NULL)
        return false;
    
    return (isRed(here->left_) || isRed(here->right_));
}

#endif

^ permalink raw reply	[flat|nested] 2+ messages in thread

* bug#405: Emacs 22.2.1 in X behaves improperly when run with low memory limits
  2008-06-13 18:12 bug#405: Emacs 22.2.1 in X behaves improperly when run with low memory limits Kwang Ketcham
@ 2008-06-14  4:42 ` Stefan Monnier
  0 siblings, 0 replies; 2+ messages in thread
From: Stefan Monnier @ 2008-06-14  4:42 UTC (permalink / raw
  To: Kwang Ketcham; +Cc: 405, bug-gnu-emacs

> When run in an X window session and with low process memory limits, Emacs
> fails to open and/or syntax highlight some files properly.  To reproduce,
> run:

>   bash --noprofile --norc
>   ulimit -d 10240
>   emacs
>     Open treeset-private.hpp [attached]

> If things are still going smoothly, try turning on font-lock-mode.  At this
> point, I get the error 'Invalid regexp: "Regular expression too big"'.
> If the ulimit is set to 8MB instead of 10MB, Emacs encounters this error on
> startup while attempting to load the splash screen.  I have encountered
> similar errors while loading or highlighting this file with memory limits up
> to at least 12MB, if not larger.  Sometimes the file will fail to load;

What can I say: it needs more memory.  That it fails gracefully rather
than crashing and burning is rather good than bad, don't you think?


        Stefan






^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2008-06-14  4:42 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-13 18:12 bug#405: Emacs 22.2.1 in X behaves improperly when run with low memory limits Kwang Ketcham
2008-06-14  4:42 ` Stefan Monnier

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.