<commit_before>//
//  ========================================================================
//  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.nosql;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import javax.servlet.http.HttpServletRequest;

import org.eclipse.jetty.server.session.AbstractSession;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;


/* ------------------------------------------------------------ */
public class NoSqlSession extends AbstractSession
{
    private final static Logger __log = Log.getLogger("org.eclipse.jetty.server.session");

    private final NoSqlSessionManager _manager;
    private Set<String> _dirty;
    private final AtomicInteger _active = new AtomicInteger();
    private Object _version;
    private long _lastSync;

    /* ------------------------------------------------------------ */
    public NoSqlSession(NoSqlSessionManager manager, HttpServletRequest request)
    {
        super(manager, request);
        _manager=manager;
        save(true);
        _active.incrementAndGet();
    }
    
    /* ------------------------------------------------------------ */
    public NoSqlSession(NoSqlSessionManager manager, long created, long accessed, String clusterId, Object version)
    {
        super(manager, created,accessed,clusterId);
        _manager=manager;
        _version=version;
    }
    
    /* ------------------------------------------------------------ */
    @Override
    public Object doPutOrRemove(String name, Object value)
    {
        synchronized (this)
        {
            if (_dirty==null)
                _dirty=new HashSet<String>();
            _dirty.add(name);
            Object old = super.doPutOrRemove(name,value);
            if (_manager.getSavePeriod()==-2)
                save(true);
            return old;
        }
    }

    /* ------------------------------------------------------------ */
    @Override
    protected void checkValid() throws IllegalStateException
    {
        super.checkValid();
    }

    /* ------------------------------------------------------------ */
    @Override
    protected boolean access(long time)
    {
        __log.debug("NoSqlSession:access:active "+_active);
        if (_active.incrementAndGet()==1)
        {
            long period=_manager.getStalePeriod()*1000L;
            if (period==0)
                refresh();
            else if (period>0)
            {
                long stale=time-_lastSync;
                __log.debug("NoSqlSession:access:stale "+stale);
                if (stale>period)
                    refresh();
            }
        }

        return super.access(time);
    }

    /* ------------------------------------------------------------ */<commit_msg>[Bug 413484] setAttribute in nosql session management better handles _dirty status<commit_after>//
//  ========================================================================
//  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.nosql;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import javax.servlet.http.HttpServletRequest;

import org.eclipse.jetty.server.session.AbstractSession;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;


/* ------------------------------------------------------------ */
public class NoSqlSession extends AbstractSession
{
    private final static Logger __log = Log.getLogger("org.eclipse.jetty.server.session");

    private final NoSqlSessionManager _manager;
    private Set<String> _dirty;
    private final AtomicInteger _active = new AtomicInteger();
    private Object _version;
    private long _lastSync;

    /* ------------------------------------------------------------ */
    public NoSqlSession(NoSqlSessionManager manager, HttpServletRequest request)
    {
        super(manager, request);
        _manager=manager;
        save(true);
        _active.incrementAndGet();
    }
    
    /* ------------------------------------------------------------ */
    public NoSqlSession(NoSqlSessionManager manager, long created, long accessed, String clusterId, Object version)
    {
        super(manager, created,accessed,clusterId);
        _manager=manager;
        _version=version;
    }
    
    /* ------------------------------------------------------------ */
    @Override
    public Object doPutOrRemove(String name, Object value)
    {
        synchronized (this)
        {
            Object old = super.doPutOrRemove(name,value);
            
            if (_manager.getSavePeriod()==-2)
            {
                save(true);
            }
            return old;
        }
    }
    
    

    @Override
    public void setAttribute(String name, Object value)
    {
        if ( updateAttribute(name,value) )
        {
            if (_dirty==null)
            {
                _dirty=new HashSet<String>();
            }
            
            _dirty.add(name);
        }
    }

    /*
     * a boolean version of the setAttribute method that lets us manage the _dirty set
     */
    protected boolean updateAttribute (String name, Object value)
    {
        Object old=null;
        synchronized (this)
        {
            checkValid();
            old=doPutOrRemove(name,value);
        }

        if (value==null || !value.equals(old))
        {
            if (old!=null)
                unbindValue(name,old);
            if (value!=null)
                bindValue(name,value);

            _manager.doSessionAttributeListeners(this,name,old,value);
            return true;
        }
        return false;
    }
    
    /* ------------------------------------------------------------ */
    @Override
    protected void checkValid() throws IllegalStateException
    {
        super.checkValid();
    }

    /* ------------------------------------------------------------ */
    @Override
    protected boolean access(long time)
    {
        __log.debug("NoSqlSession:access:active "+_active);
        if (_active.incrementAndGet()==1)
        {
            long period=_manager.getStalePeriod()*1000L;
            if (period==0)
                refresh();
            else if (period>0)
            {
                long stale=time-_lastSync;
                __log.debug("NoSqlSession:access:stale "+stale);
                if (stale>period)
                    refresh();
            }
        }

        return super.access(time);
    }

    /* ------------------------------------------------------------ */
{'fraction_non_alphanumeric': 0.24564044661899384, 'fraction_numerical': 0.0072763768661397565, 'mean_word_length': 1.4889166406493912, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3140585', 'n_tokens_mistral': 1946, 'n_tokens_neox': 1862, 'n_words': 444}