Annotation of parser3/src/main/pa_stylesheet_manager.C, revision 1.17

1.1       parser      1: /** @file
                      2:        Parser: sql driver manager implementation.
                      3: 
1.17    ! paf         4:        Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com)
1.13      paf         5:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1       parser      6: */
                      7: #include "pa_config_includes.h"
                      8: #ifdef XML
1.14      paf         9: 
1.17    ! paf        10: static const char* IDENT_STYLESHEET_MANAGER_C="$Date: 2003/07/23 08:40:54 $";
1.1       parser     11: 
                     12: #include "pa_stylesheet_manager.h"
                     13: #include "pa_exception.h"
                     14: #include "pa_common.h"
                     15: #include "pa_threads.h"
                     16: #include "pa_stack.h"
1.2       paf        17: #include "pa_vhash.h"
1.3       paf        18: #include "pa_vtable.h"
1.1       parser     19: 
                     20: // globals
                     21: 
1.17    ! paf        22: Stylesheet_manager stylesheet_manager;
1.1       parser     23: 
                     24: // consts
                     25: 
1.17    ! paf        26: const time_t SECOND=1;
        !            27: const time_t EXPIRE_UNUSED_CONNECTION_SECONDS=5*60;
        !            28: const time_t CHECK_EXPIRED_CONNECTION_SECONDS=EXPIRE_UNUSED_CONNECTION_SECONDS*2;
1.1       parser     29: 
                     30: // helpers
                     31: 
1.17    ! paf        32: static void expire_connection(Stylesheet_connection& connection, time_t older_dies) {
1.1       parser     33:        if(connection.connected() && connection.expired(older_dies))
                     34:                connection.disconnect();
                     35: }
1.17    ! paf        36: static void expire_connections(
        !            37:                               Stylesheet_manager::connection_cache_type::key_type /*key*/, 
        !            38:                               Stylesheet_manager::connection_cache_type::value_type stack, 
        !            39:                               time_t older_dies) {
        !            40:        for(size_t i=0; i<stack->top(); i++)
        !            41:                expire_connection(*stack->get(i), older_dies);
1.1       parser     42: }
                     43: 
1.17    ! paf        44: // Stylesheet_connection methods
1.1       parser     45: 
1.17    ! paf        46: void Stylesheet_connection::close() {
        !            47:        stylesheet_manager.close_connection(ffile_spec, *this);
1.1       parser     48: }
                     49: 
1.17    ! paf        50: // Stylesheet_manager methods
1.1       parser     51: 
1.17    ! paf        52: Stylesheet_manager::Stylesheet_manager(): prev_expiration_pass_time(0) {
1.1       parser     53: 
1.17    ! paf        54:        cache_managers.put(StringBody("stylesheet"), this);
        !            55: }
        !            56: 
        !            57: Stylesheet_manager::~Stylesheet_manager() {
        !            58:        connection_cache.for_each(expire_connections, time(0)+SECOND/*=in future=expire all*/);
        !            59: }
        !            60: 
        !            61: Stylesheet_connection_ptr Stylesheet_manager::get_connection(const String& file_spec) {
        !            62:        Stylesheet_connection* result=get_connection_from_cache(file_spec);
        !            63:        if(!result)
        !            64:                result=new Stylesheet_connection(file_spec);
        !            65:        return Stylesheet_connection_ptr(result);
1.1       parser     66: }
                     67: 
                     68: void Stylesheet_manager::close_connection(const String& file_spec, 
                     69:                                                                                  Stylesheet_connection& connection) {
                     70:        put_connection_to_cache(file_spec, connection);
                     71: }
                     72: 
                     73: // stylesheet cache
                     74: /// @todo get rid of memory spending Stack [zeros deep inside got accumulated]
1.17    ! paf        75: Stylesheet_connection* Stylesheet_manager::get_connection_from_cache(const String& file_spec) { 
1.1       parser     76:        SYNCHRONIZED;
                     77: 
1.17    ! paf        78:        if(connection_cache_type::value_type connections=connection_cache.get(file_spec))
        !            79:                while(!connections->is_empty()) { // there are cached stylesheets to that 'file_spec'
        !            80:                        Stylesheet_connection* result=connections->pop();
1.1       parser     81:                        if(result->connected()) // not expired?
                     82:                                return result;
                     83:                }
                     84: 
                     85:        return 0;
                     86: }
                     87: 
                     88: void Stylesheet_manager::put_connection_to_cache(const String& file_spec, 
1.17    ! paf        89:                                                 Stylesheet_connection& connection) { 
1.1       parser     90:        SYNCHRONIZED;
                     91: 
1.17    ! paf        92:        connection_cache_type::value_type connections=connection_cache.get(file_spec);
1.1       parser     93:        if(!connections) { // there are no cached stylesheets to that 'file_spec' yet?
1.17    ! paf        94:                connections=new connection_cache_value_type;
1.1       parser     95:                connection_cache.put(file_spec, connections);
                     96:        }       
                     97:        connections->push(&connection);
                     98: }
                     99: 
1.5       paf       100: void Stylesheet_manager::maybe_expire_cache() {
1.1       parser    101:        time_t now=time(0);
                    102: 
                    103:        if(prev_expiration_pass_time<now-CHECK_EXPIRED_CONNECTION_SECONDS) {
1.17    ! paf       104:                connection_cache.for_each(expire_connections, now-EXPIRE_UNUSED_CONNECTION_SECONDS);
1.1       parser    105: 
                    106:                prev_expiration_pass_time=now;
                    107:        }
                    108: }
1.17    ! paf       109: /*
1.3       paf       110: static void add_connection_to_status_cache_table(Array::Item *value, void *info) {
                    111:        Stylesheet_connection& connection=*static_cast<Stylesheet_connection *>(value);
                    112:        Table& table=*static_cast<Table *>(info);
                    113: 
                    114:        if(connection.connected()) {
1.17    ! paf       115:                =table.pool();
        !           116:                Array& row=*new Array();
1.3       paf       117: 
1.4       paf       118:                // file
1.3       paf       119:                row+=&connection.file_spec();
1.4       paf       120:                // time
1.3       paf       121:                time_t time_stamp=connection.get_time_used();
1.17    ! paf       122:                row+=new String(pool.copy(ctime(&time_stamp)));
1.3       paf       123: 
                    124:                table+=&row;
                    125:        }
                    126: }
                    127: static void add_connections_to_status_cache_table(const Hash::Key& key, Hash::Val *value, void *info) {
                    128:        Stack& stack=*static_cast<Stack *>(value);
                    129:        Array_iter iter(stack);
                    130:        for(int countdown=stack.top_index(); countdown-->=0; )
                    131:                add_connection_to_status_cache_table(iter.next(), info);
                    132: }
1.17    ! paf       133: */
        !           134: Value* Stylesheet_manager::get_status() {
        !           135:        VHash* result=new VHash;
        !           136: /*
1.2       paf       137:        // cache
                    138:        {
1.17    ! paf       139:                Array& columns=*new Array();
        !           140:                columns+=new String("file");
        !           141:                columns+=new String("time");
        !           142:                Table& table=*new Table(0, &columns, connection_cache.length());
1.2       paf       143: 
                    144:                connection_cache.for_each(add_connections_to_status_cache_table, &table);
                    145: 
1.17    ! paf       146:                result.hash(source).put(*new String("cache"), new VTable(&table));
1.2       paf       147:        }
1.17    ! paf       148: */
1.2       paf       149:        return result;
                    150: }
                    151: 
1.1       parser    152: #endif

E-mail: