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

1.1       parser      1: /** @file
                      2:        Parser: sql driver manager implementation.
                      3: 
1.31      moko        4:        Copyright (c) 2001-2017 Art. Lebedev Studio (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.1       parser     10: #include "pa_stylesheet_manager.h"
                     11: #include "pa_exception.h"
                     12: #include "pa_common.h"
                     13: #include "pa_threads.h"
                     14: #include "pa_stack.h"
1.2       paf        15: #include "pa_vhash.h"
1.3       paf        16: #include "pa_vtable.h"
1.1       parser     17: 
1.33    ! moko       18: volatile const char * IDENT_PA_STYLESHEET_MANAGER_C="$Id: pa_stylesheet_manager.C,v 1.32 2020/12/10 23:21:09 moko Exp $" IDENT_PA_STYLESHEET_MANAGER_H;
1.29      moko       19: 
1.1       parser     20: // globals
                     21: 
1.23      paf        22: Stylesheet_manager* stylesheet_manager=0;
1.1       parser     23: 
                     24: // consts
                     25: 
1.17      paf        26: const time_t EXPIRE_UNUSED_CONNECTION_SECONDS=5*60;
                     27: const time_t CHECK_EXPIRED_CONNECTION_SECONDS=EXPIRE_UNUSED_CONNECTION_SECONDS*2;
1.1       parser     28: 
                     29: // helpers
                     30: 
1.17      paf        31: static void expire_connection(Stylesheet_connection& connection, time_t older_dies) {
1.1       parser     32:        if(connection.connected() && connection.expired(older_dies))
                     33:                connection.disconnect();
                     34: }
1.32      moko       35: static void expire_connections(Stylesheet_manager::connection_cache_type::key_type /*key*/, Stylesheet_manager::connection_cache_type::value_type stack, time_t older_dies) {
1.19      paf        36:        for(size_t i=0; i<stack->top_index(); i++)
1.17      paf        37:                expire_connection(*stack->get(i), older_dies);
1.1       parser     38: }
                     39: 
1.17      paf        40: // Stylesheet_connection methods
1.1       parser     41: 
1.17      paf        42: void Stylesheet_connection::close() {
1.24      paf        43:        stylesheet_manager->close_connection(ffile_spec, *this);
1.1       parser     44: }
                     45: 
1.17      paf        46: // Stylesheet_manager methods
1.1       parser     47: 
1.17      paf        48: Stylesheet_manager::Stylesheet_manager(): prev_expiration_pass_time(0) {
                     49: }
                     50: 
                     51: Stylesheet_manager::~Stylesheet_manager() {
1.28      paf        52:        connection_cache.for_each<time_t>(expire_connections, time(0)+(time_t)10/*=in future=expire all*/);
1.17      paf        53: }
                     54: 
1.33    ! moko       55: Stylesheet_connection* Stylesheet_manager::get_connection(String::Body file_spec) {
1.17      paf        56:        Stylesheet_connection* result=get_connection_from_cache(file_spec);
1.33    ! moko       57:        return result ? result : new Stylesheet_connection(file_spec);
1.1       parser     58: }
                     59: 
1.21      paf        60: void Stylesheet_manager::close_connection(String::Body file_spec, Stylesheet_connection& connection) {
1.1       parser     61:        put_connection_to_cache(file_spec, connection);
                     62: }
                     63: 
                     64: // stylesheet cache
                     65: /// @todo get rid of memory spending Stack [zeros deep inside got accumulated]
1.21      paf        66: Stylesheet_connection* Stylesheet_manager::get_connection_from_cache(String::Body file_spec) { 
1.1       parser     67:        SYNCHRONIZED;
                     68: 
1.17      paf        69:        if(connection_cache_type::value_type connections=connection_cache.get(file_spec))
                     70:                while(!connections->is_empty()) { // there are cached stylesheets to that 'file_spec'
                     71:                        Stylesheet_connection* result=connections->pop();
1.1       parser     72:                        if(result->connected()) // not expired?
                     73:                                return result;
                     74:                }
                     75: 
                     76:        return 0;
                     77: }
                     78: 
1.32      moko       79: void Stylesheet_manager::put_connection_to_cache(String::Body file_spec, Stylesheet_connection& connection) {
1.1       parser     80:        SYNCHRONIZED;
                     81: 
1.17      paf        82:        connection_cache_type::value_type connections=connection_cache.get(file_spec);
1.1       parser     83:        if(!connections) { // there are no cached stylesheets to that 'file_spec' yet?
1.17      paf        84:                connections=new connection_cache_value_type;
1.1       parser     85:                connection_cache.put(file_spec, connections);
                     86:        }       
                     87:        connections->push(&connection);
                     88: }
                     89: 
1.5       paf        90: void Stylesheet_manager::maybe_expire_cache() {
1.1       parser     91:        time_t now=time(0);
                     92: 
                     93:        if(prev_expiration_pass_time<now-CHECK_EXPIRED_CONNECTION_SECONDS) {
1.28      paf        94:                connection_cache.for_each<time_t>(expire_connections, now-EXPIRE_UNUSED_CONNECTION_SECONDS);
1.1       parser     95: 
                     96:                prev_expiration_pass_time=now;
                     97:        }
                     98: }
1.3       paf        99: 
1.22      paf       100: static void add_connection_to_status_cache_table(Stylesheet_connection& connection, Table* table) {
1.3       paf       101:        if(connection.connected()) {
1.22      paf       102:                ArrayString& row=*new ArrayString;
1.3       paf       103: 
1.4       paf       104:                // file
1.22      paf       105:                row+=new String(connection.file_spec(), String::L_AS_IS);
1.4       paf       106:                // time
1.22      paf       107:                time_t time_used=connection.get_time_used();
                    108:                row+=new String(pa_strdup(ctime(&time_used)));
1.3       paf       109: 
1.22      paf       110:                *table+=&row;
1.3       paf       111:        }
                    112: }
1.32      moko      113: static void add_connections_to_status_cache_table(Stylesheet_manager::connection_cache_type::key_type /*key*/, Stylesheet_manager::connection_cache_type::value_type stack, Table* table) {
1.22      paf       114:        for(Array_iterator<Stylesheet_connection*> i(*stack); i.has_next(); )
                    115:                add_connection_to_status_cache_table(*i.next(), table);
1.3       paf       116: }
1.22      paf       117: 
1.17      paf       118: Value* Stylesheet_manager::get_status() {
                    119:        VHash* result=new VHash;
1.2       paf       120:        // cache
                    121:        {
1.22      paf       122:                ArrayString& columns=*new ArrayString;
1.17      paf       123:                columns+=new String("file");
                    124:                columns+=new String("time");
1.22      paf       125:                Table& table=*new Table(&columns, connection_cache.count());
1.2       paf       126: 
1.28      paf       127:                connection_cache.for_each<Table*>(add_connections_to_status_cache_table, &table);
1.2       paf       128: 
1.22      paf       129:                result->get_hash()->put(*new String("cache"), new VTable(&table));
1.2       paf       130:        }
                    131:        return result;
                    132: }
                    133: 
1.1       parser    134: #endif

E-mail: